socket 中read返回0的情况
当client,调用read(socketfd,buffer,n)时,返回0的情况:
1、server端调用了close(soketfd)函数
2、server调用了close(fd,SHUT_WR),关闭server端的写连接,半关闭

关于close 和shutdown的过程
一.void close(fd):close发送的是FIN分节(不一定是发送FIN,也可能发送RST(如果local接受缓冲区的数据没有被读完);sever端close时候,如果发送了FIN,则这个sokcet在server端将不能够被read和write,会返回错误(如果有read或者write则返回errno9: Bad file descriptor错误)
默认状态,是把此套接字标记为关闭状态(真正只是把套接字的引用计数-1),close函数都立刻返回。如果引用计数为0,才开始发送四字节的FIN分节(连接终止序列),close在sever端调用之后,会立刻返回,同时尽力发送此时仍然在套接字发送缓冲区的发送数据,在此之后才会发出FIN四分节的连接终止序列。
扩展:在父子进程模型中,我们每次fork子进程之后,都需要在父进程中关闭连接套接字(connfd),而在子进程中都需要关闭监听套接字,此模型中accept在fork函数之前。
原因有两点:
1、如果不关闭,则父进程将消耗所以的可用描述符,因为它每次accept新连接,都得返回一个新的未用的fd
2.如果不关父进程中的connfd,则父子进程的引用计数都保持在2,即便子进程关闭,只是把引用计数-1,这样由于父进程正常情况永远不会关闭,所以这些连接其实永远都不会关闭,消耗资源,因为这阻挡了终止序列FIN的发出。
二:shutdown(int fd,int how)
close是关闭读写两个方向的数据传输,而shutdown指定关闭SHUT_WRS称为半关闭,只关闭一个方向,另一个方向依然可用。
两个参数的意思:
shutdown:SHUT_RD
server端关闭连接的读这一半,进程不能再对这样的套接字调用任何读操作(如果有read则返回errno9: Bad file descriptor错误)。这个SHUT_RD标志告诉内核,我绝食了,再有吃的来(数据),不要放我的餐桌上了(接收缓冲区)直接扔给狗吃把。(但是此时client还是可以发送给server套接字的接收缓冲区,只是被TCP抛弃而已)
套接字不再有数据可接受,server不能调用read,server进程仍可往套接字发送数据,server套接字接收缓冲区中所有数据被丢弃,再接收到的任何数据都被TCP丢弃,对套接字发送缓冲区没有任何影响;
shutdown:SHUT_WR(又叫做半关闭):与close不同的是,无论引用计数是否为0,这样的操作都进行,此后server进程不能对此套接字进行写操作)
当前server套接字发送缓冲区中的内容被发送到对端,后跟正常的TCP连接终止序列(即发送FIN),
关闭连接的写这一半,进程不能再对这样的套接字调用任何写操作;(如果server有write则返回errno9: Bad file descriptor错误)
在server的套接字上不能再发出发送请求,进程仍可从套接字接收数据,当前server套接字发送缓冲区中的内容被发送到对端,后跟正常的TCP连接终止序列(即发送FIN),对套接字接收缓冲区无任何影响;
注意:1. server端,close调用之后如果在local TCP buffer内如果还有数据没有读取会给对方,则主动直接发送RST给client, 否则发送FIN,这取决于调用close时刻local TCP buffer的状态, 跟对端是不是继续发送数据无关。
2. shutdown关闭读不会给对方发FIN, 只有关闭写才会发FIN, 而且跟local TCP buffer状态没关系,只发送FIN包,从不发送RST
总结:shutdown从不发送RST给对端(只发送FIN),只有close在接收缓存区没有被读完的条件下,才发送给对端RST。
socket 中read返回0的情况的更多相关文章
- Java中除数为0的情况
转自http://blog.csdn.net/alanzyy/article/details/8591534 在数学中,规定被除数不能为0 那么在Java程序中一旦出现除数为0时,会出现什么情况呢: ...
- JavaScript中的ParseInt("08")和“09”返回0的原因分析及解决办法
今天在程序中出现一个bugger ,调试了好久,最后才发现,原来是这个问题. 做了一个实验: alert(parseInt("01")),当这个里面的值为01====>07时 ...
- 在一个exe文件中查找指定内容,找到则返回起始位置, 否则返回0
//在一个exe文件中查找指定内容,找到则返回起始位置, 否则返回0//如果某字符串, 直接传入字符串进来//如果要查找16进制,则用如下格式传参进来: #$1A#$2A#$3A function F ...
- 关于 OnCloseQuery: 顺序、不能关机等(所有的windows的广播消息都是逐窗口传递的)——如果一个窗体的OnCloseQuery事件中如果写了代码那么WM_QUERYENDSESSION消息就传不过去了msg.result会返回0,关机事件也就停止了
系统关闭窗体的事件顺序为: OnCloseQuery ----> OnClose ----> OnDestroy 下面的代码说明问题: unit Unit3; interface uses ...
- sql server中的charindex函数用法解析(在一段字符中搜索字符或者字符串-----返回expression1在expression2出现的位置;反之,返回0)
https://blog.csdn.net/xinghuo0007/article/details/70651358 知识点一:charindex()语法 CHARINDEX ( expression ...
- Python:判断文本中的用户名在数据库中是否存在,存在返回1,不存在返回0
下面是我写的python的一个小脚本,作用是:判断文本中的用户名在数据库中是否存在,存在返回1,不存在返回0.用的是MySQL数据库. 要注意的是:strip函数的使用,该函数的作用是去除字符串两端多 ...
- Comparator中返回0导致数据丢失的大坑
今天对一列数据进行排序,因为存储的是Map结构,要实现排序,马上就想到了TreeMap,于是查到API,这样新建TreeMap就能实现添加的时候就自动排序. new TreeMap<>(n ...
- 删除顺序表L中下标为p(0<=p<=length-1)的元素,成功返回1,不成功返回0,并将删除元素的值赋给e
原创:转载请注明出处. [天勤2-2]删除顺序表L中下标为p(0<=p<=length-1)的元素,成功返回1,不成功返回0,并将删除元素的值赋给e 代码: //删除顺序表L中下标为p(0 ...
- 求一个整型数字中有没有相同的部分,例如12386123这个整型数字中相同的部分是123,相同的部分至少应该是2位数,如果有相同部分返回1,如果没有则返回0。方法是先将整型数字转换到数组中,再判断。函数为 int same(int num)其中num是输入的整型数字
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Test { pub ...
随机推荐
- leetcode377
public class Solution { private int[] dp; public int CombinationSum4(int[] nums, int target) { dp = ...
- XSS的各种用途
0x01 最常见之窃取用户cookie 当cookie没有设置HttpOnly属性时,可以通过javascript代码创建img,script,iframe等标签,并把src属性设置为自己部署的xss ...
- python request (1) 环境
环境准备 requests httpbin virtualenv pip python 安装 #mkdir /home/requests #yum install -y python-pip ...
- java获取Linux持续运行时间及友好显示
一.uptime命令 uptime命令可以查看系统的运行时间和负载 终端输入uptime 04:03:58 up 10 days, 13:19, 1 user, load average: 0.54, ...
- 通过Excel导入Mysql 超过65535条数据的办法
1.截取 65534条数据,进行分sheet,然后1个sheet导入一张表,最后进行整合! 2.采用TXT导入方式,TXT的导入暂时没发现限制的数据条数,下午用TXT导入74万条数据成功 3.如果遇到 ...
- js对象简单、深度克隆(复制)
javascript的一切实例都是对象,只是对象之间稍有不同,分为原始类型和合成类型.原始类型对象指的是字符串(String).数值(Number).布尔值(Boolean),合成类型对象指的是数组( ...
- 关于FILL_PARENTE和match_parent布局属性
在观看早期的代码的时候,经常会看到FILL_PARENT属性,但是新的代码中却有了MATCH_PARENT 那么,两者有何区别呢? 答案是,没有,只是换了个名字而已,均为-1
- git 删除本地分支和远程分支
(1)使用命令git branch -a 查看所有分支 其中,remote/origin/master表示的是远程分支 (2)删除远程分支 使用命令 git push origin --delete ...
- 1054D&EZOJ #93 Changing Array
传送门 分析 我们可以对一个数列求前缀和,如果pre[l]=pre[r]则我们可以知道区间[l,r]一定不合法 于是我们就要让不合法的区间尽量少 我们知道对于一个数$x$,他只受x和$(2^k-1)$ ...
- CF1030F Putting Boxes Together
昨晚的比赛题.(像我这种蒟蒻只能打打div2) 题意 给你$n$个物品,每一个物品$i$,有一个权值$w_i$和一个位置$a_i$,定义移动一个物品$i$到位置$t$的代价为$w_i * \left ...