linux tcp阻塞socket recv接收数据 未达到指定长度返回问题
一直以为在阻塞的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都会实现的。
可自定义数据包头 定义几个字节的数据包长度位 先接受长度 再接受数据包 结合recv的MSG_PEEK来使用
MSG_PEEK可以参考:linux socket recv函数 MSG_PEEK标志介绍 https://blog.csdn.net/whatday/article/details/96100572
linux tcp阻塞socket recv接收数据 未达到指定长度返回问题相关推荐
- TCP协议发送和接收数据
TCP协议发送与接收数据 一.发送数据 1.使用Socket类的构造方法创建Socket对象 Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指 ...
- linux 非阻塞 socket - Google 搜索
linux 非阻塞 socket - Google 搜索 linux c实现超时.非阻塞socket的函数select - Yunlu Liu (刘云璐) sites.google.com/site/ ...
- Linux/windows com串口 java 接收数据 并解析 web程序
1.首先应公司要求再 com 口本来使用 .net 由于 .net 适用 linux 太麻烦 改为java 准备工作 准备 RXTXconmm.jar(版本很重要) 因为版本问题我搞了一天. 主要讲述 ...
- linux下利用RTMP协议接收数据
在windows下利用RTMP接收数据的代码有很多的例子可以参考,但是在linux下利用rtmp协议接收数据,例子特别少.在无计可用的情况下,只能自己写代码了. 在写代码之前需要做一点事情,去rtmp ...
- usb键码转linux键值,CH554串口接收数据转USB键值程序 CH559模拟USB复合设备,键鼠,支持类命令...
/********************************** (C) COPYRIGHT ******************************* * File Name ...
- Java中通过TCP协议发送和接收数据-Socket编程
TCP TCP协议是面向连接.保证高可靠性(数据无丢失.数据无失序.数据无错误.数据无重复到达)传输层协议. TCP通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的所以只能用于端到端 ...
- Qt TCP通信readAll()读取接收数据时无法读完大数据量的解决法案
在测试利用TCP传输图片的时候,服务器使用Qt的TCP类库.在TCP接收槽函数中使用readAll()成员函数的时候发现readAll()并不能读取全部的数据,比如,在客户端发送一张2MB的图像,但是 ...
- java 基于tcp客户端服务端发送接收数据
客户端: package demo03;import java.io.IOException; import java.io.InputStream; import java.io.OutputStr ...
- Linux下串口编程遇 接收数据错误问题及原因
近日在调试串口的时候发现,另一设备向我ARM板的串口发送0x0d,我接收之后变成了0x0a,这是问题一:另外当对方向我发送一串数据,如果其中有0x11,那么我总是漏收此数,这是问题二. 由于问题莫名其 ...
最新文章
- Java 对synchronized的补充Lock锁
- 云上护航服务—保障云上的尖峰时刻
- sklearn 神经网络_sklearn中的数据预处理和特征工程
- Android adb.exe程序启动不起来,如何处理
- 记录使用websocket时因为Sec-Websocket-Protocol遇到的一个问题
- Appium+Robotframework实现Android应用的自动化测试-2:Windows中启动Appium和模拟器
- 前端学习(1667):前端系列实战课程之拖拽
- 遍历Map keySet和entrySet
- java 多线程 选择题_Java多线程之三道多线程练习题
- 大学生学java要去培训机构吗?
- txt格式单词导入有道词典生词本
- java 同比数据怎么算的_如何计算同比的计算公式?
- Software Architecture Patterns: Layered Architecture
- 怎么将计算机的网络恢复连接,win7怎么还原网络设置 win7本地连接不上的解决方法...
- NVIDIA NGC镜像使用笔记
- 2022年山东省安全员A证考试模拟100题及在线模拟考试
- 360众筹网_360众筹平台
- 找到组织了---perftest工作室 TIB工作室
- JavaWeb基础(黑马配套)
- Mock工具介绍,为什么使用Mock?