【问题标题】:Socket programming issue, data sent on exit套接字编程问题,退出时发送数据
【发布时间】:2015-03-28 08:43:25
【问题描述】:

我在 OS X (C++) 上的套接字编程有问题。我的客户端可以连接到服务器,但是当我发送数据时,尽管 send() 没有失败,但只有在程序退出时才会发送数据。

这是我的代码:

在客户端构造函数中创建套接字并连接到服务器:

ComBridge::ComBridge(std::string comManagerIP, int portNumber){
    this->myComManagerIP = comManagerIP;
    this->portNum = portNumber;

    initComBridge();
}

ComBridge::~ComBridge(){
   close(socketFD);
}

void ComBridge::initComBridge(){
    /*Opening the socket*/
    socketFD = socket(AF_INET, SOCK_STREAM, 0);
    if (socketFD<0) {
        cout<<"Error opening socket !"<<endl;
        exit(1);
    }

    /*Defining the server address*/
    bzero((char *) &server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    /*bcopy(myComManagerIP.c_str(),
      (char *)&server_addr.sin_addr.s_addr,
      myComManagerIP.size());*/
    inet_pton(AF_INET,myComManagerIP.c_str(),&server_addr.sin_addr);
    server_addr.sin_port = htons(portNum);

    cout<<"ip server store : "<<myComManagerIP.c_str()<<endl;

    cout<<"ip server in server_addr: "<<server_addr.sin_addr.s_addr<<endl;

    /*Connecting to ComManager*/
    int rcon = connect(socketFD, (struct sockaddr*)&server_addr, sizeof(server_addr));
    cout<<"back num for connection : "<<rcon<<endl;
    if (rcon<0) {
        cout<<"Failed connection to ComManager !"<<endl;
    }
}

以及发送和接收方法:

void ComBridge::readMessage(){
    bzero(bufferIn,256);

    /*Waiting for data from socket*/
    ssize_t numOfCharRecv = recv(socketFD, &bufferIn, 255,0);
    //ssize_t numOfCharRecv = read(socketFD,&bufferIn,255);

    if (numOfCharRecv < 0)
        cout<<"ERROR reading socket"<<endl;

    /*Storing the string received in a jsonDocument*/
    jsonDocument.Parse(bufferIn);
    cout<<"message : "<<bufferIn<<endl;
    /*Notifying observers of event*/
    //notify(jsonDocument);
}

void ComBridge::writeMessage(rapidjson::Document& d){
    buffer = myJsonHandler.convertJsonToString(d);

    cout<<buffer<<endl;

    ssize_t writeRes = send(socketFD,buffer.c_str(),strlen(buffer.c_str())+1,0);
    if (writeRes < 0)
        cout<<"ERROR writing to socket"<<endl;
    else cout<<"Message sent ! "<<writeRes<<endl;
}

调用readMessage和writeMessage的更新方法:

void ComBridge::update(rapidjson::Document& d){

    /*If the message is for the ComManager*/
    if (!d.HasMember("To")) {
        rapidjson::Value myVal;
        /*Adding the comManager IP*/
        myVal.SetString(myComManagerIP.c_str(), d.GetAllocator());
        d.AddMember("To", myVal, d.GetAllocator());
    }

    /*Sending message*/
    writeMessage(d);

    /*Waiting for answer*/
    //readMessage();

}

有人知道出了什么问题吗?

感谢您的帮助!

米凯尔10j

【问题讨论】:

  • readmessage和writemessage怎么叫?
  • 它们都在名为 update() 的方法中调用。我编辑我的帖子给你看。

标签: c++ sockets tcp xcode6 osx-yosemite


【解决方案1】:

这通常发生在你读行而不写行时。这会导致行读取方法阻塞,直到:

  • 收到一个行终止符
  • 流结束
  • 出现错误。

并不是说直到程序退出才发送数据,而是直到有行终止符或流结束时,行读取方法才返回直到流结束。如果发送方没有发送行终止符,则在关闭套接字之前什么都不会发生。

【讨论】:

  • 感谢您的回复。事实上,如果我只使用 send 方法,我会得到相同的结果。而如果我先发送再接收,结果也是一样的……
【解决方案2】:
void ComBridge::writeMessage(rapidjson::Document& d){
    buffer = myJsonHandler.convertJsonToString(d);
    buffer+="\n\r";
    cout<<buffer<<endl;

    ssize_t writeRes = send(socketFD,buffer.c_str(),strlen(buffer.c_str()),0);
    if (writeRes < 0)
         cout<<"ERROR writing to socket"<<endl;
    else cout<<"Message sent ! "<<writeRes<<endl;
}

【讨论】:

  • 你“找到答案”我一天前发布的。
  • 对不起,英语不是我的语言,我误解了你的回答。
猜你喜欢
  • 1970-01-01
  • 2013-11-28
  • 2018-09-13
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多