socket 的客户端发送空字符与主动关闭是否有区别

2016-02-23 18:07:13 +08:00
 quietin
对于一个服务端和一个客户端这样的模型,两者建立了连接

我看到一些资料上看到,服务器收到 0bytes 的包就代表客户端要关闭
比如 https://wiki.python.org/moin/TcpCommunication
没有读到 data 的时候就认为客户端主动关闭而 break 了

我认为,没有读到 data 还是有两种情况,一种是客户端发送的空字符,另外一种就是客户端发 Fin 准备关闭,两种情况的 Fin 位应该不同

虽然客户端不发送空字符就可以解决问题,但服务端应该可以区别接收到的包中的 Fin 位吧,有没有区分的办法呢
6514 次点击
所在节点    Python
10 条回复
shuax
2016-02-23 18:22:10 +08:00
tcp/ip 详解 卷一
quietin
2016-02-23 19:08:23 +08:00
@shuax 书看了一部分,我比较希望获得答案
mengzhuo
2016-02-23 20:33:55 +08:00
书最好还是看看,配合 wireshark 抓包就清楚了。
必须有 fin 包双方才开始四次断开,否则就是超时。
而且发了 fin 没发够的话也会触发 timewait 行为。
根据包结构和位解析来说, fin 包还可以放 psh 数据,不过一般没这么实现的罢了。
gamexg
2016-02-23 20:40:26 +08:00
没试过,但是客户端 write 空应该不会实际发包,也就是服务端不会知道。虽然客户端系统有时会发送空包( ack 等)但是服务端 read 不会返回空的(阻塞模式)。
Strikeactor
2016-02-23 21:04:32 +08:00
你举的那个栗子,在没读到的时候,函数是阻塞的。。

就像你在那儿儿接水,接一盆端走接一盆端走,中间水压不够水暂时断流的话,人是会等在那儿一直到出水的。人走了而桶里没水,就一种可能,那就是水龙头被拧上了。。
skydiver
2016-02-23 21:06:27 +08:00
@Strikeactor 哈哈哈哈
quietin
2016-02-23 21:51:20 +08:00
@Strikeactor 阻塞这个我知道啊,感觉例子举得不好,基础不好容易被误导比如我
XiaoxiaoPu
2016-02-23 23:02:01 +08:00
@quietin 以用 read 函数读取 socket 为例:对于 socket 连接的*阻塞*读请求, 1: 如果对端没有写数据,那么会一直阻塞直到后面两种情况发生, 2: 如果接收到对端写的数据,那么会返回这次请求接收的数据的字节数, 3: 如果对端关闭连接\结束写操作(即发送 FIN),那么会返回 0 。你说的客户端发送空字符的情况,说法是不准确的, socket 上发送或接受的都是字节流,要么有数据,要么没数据,无所谓数据的内容,只看数据的字节数。
quietin
2016-02-24 10:38:58 +08:00
@gamexg 确实, TCP 不会发空包, UDP 会
quietin
2016-02-24 10:40:51 +08:00
@XiaoxiaoPu 我用 python 实验,对端关闭时就是收到空字符,不是 0
另外 tcp 不会发空包

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/258536

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX