recv()库函数手册页提到:
它返回收到的字节数。 它通常返回任何可用的数据,直到请求的金额,而不是等待收到所需的全部金额。
如果我们使用阻塞recv()调用并请求100字节:
recv(sockDesc,buffer,size,0); /* Where size is 100. */
并且只有50个字节被服务器发送,那么这个recv()被阻塞,直到有100个字节可用,否则它将返回接收50个字节。
如何将对象的安全描述符重置为默认?
关于窗口和posix中的一个刻度
multithreading不利用多核心?
如何在Linux系统上以编程方式清除C ++中的文件系统内存caching?
Valgrind Memcheck输出
情况可能是这样的:
服务器发送仅50个字节后崩溃
错误的协议devise,其中服务器只发送50字节,而客户端期待100,服务器也在等待客户端的回复(即套接字closures连接尚未由服务器启动recv将返回)
我对Linux / Solaris平台感兴趣。 我没有开发环境来自己检查一下。
尝试从mm_struct-> start_code进行复制时,memcpy失败
linux内核中潜在的内存泄漏?
是否存在一个可靠的,跨平台的方式来重现SIGBUS?
Eclipse CDT – 如何在外部控制台(cmd.exe)中运行编译的.exe
Qt在windows下部署应用程序需要dll
当内部缓冲区中的数据返回时,recv将返回。 如果请求100个字节,它不会等到有100个字节。
如果你发送100个字节的“消息”,请记住TCP不提供消息,这只是一个流。 如果您正在处理应用程序消息,则需要在应用程序层处理,因为TCP不会这样做。
在调用recv(…,100)时,有很多很多情况下,100字节的send()调用在另一端可能无法完全读取,只有一个recv调用; 这里只是一些例子:
发送TCP堆栈决定捆绑15个写入调用,而MTU碰巧是1460,这取决于到达的数据的时间可能导致客户端的前14个调用取100个字节,而调用取60个字节 – 最后40个字节将在下次调用recv()时出现。 (但是如果你用100的缓冲区调用recv,你可能会得到前一个应用程序“消息”的最后40个字节和下一个消息的前60个字节)
发送缓冲区已满,也许阅读缓慢,或网络拥塞。 在某一点上,数据可能会通过,而清空缓冲区时,最后一块数据不是100的倍数。
接收缓冲区已满,而您的应用程序recv()该数据,它所拉起的最后一个块只是部分,因为该消息的整个100字节不适合缓冲区。
许多这样的情况是很难测试的,特别是在一个你可能没有很多拥塞或者数据包丢失的局域网上 – 随着你发送/产生消息的速度,情况可能会有所不同。
无论如何。 如果你想从套接字读取100个字节,请使用类似的东西
int readn(int f,void *av,int n) { char *a; int m,t; a = av; t = 0; while(t < n){ m = read(f,a+t,nt); if(m <= 0){ if(t == 0) return m; break; } t += m; } return t; }
…
if(readn(mysocket,BUFFER_SZ) != BUFFER_SZ) { //something really bad is going on. }
行为是由两件事情决定的。 接收到低水位标志以及是否通过MSG_WAITALL标志。 如果你传递这个标志,那么即使服务器崩溃,呼叫也会被阻塞,直到收到请求的字节数。 其他方面,只要在套接字的接收缓冲区中至少有SO_RCVLOWAT字节可用,它就会返回。
SO_RCVLOWAT
设置套接字输入操作要处理的最小字节数。 SO_RCVLOWAT的默认值为1.如果SO_RCVLOWAT设置为较大值,阻塞接收呼叫通常会等待,直到它们接收到低水位值或请求数量中的较小值。 (如果发生错误,信号被捕获,或者接收队列中的下一个数据类型与返回的数据类型(例如带外数据)不同,它们可以返回低于低水位标记)。 该选项采用一个int值。 请注意,并非所有实现都允许设置此选项。
如果您仔细阅读报价,最常见的情况是:
套接字正在接收数据。 那100个字节需要一些时间。
recv()调用已经完成。
如果缓冲区中有多于0个字节,则recv()返回可用并不等待的内容。
虽然有0个字节可用,但块和线程系统的粒度决定了多长时间。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。