2013-03-13 104 views
0

我正在嘗試在Linux中創建客戶端服務器應用程序。服務器應該向所有連接的客戶端發送一個對象。 這是它的代碼。 在此當服務器發送對象時,服務器端的所有內容都保持不變,但客戶端服務器立即收到分段錯誤。將服務器上的對象傳遞給客戶端

服務器:

#include "Question.h" 
#include <iostream> 
#include <string.h> 
using namespace std; 

#include<sys/socket.h> 
#include<sys/types.h> 
#include<stdio.h> 
#include<arpa/inet.h> 
#include<time.h> 

#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <netinet/in.h> 

int main() { 
    Question q1("Capital Of Pakistan?", "Lahore", "Karachi", "Quetaa", "Islamabad"); 

    int socketID = 0, clientID[10] = {0}, totalClients = 3; 
    char sendBuffer[1024]; 
    memset(sendBuffer, '0', sizeof(sendBuffer)); 

    time_t time; 
    struct sockaddr_in servAddr; 

    cout << "Question is: \n" << q1.getQuestion()<<endl; 
    cout << q1.getOpt1() << endl << q1.getOpt2() << endl << q1.getOpt3() << endl << q1.getCorrect()<<endl; 

    cout << "\n\n --- Server starting up --- \n\n"; 

    /* 
    * Creating Socket 
    */ 
    socketID = socket(AF_INET, SOCK_STREAM, 0); 
    if (socketID == -1) { 
     cerr << " Can't create Socket"; 
    } 

    servAddr.sin_family = AF_INET; 
    servAddr.sin_port = htons(5000); 
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    /* 
    * Binding IP 
    */ 
    int bindID; 
    bindID = bind(socketID, (struct sockaddr *) &servAddr, sizeof(servAddr)); // Casting sockaddr_in on sockaddr and binding it with socket id 
    if (bindID != -1) { 
     cout << " Bind SucessFull"; 

     listen(socketID, 5); 
     cout << " Server Waiting for connections" << endl; 
     int i = 0; 
     while (1) { 
      clientID[i] = accept(socketID, (struct sockaddr *) NULL, NULL); 
      cout << "Got Client: " << i+1 << ","<<totalClients-(i+1)<<" to go" << endl; 
      cout << "ID: " << clientID[i]<<endl; 
      cout.flush(); 
      snprintf(sendBuffer, sizeof(sendBuffer), "%.24s\n", ctime(&time)); 
      write(clientID[i], sendBuffer, strlen(sendBuffer)); 

      i++; 
      if (i >= totalClients) 
       break; 
      sleep(1); 
     } 
     cout << "Sending Question to All Clients...." << endl; 
     for(int j=0; j<totalClients; j++) { 
      cout << "Sending to ID " << clientID[j]<<endl; 
      write(clientID[j], &q1 , sizeof(q1)); 
      cout << "Sent " << j << "...." << endl; 
     } 
     /* 
     * Closing all clients 
     */ 
     for (int k = 0; k < totalClients; k++) { 
      close(clientID[k]); 
     } 
    } else { 
     cerr << " Unable to Bind"; 
    } 
    return 0; 
} 

客戶:

#include "Question.h" 
#include <iostream> 
#include <string.h> 
using namespace std; 

#include<sys/socket.h> 
#include<sys/types.h> 
#include<stdio.h> 
#include<arpa/inet.h> 
#include<time.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 


int main(int argc, char *argv[]) 
{ 
    int socketID = 0 /*Socket Descriptor*/, n = 0; 
    char recvBuffer[1024]; 

    memset(recvBuffer, '0',sizeof(recvBuffer)); 

    struct sockaddr_in servAddr; 

    if(argc!=2){ 
     cout << "\n Usage: %s <ip of server> \n",argv[0]; 
     return 1; 
    } 

    socketID = socket(AF_INET, SOCK_STREAM, 0); 
    if(socketID == -1){ 
     cerr << "\n Can't create socket \n"; 
     return 1; 
    } 

    servAddr.sin_family = AF_INET; 
    servAddr.sin_port = htons(5000); 

    if(inet_pton(AF_INET, argv[1], &servAddr.sin_addr)==-1){ 
     cerr << "\n Unable to convert given IP to Network Form \n inet_pton Error"; 
     return 1; 
    } 

    int connectFlag; 
    connectFlag = connect(socketID, (struct sockaddr *)&servAddr, sizeof(servAddr)); 
    if(connectFlag == -1){ 
     cout << " Connection Failed" << endl; 
     return 1; 
    } 
    n = read(socketID, recvBuffer, sizeof(recvBuffer)-1); 
    recvBuffer[n] = 0; 
    cout << recvBuffer << endl; 

    if(n < 0){ 
     cerr << "Buffer Read error\n"; 
    } 
    Question q1; 
    cout << "Gonna Receive Connections"<<endl; 
    q1.setAll("0","0","0","0","0"); 
    cout.flush(); 
    n = read(socketID, &q1, sizeof(q1)); 
    cout << n << endl; 
    cout << "Received Question " << endl; 
    cout << "Question is: \n" << q1.getQuestion()<<endl; 
    cout << q1.getOpt1() << endl << q1.getOpt2() << endl << q1.getOpt3() << endl << q1.getCorrect()<<endl; 
    cout.flush(); 

    return 0; 
} 

Question.h

#ifndef QUESTION_H_ 
#define QUESTION_H_ 

#include <iostream> 
using namespace std; 

class Question { 
private: 
    string question; 
    string opt1; 
    string opt2; 
    string opt3; 
    string correct; 
public: 
    /* 
    * Constructors 
    */ 
    Question(); 
    Question(string, string, string, string, string); 

    void setAll(string, string, string, string, string); 
    string getCorrect() const; 
    void setCorrect(string correct); 
    string getOpt1() const; 
    void setOpt1(string opt1); 
    string getOpt2() const; 
    void setOpt2(string opt2); 
    string getOpt3() const; 
    void setOpt3(string opt3); 
    void setQuestion(string question); 
    string getQuestion() const; 

}; 

#endif /* QUESTION_H_ */ 

回答

1

您需要將 「序列化」 的對象。這通常包括把它變成一個字符串,可以在你發送對象的任何東西的另一個「側面」讀取。

問題與將數據寫入文件完全相同,您不想存儲OBJECT,您想要存儲該類的「有效內容」或「內容」 。

您可以使用stringstream來形成一長串數據,並傳遞由此形成的字符串。

喜歡的東西:

class A 
{ 
    int x; 
    string s; 
}; 

... 
class A a; 

stringstream ss; 

ss << a.x << ", " << a.s << endl; 

.... 
write(clientID[j], ss.str.c_str(), ss.str.length()); 

你顯然需要在另一端解析得到的字符串 - 和,可能不是理想的分離。隨意使用別的...

+0

我不完全知道如何做到這一點。請告訴2行語法。 – 2013-03-13 17:04:00

+0

明白了。問題解決了 :) – 2013-03-13 17:34:01

相關問題