2013-03-13 4 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 줄의 구문을 알려주십시오. –

+0

알았어요. 문제 해결됨 :) –