C++ 从套接字发送和接收所有字节的正确方法?
我正在开发一个客户端和一个服务器应用程序,用于在彼此之间发送和接收消息。该代码是可移植的,专为在Windows、OSX和Linux上运行而设计 但是,当客户端在Windows上运行时,我遇到了随机套接字断开的问题。这在Mac或Linux上不会发生。我仍在试图找出服务器或客户端应用程序的哪个部分导致此问题,我怀疑我正在接收和发送数据的代码 如果正确的话,你能看一下我发送和接收数据的代码吗 发送数据:C++ 从套接字发送和接收所有字节的正确方法?,c++,sockets,visual-c++,c++11,C++,Sockets,Visual C++,C++11,我正在开发一个客户端和一个服务器应用程序,用于在彼此之间发送和接收消息。该代码是可移植的,专为在Windows、OSX和Linux上运行而设计 但是,当客户端在Windows上运行时,我遇到了随机套接字断开的问题。这在Mac或Linux上不会发生。我仍在试图找出服务器或客户端应用程序的哪个部分导致此问题,我怀疑我正在接收和发送数据的代码 如果正确的话,你能看一下我发送和接收数据的代码吗 发送数据: int _sendmsg(int socketfd, std::vector<char>
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;
}
int\u sendmsg(intsocketfd,std::vectormessage)
{
int total=0;//我们发送了多少字节
size\u t bytesleet=message.size();//我们还有多少要发送
int n;
while(总计throw EXCEPTION\u sendmsg返回-1”);
}
总+=n;
字节左-=n;
}
返回总数;
}
接收数据(为了代码的简单性,我设置了一个固定值,单位为字节\u needed\u payload=30000。在我的应用程序中,这个数字是从消息的前4个字节计算出来的):
int接收(int socketfd,std::vector*charbuffer)
{
大小\u t字节\u需要\u有效负载=30000;
charbuffer->resize(需要字节数\u负载);
大小\u t字节\u cnt\u有效负载=0;
while(字节\u cnt\u有效负载<字节\u需要的\u有效负载)
{
int bytes\u rcv\u payload=recv(socketfd,charbuffer->data()+bytes\u cnt\u payload,bytes\u needed\u payload-bytes\u cnt\u payload,0);
如果(字节数\u rcv\u有效负载==0){
std::您的发送看起来还可以(虽然您可以对其进行一些调整),但请显示您真正的接收代码,而不是您更改的代码。@blitz:这就是他应该做的。-1是错误,0是断开连接(发送不返回0),并且>0是成功。[OT]:您可以通过const ref在\u sendmsg
(参考\u receive
)@billz send在出现错误时返回-1。当需要的字节数\u payload>0时,它能否返回零?@Yiannis Mpourkelis:请提供有关发生情况的更多信息。上面代码中是否显示任何错误消息?错误是发生在客户端还是服务器端?
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;
}
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;
}