从套接字发送和接收所有字节的正确方法?

时间:2014-10-14 22:09:29

标签: c++ sockets visual-c++ c++11

我正在开发一个客户端和一个服务器应用程序,用于在彼此之间发送和接收消息。该代码是可移植的,专为在Windows,OSX和Linux上运行而设计。

但是,当客户端在Windows上运行时,我遇到了随机套接字断开连接的问题。这不是在Mac或Linux上发生的。我仍在试图找出服务器或客户端应用程序的哪个部分导致此问题,我怀疑我收到的代码并发送数据。

如果正确无误,请查看我的代码以发送和接收数据吗?

发送数据:

int _sendmsg(int socketfd, std::vector<char>message)
{
    int total = 0;        // how many bytes we've sent
    size_t bytesleft = message.size(); // how many we have left to send
    int n;
    while (total < message.size()){
        n = send(socketfd, message.data() + total, bytesleft, 0);
        if (n < 0){
            throw std::runtime_error(std::string("----> throw EXCEPTION _sendmsg  returned -1”));
        }
        total+=n;
        bytesleft-=n;
    }

    return total;
}

接收数据(为了简单起见,我在bytes_needed_pa​​yload = 30000中设置了一个固定值。在我的应用程序中,这个数字是根据消息的前4个字节计算的):

int _recieve(int socketfd, std::vector<char> * charbuffer)
{
    size_t bytes_needed_payload = 30000;
    charbuffer->resize(bytes_needed_payload);
    size_t bytes_cnt_payload = 0;

    while(bytes_cnt_payload < bytes_needed_payload)
    {
        int bytes_rcv_payload = recv(socketfd,charbuffer->data() + bytes_cnt_payload,bytes_needed_payload - bytes_cnt_payload, 0);

        if (bytes_rcv_payload == 0){
            std::cout << std::this_thread::get_id() << " " <<
                       "####  int _recieve: recv return 0 bytes. [second while loop]. Returning from function." << std::endl;
            return 0;
        }
        else if (bytes_rcv_payload == -1){
            std::cout << "int _recieve(int socketfd, std::vector<char> * charbuffer)) - returned -1" << std::endl;
            return -1;
        }

        bytes_cnt_payload += bytes_rcv_payload;
    }

    return bytes_cnt_payload;
}

编辑1:这是我完整的_recieve代码:

int clientserver::_recieve(int socketfd, std::vector<char> * charbuffer)
{
    //-----------
    //first part: receive total bytes of data expected from the
    //from the first 4 bytes of the charbuffer
    size_t bytes_needed = 4;
    char len_bytes[4];
    memset(len_bytes,0,bytes_needed);
    size_t bytes_cnt=0;

    while(bytes_cnt < bytes_needed)
    {
        int bytes_rcv = recv(socketfd, &len_bytes[bytes_cnt],bytes_needed - bytes_cnt, 0);

        if (bytes_rcv == 0){
            std::cout << std::this_thread::get_id() << " " <<
                       "####  int recieve: recv return 0 bytes. [first while loop]. Returning from function." << std::endl;
            return 0;
        }
        else if (bytes_rcv == -1){
            displayErrno("int clientserver::recieve(int socketfd, std::vector<char> * charbuffer) - first while loop");
            return -1;
        }

        bytes_cnt += bytes_rcv;
    }

    if (bytes_needed != bytes_cnt){
        std::cout << "----> EXCEPTION IN recieve func (payload length). Bytes recieved not equal to bytes expected. Expected: " << bytes_needed << " recieved: " << bytes_cnt << std::endl;
        throw std::runtime_error(std::string("----> EXCEPTION IN recieve func (payload length). Bytes recieved not equal to bytes expected."));
    }

    //-----------

    //second part: receiving the payload
    size_t bytes_needed_payload = bytesToInt(len_bytes,4);
    charbuffer->resize(bytes_needed_payload);
    size_t bytes_cnt_payload = 0;

    while(bytes_cnt_payload < bytes_needed_payload)
    {
        int bytes_rcv_payload = recv(socketfd,charbuffer->data() + bytes_cnt_payload,bytes_needed_payload - bytes_cnt_payload, 0);

        if (bytes_rcv_payload == 0){
            std::cout << std::this_thread::get_id() << " " <<
                       "####  int recieve: recv return 0 bytes. [second while loop]. Returning from function." << std::endl;
            return 0;
        }
        else if (bytes_rcv_payload == -1){
            displayErrno("int clientserver::recieve(int socketfd, std::vector<char> * charbuffer)) - second while loop");
            return -1;
        }

        bytes_cnt_payload += bytes_rcv_payload;
    }

    if (bytes_cnt_payload != bytes_needed_payload){
        std::cout << "----> EXCEPTION IN recieve func (payload). Bytes recieved not equal to bytes expected. Expected: " << bytes_needed_payload << " recieved: " << bytes_cnt_payload << std::endl;
        throw std::runtime_error(std::string("----> EXCEPTION IN recieve func (payload). Bytes recieved not equal to bytes expected."));
    }

    return bytes_cnt_payload + bytes_cnt;
}

0 个答案:

没有答案