Tre*_*rey 2 c++ sockets winsock send recv
我当然没有在本地系统上遇到这个问题(当然),但是现在我正在设置一个虚拟服务器,我的部分代码存在一些问题.
为了从非阻塞TCP recv()接收所有数据,我有这个功能
ssize_t Server::recvAll(int sockfd, const void *buf, size_t len, int flags) {
// just showing here that they are non-blocking sockets
u_long iMode=1;
ioctlsocket(sockfd,FIONBIO,&iMode);
ssize_t result;
char *pbuf = (char *)buf;
while ( len > 0 ) {
result = recv(sockfd,pbuf,len,flags);
printf("\tRES: %d", result);
if ( result <= 0 ) break;
pbuf += result;
len -= result;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我注意到,recvAll将通常打印RES: 1024(1024是我送的字节数)和它的伟大工程.但不常见的是,数据丢失并且只打印RES: 400(其中400是大于0且小于1024的某个数字)并且我的代码不起作用,因为它需要所有1024个字节.
我也尝试打印WSAGetLastError()并在调试中运行,但由于我没有遇到此问题的打印/调试,看起来程序运行得足够慢.
我假设这个函数适用于阻塞套接字,但不适用于非阻塞套接字.
我可以采取任何测量建议,以确保我确实收到所有1024个字节,而非阻塞套接字没有数据丢失?
如果使用非阻塞模式,则读取已到达系统的所有数据.一旦你读出所有数据recv返回错误,原因取决于系统:
收到此错误后,您需要等待其他数据的到达.您可以通过以下几种方式实现:
如果你需要减少延迟,最好选择/ poll/epoll.睡眠实现起来要简单得多.
此外,您需要考虑TCP是流协议,并不保持框架.这意味着您可以发送例如256个字节,然后发送另外256个字节,但一次接收512个字节.这也是相反的:您可以一次发送512个字节,第一次读取时接收256个字节,下次读取时接收另外256个字节.