socket读写返回值的处理

在调用socket读写函数read(),write()时,都会有返回值。如果没有正确处理返回值,就可能引入一些问题

总结了以下几点

1当read()或者write()函数返回值大于0时,表示实际从缓冲区读取或者写入的字节数目

2当read()函数返回值为0时,表示对端已经关闭了 socket,这时候也要关闭这个socket,否则会导致socket泄露。netstat命令查看下,如果有closewait状态的socket,就是socket泄露了

当write()函数返回0时,表示当前写缓冲区已满,是正常情况,下次再来写就行了。

3当read()或者write()返回-1时,一般要判断errno

如果errno == EINTR,表示系统当前中断了,直接忽略

如果errno == EAGAIN或者EWOULDBLOCK,非阻塞socket直接忽略;如果是阻塞的socket,一般是读写操作超时了,还未返回。这个超时是指socket的SO_RCVTIMEO与SO_SNDTIMEO两个属性。所以在使用阻塞socket时,不要将超时时间设置的过小。不然返回了-1,你也不知道是socket连接是真的断开了,还是正常的网络抖动。一般情况下,阻塞的socket返回了-1,都需要关闭重新连接。

4.另外,对于非阻塞的connect,可能返回-1.这时需要判断errno,如果 errno == EINPROGRESS,表示正在处理中,否则表示连接出错了,需要关闭重连。之后使用select,检测到该socket的可写事件时,要判断getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen),看socket是否出错了。如果err值为0,则表示connect成功;否则也应该关闭重连

5 在使用epoll时,有ET与LT两种模式。ET模式下,socket需要read或者write到返回-1为止。对于非阻塞的socket没有问题,但是如果是阻塞的socket,正如第三条中所说的,只有超时才会返回。所以在ET模式下千万不要使用阻塞的socket。那么LT模式为什么没问题呢?一般情况下,使用LT模式,我们只要调用一次read或者write函数,如果没有读完或者没有写完,下次再来就是了。由于已经返回了可读或者可写事件,所以可以保证调用一次read或者write会正常返回。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

request;response 对象

response ? 1. response简介 response的类型为HttpServletResponse,它是Servlet的service()方法的参...

3627
来自专栏大闲人柴毛毛

Java并发编程的艺术(六)——线程间的通信

多条线程之间有时需要数据交互,下面介绍五种线程间数据交互的方式,他们的使用场景各有不同。 1. volatile、synchronized关键字 PS:关于vo...

3664
来自专栏炸天帮5

win32进程概念之句柄表,以及内核对象.

我们知道.我们使用CreateProcess 的时候会返回一个进程句柄.以及线程句柄. 其实在调用CreateProcess的时候.内核中会新建一个EPROCE...

911
来自专栏LanceToBigData

linux(六)之文本操作

接下来我们一起来看一下再linux中怎么去对文本进行操作的 一、文本文件 既然要操作文本,所以我们要对文本有一个了解,那什么是文本文件呢。 文本文件是一种由若干...

2686
来自专栏乐百川的学习频道

Flask 快速入门

Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务。本文参考自Flask官方文档,大部分代码引用自官方...

33110
来自专栏Python

linux每日命令(17):which命令

我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索:

1474
来自专栏程序员同行者

python3模块: os

1113
来自专栏三木的博客

Linux shell 程序设计2——bash的内置命令

常用的内置命令忽略,来看看shell编程中其他一些重要的内置命令: 1、help:显示所有内置命令列表,或显示一个具体命令的用法。 -s: 表示列出命令的语法...

2196
来自专栏程序员同行者

django基础之二

1384
来自专栏python3

python3--队列Queue,管道Pipe,进程之间的数据共享,进程池Pool,回调函数callback

既打印了主进程put的值,也打印了子进程put的值,在进程中使用队列可以完成双向通信

5221

扫码关注云+社区

领取腾讯云代金券