在阻塞式的tcp连接中使用recv接收数据未达到指定长度返回问题
来源:互联网 发布:华东师范大学网络 编辑:程序博客网 时间:2024/06/06 12:53
转自http://naso.iteye.com/blog/1927483
一直以为在阻塞的tcp socket上使用read/recv读取的数据长度一定和指定的读取长度一致,但是实际测试时发现往往返回的长度都比指定长度短,查找资料发现其实是一直误解了这个函数。
引用《UNIX网络编程 卷一 套接字联网API》3.9中的说法:字节流套接口(如tcp套接口)上的read和write函数所表现的行为不同于通常的文件IO。字节流套接口上的读或写输入或输出的字节数可能比要求的数量少,但这不是错误状况,原因是内核中套接口的缓冲区可能已达到了极限。此时所需的是调用者再次调用read或write函数,以输入或输出剩余的字节。
书中给出了readn和writen函数解决这个问题。
- ssize_t /* Read "n" bytes from a descriptor. */
- readn(int fd, void *vptr, size_t n)
- {
- size_t nleft;
- ssize_t nread;
- char *ptr;
- ptr = vptr;
- nleft = n;
- while (nleft > 0) {
- if ( (nread = read(fd, ptr, nleft)) < 0) {
- if (errno == EINTR)
- nread = 0; /* and call read() again */
- else
- return(-1);
- } else if (nread == 0)
- break; /* EOF */
- nleft -= nread;
- ptr += nread;
- }
- return(n - nleft); /* return >= 0 */
- }
- ssize_t /* Write "n" bytes to a descriptor. */
- writen(int fd, const void *vptr, size_t n)
- {
- size_t nleft;
- ssize_t nwritten;
- const char *ptr;
- ptr = vptr;
- nleft = n;
- while (nleft > 0) {
- if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
- if (nwritten < 0 && errno == EINTR)
- nwritten = 0; /* and call write() again */
- else
- return(-1); /* error */
- }
- nleft -= nwritten;
- ptr += nwritten;
- }
- return(n);
- }
在13.3中提供了另外一个选择:
在recv中,可以使用MSG_WAITALL标志保证要求读取的字节数。即使使用了MSG_WAITALL标志,如果发生了下列情况:(a)捕获一个信号(b)连接被终止,或(c)在套接口上发生错误,这个函数返回的字节数仍会比请求的少。
而且要注意的是这个标志并不是每个版本的recv都会实现的。
0 0
- 在阻塞式的tcp连接中使用recv接收数据未达到指定长度返回问题
- windows tcp连接 recv()立即返回 接收字符为空
- socket tcp使用recv接收数据时,返回errno错误代码88
- 在多线程中,recv非阻塞模式带来的问题
- WSAAsynSelect()模型 FD_READ事件中recv()接收数据的返回值讨论
- recv返回值----任意长度的可读的数据
- socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题
- socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题
- socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题
- socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题
- 使用NDK开发阻塞式socket客户端程序,recv读取数据无法关闭socket问题的解决
- Windows socket通信出现接收数据时出现recv返回大于0,但缓冲区为大小为0的问题
- 关于socket阻塞与非阻塞情况下的recv、seng、read、write返回值问题
- 关于socket阻塞与非阻塞情况下的recv、seng、read、write返回值问题
- 阻塞状态的recv返回值
- 阻塞状态的recv返回值
- 简单的TCP连接(send/recv使用的sockfd)
- JSTL中截取一定长度的字符串长度,如果超过指定长度在未尾加“......”,否则返回原来字符串。
- 待我考研归来更新
- 用MSVC2015编译Qt5.6(包含openssl、webengine)
- 如何单独编译Android源代码中的模块
- c++作业5
- Pojo和JavaBean的区别
- 在阻塞式的tcp连接中使用recv接收数据未达到指定长度返回问题
- 【深度专访】大数据时代——数据乃企业之“脊梁”
- BTrace分析和使用
- gitbook安装使用
- 【HUSTOJ】1050: 字符图形6-星号倒三角
- runtime 一键改变字体 - CocoaChina_让移动开发更简单
- Leetcode - Move Zeroes
- [Java视频笔记]day17
- MIPI概述