read: Transport endpoint is not connected
调用 select() 相关函数编程时,委托内核对需要监测的文件描述符进行检测,检测的内容可以理解为两个方面:
- 用于的监听套接字文件描述符
- 用于通信的套接字文件描述符
不论哪种文件描述符对应的缓冲区发生改变,内核都会将文件描述符数组对应值置1。
问题来了
当只有监听文件描述符对应缓冲区发生变化,而通信文件描述符没变化时,调用 select() 会有返回值 1. 因为只有一个文件描述符发生变化。
而编写程序的逻辑是先判断是否是监听文件描述符发生变化,如果是,要通过其生成一个用于通信的文件描述符。此时其实我们这一轮的工作已经完成,直接下轮循环调用 select() 即可,也可对。但如果没有直接下轮循环,而是继续去进行遍历文件描述符数组进行读写操作的判断,并且遍历文件描述符数组是从 0 开始的,就会出问题:read: Transport endpoint is not connected
。
分析
这个问题是因为我们读取的是用于监听的文件描述符的缓冲区。因为我们这一轮循环只有一个文件描述符发生了变化,也进行了判断 发生变化的文件描述符就是监听文件描述符,接收连接 其实工作已经完成。结果继续遍历去读写数据,还是从文件描述符的头部 0 开始遍历,必然又会遍历到监听文件描述符为 1. 此时 read() 就会报错。
解决方案
方案1:
判断发生变化的文件描述符为 监听描述符 并完成连接业务后,进行一次判断,判断 select() 的返回值是否为 1,为 1 则说明这次委托检测只有客户端连接进来了,没有客户端往服务器端写数据。则和连接进来的客户端建立连接后将其加入下次监听行列就好了,就可以下次循环了。
if (FD_ISSET(lisfd, &tmp))
{// 找到连接进来的客户端对应的文件描述符,进行连接struct sockaddr_in cliaddr;int len = sizeof(cliaddr);int comfd = accept(lisfd, (struct sockaddr*)&cliaddr, &len);// 将用于通信的文件描述符 添加到需要委托内核检测的数组集合中FD_SET(comfd, &rdset);// 更新下次内核遍历时,需要遍历到的地方maxfd = comfd > maxfd ? comfd : maxfd;if (ret == 1) // 加一个判断,满足直接下一轮循环{continue;} }
方案2:
如果不采用方案1,也就是不在 accept() 最后判断 select() 的返回值 是否等于1。则在读写遍历的范围上注意一下也可以。FD_SET 在设置监测文件描述符时每次都是将最小的没有被占用的文件描述符设置为1,所以监听文件描述符一定在通信文件描述符之前,我们只要将遍历范围的起始值设置为 lisfd + 1 即可。
for (int i = lisfd + 1; i <= maxfd; i++){if (FD_ISSET(i, &tmp)){// 说明这个文件描述符对应的客户端发来了数据// 读写数据}}
问题解决
read: Transport endpoint is not connected相关推荐
- Android异常总结--- java.net.SocketTimeoutException: Transport endpoint is not connected
1.查询号码归属地中出现的异常: java.net.SocketTimeoutException: Transport endpoint is not connected at org.apache ...
- 解决在ceph对象网关中使用s3fs报错“unable to access MOUNTPOINT /s3: Transport endpoint is not connected”
s3fs简介 简要来说,就是将s3的存储桶,文件,文件列表可以通过挂载到本地形成一个本地文件系统,方便浏览和查看目录结构,由于ceph rgw服务兼AWS S3,所以通过s3fs工具我们也能够将c ...
- linux socket 错误 Transport endpoint is not connected 在 recv shutdown 中的触发时机
1.recv触发情况 用错了socket,把监听socket 和 连接socket 错误使用.实例如下: for(;;){socklen_t len = sizeof(client_address); ...
- sshfs rm: cannot rm ‘mybucket’: Transport endpoint is not connected
The fold is busy(now mounted as a FUSE), you can not rm or stat it, just umount it, and this will re ...
- Linux中errno使用
当linux中的C api函数发生异常时,一般会将errno变量(需include errno.h)赋一个整数值,不同的值表示不同的含义,可以通过查看该值推测出错的原因,在实际编程中用这一招解决了不少 ...
- linux命令执行返回值(附错误对照表)
转自:http://blog.sina.com.cn/s/blog_6739945f0100zt4b.html 在 Linux 下,不管你是启动一个桌面程序也好,还是在控制台下运行命令,所有的程序在结 ...
- PHP的CURL报错的排查记录:短连接的成本真的很高啊
2019独角兽企业重金招聘Python工程师标准>>> 最近在优化接口的时候发现,php的curl调用远程接口的时候出现了大量的这种错误 * Resolving timed out ...
- linux error errno 错误对照
errno 在 <errno.h> 中定义,错误 Exx 的宏定义在 /usr/include/asm-generic 文件夹下面的 errno-base.h 和 errno.h,分别定 ...
- Linux C编程--进程介绍4--errno
当linux中的C api函数发生异常时,一般会将errno变量(需includeerrno.h)赋一个整数值,不同的值表示不同的含义,可以通过查看该值推测出错的原因,在实际编程中用这一招解决了不少原 ...
最新文章
- 2021年移动云API应用创新开发大赛火热开启!
- Linux的用户和用户组管理
- 基于J2EE+JBPM3.x/JBPM4.3+Flex流程设计器+Jquery+授权认证)企业普及版贝斯OA与工作流系统...
- SharePoint 开发TimerJob 介绍
- php a链接怎么传id_PHP函数参数的传递
- DEDECMS 关键字不能小于2个字节!
- 将学校版JAVA系统迁移到Mysql数据库的工作安排
- String与Integer相互转换
- matlab 上穿,Matlab混入模式(Mixin)
- 解析含有资源类型的字符串
- Spring Boot——开发新一代Spring应用
- Redis 3.2.8 安装与配置
- Django 错误信息:AttributeError: 'str' object has no attribute '_meta'
- Python语言程序设计基础_实验5 序列型数据_答案_通识教育必修课程_上海师范大学
- 华南师大考研旅游管理系2010-2016年分数线汇总
- ubuntu中修改只读文件
- MySQL数据库--韩顺平老师课
- 转载的 C#.NET面试题
- 解压上传zip文件并获取excel表数据
- 面试|C# .net 面试题
热门文章
- メイプルストーリー、「魔法少女まどか☆マギカ」とのタイアップを実施
- VDMA学习(一)pg020总结
- 聚醚酮酮(PEKK)的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- 【基础知识】~ 进制转换、补码、格雷码、BCD码、独热码
- NDK abiFilters含义
- 利用NGINX搭建部署直播流媒体服务器
- php中pre的作用
- 搭载鸿蒙的华为什么时间上市,[财经]华为鸿蒙系统什么时候上市?搭载鸿蒙系统的华为手机或很快推出 - 南方财富网...
- 中国历史上的女子的十二种结局
- IDEA调试出现帧不可用