C 非阻止等待所有RECV数据
C++ nonblocking wait for all recv data
我没有在本地系统上遇到这个问题,但是现在我正在设置虚拟服务器,我在代码的一部分中遇到了一些问题。
为了从非块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;
}
我注意到recvAll
通常通常 打印RES: 1024
(1024是我发送的字节的数量),并且效果很好。但是较少的频率是数据丢失,它仅打印RES: 400
(其中400个数字大于0,小于1024),而我的代码不起作用,因为它预计所有1024个字节。
我也尝试打印WSAGetLastError()
并在调试中运行,但是由于我没有遇到此问题,因此该程序看起来足够缓慢。
我假设此功能非常适合阻塞插座,但不是非阻滞插座。
我可以对测量结果提出任何建议,以确保我确实收到所有1024个字节,而不会在非阻止插座上数据丢失?
如果使用非阻滞模式,则您读取所有已经到达系统的数据。一旦读取了所有数据RECV返回错误,原因是根据系统的不同:
- ewoldblock(在Posix系统中)
- Windows插座系统中的WSAEWOULDBLOCK
收到此错误后,您需要等待另一个数据的到达。您可以通过几种方式进行:
- 等待特殊功能,例如Select/poll/epoll
- 睡一段时间,尝试再次收到(用户空间轮询)
如果您需要减少延迟/poll/epoll是可取的。睡眠更容易实现。
您还需要考虑TCP是流协议,并且不会保持构架。这意味着您可以发送256个字节,然后再发送256个字节,但一次接收512个字节。这也相反:您可以一次发送512个字节,并在下一篇读取中收到256个字节,另外256个字节。
相关文章:
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- C++ TCP 套接字通信 - 连接按预期工作,几秒钟后失败,没有收到新数据,read() 和 recv() 块
- 在UNIX中通过recv/send交换数据时,如何正确使用缓冲区
- 为什么 sys 套接字 recv 函数不填充数据但返回字节长度?
- C++ 即使数据可用,Windows recv() 也不会返回
- 为 posix recv 设置超时会导致 udp 数据包丢失吗?
- C 非阻止等待所有RECV数据
- recv() 获取损坏的数据
- Winsock recv() 返回不正确的数据
- 如何使用 winsock (c++) 发送recv 非字符数据
- recv (Winsock) 函数挂起,但数据可用
- C++ 绕道 Winsock recv 挂钩 - 自定义数据包
- C++ WinSock Recv 在接收 0 数据时终止线程而不是返回错误代码
- 如何使用c++使用recv()函数接收大数据
- 使用 recv() 接收部分数据是可能的
- 在本地将数据填充到recv缓冲区中
- 由于PROTOBUF服务器中的字符串数据类型变量和客户端通过cpp中recv端的套接字进行通信,因此正在获取segfau
- 套接字发送数据,但 recv 程序无法正常工作
- 接收recv数据,直到流结束(使用HTTP)
- 为什么节俭TBinaryProtocol读取recv数据比只是大小+内容更复杂