将对象从服务器传递到客户端



我试图在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 << "nn --- Server starting up --- nn";
    /*
     * 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), "%.24sn", 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 errorn";
    }
    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_ */

您需要"序列化"您的对象。这通常涉及到将它变成一个字符串,可以在你发送对象的另一边读取。

这是完全相同的问题,如果你是写数据到一个文件,你不想存储对象,你想存储的"有效载荷"或"内容"是在类内。

您可以使用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());

显然需要解析另一端的结果字符串—,可能不是理想的分隔符。你可以随便用别的东西……

相关内容

  • 没有找到相关文章

最新更新