一直以为在阻塞的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接收数据 未达到指定长度返回问题相关推荐

  1. TCP协议发送和接收数据

    TCP协议发送与接收数据 一.发送数据 1.使用Socket类的构造方法创建Socket对象 Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指 ...

  2. linux 非阻塞 socket - Google 搜索

    linux 非阻塞 socket - Google 搜索 linux c实现超时.非阻塞socket的函数select - Yunlu Liu (刘云璐) sites.google.com/site/ ...

  3. Linux/windows com串口 java 接收数据 并解析 web程序

    1.首先应公司要求再 com 口本来使用 .net 由于 .net 适用 linux 太麻烦 改为java 准备工作 准备 RXTXconmm.jar(版本很重要) 因为版本问题我搞了一天. 主要讲述 ...

  4. linux下利用RTMP协议接收数据

    在windows下利用RTMP接收数据的代码有很多的例子可以参考,但是在linux下利用rtmp协议接收数据,例子特别少.在无计可用的情况下,只能自己写代码了. 在写代码之前需要做一点事情,去rtmp ...

  5. usb键码转linux键值,CH554串口接收数据转USB键值程序 CH559模拟USB复合设备,键鼠,支持类命令...

    /********************************** (C) COPYRIGHT ******************************* * File Name        ...

  6. Java中通过TCP协议发送和接收数据-Socket编程

    TCP TCP协议是面向连接.保证高可靠性(数据无丢失.数据无失序.数据无错误.数据无重复到达)传输层协议. TCP通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的所以只能用于端到端 ...

  7. Qt TCP通信readAll()读取接收数据时无法读完大数据量的解决法案

    在测试利用TCP传输图片的时候,服务器使用Qt的TCP类库.在TCP接收槽函数中使用readAll()成员函数的时候发现readAll()并不能读取全部的数据,比如,在客户端发送一张2MB的图像,但是 ...

  8. java 基于tcp客户端服务端发送接收数据

    客户端: package demo03;import java.io.IOException; import java.io.InputStream; import java.io.OutputStr ...

  9. Linux下串口编程遇 接收数据错误问题及原因

    近日在调试串口的时候发现,另一设备向我ARM板的串口发送0x0d,我接收之后变成了0x0a,这是问题一:另外当对方向我发送一串数据,如果其中有0x11,那么我总是漏收此数,这是问题二. 由于问题莫名其 ...

最新文章

  1. Java 对synchronized的补充Lock锁
  2. 云上护航服务—保障云上的尖峰时刻
  3. sklearn 神经网络_sklearn中的数据预处理和特征工程
  4. Android adb.exe程序启动不起来,如何处理
  5. 记录使用websocket时因为Sec-Websocket-Protocol遇到的一个问题
  6. Appium+Robotframework实现Android应用的自动化测试-2:Windows中启动Appium和模拟器
  7. 前端学习(1667):前端系列实战课程之拖拽
  8. 遍历Map keySet和entrySet
  9. java 多线程 选择题_Java多线程之三道多线程练习题
  10. 大学生学java要去培训机构吗?
  11. txt格式单词导入有道词典生词本
  12. java 同比数据怎么算的_如何计算同比的计算公式?
  13. Software Architecture Patterns: Layered Architecture
  14. 怎么将计算机的网络恢复连接,win7怎么还原网络设置 win7本地连接不上的解决方法...
  15. NVIDIA NGC镜像使用笔记
  16. 2022年山东省安全员A证考试模拟100题及在线模拟考试
  17. 360众筹网_360众筹平台
  18. 找到组织了---perftest工作室 TIB工作室
  19. JavaWeb基础(黑马配套)
  20. Mock工具介绍,为什么使用Mock?

热门文章

  1. Linux_LAMP 最强大的动态网站解决方案
  2. GNSS NMEA ddmm.mmmmm格式转换
  3. Altium Designer从已有的PCB图中导出封装库
  4. 22 面向对象 名称空间 类与对象
  5. 获取节点及元素的代码
  6. 央行:货币政策稳健并不意味着一成不变
  7. Jsp 无法解析${}
  8. (1)java虚拟机概念和结构图
  9. 【Excel】Excel根据单元格背景色求和
  10. 使用Axis开发Web Service程序