网络传输 MTU 最大是 1500 扣除以太网 TCP IP 报文头,如果我 read 一个已经握手好的 TCP 的 fd 并设置 buffer 是 4096,操作系统是尽量快速返回还是尽量塞满我的 buffer 之后再返回?

2020-12-26 08:05:30 +08:00
 lewis89
2571 次点击
所在节点    程序员
11 条回复
lewis89
2020-12-26 08:08:36 +08:00
网络传输 MTU 最大是 1500 扣除以太网 TCP IP 报文头,如果我 read 一个已经握手好的 TCP 的 fd 并设置 buffer 是 4096,操作系统是尽量快速返回还是尽量塞满我的 buffer 之后再返回?
fff333
2020-12-26 08:49:37 +08:00
塞满
zhs227
2020-12-26 08:50:18 +08:00
有个 NAGLE 算法,发包时会稍微等一下,凑齐一个大包。可以使用 sockopt TCP_NODELAY 来关掉。读的时候应该不会等,缓冲区里有多少就读多少,除非还没有收到,或者是头部阻塞了在等重传。

想要塞满 buffer 可以多读几次,直到大于一个 buffer 以后,把多余的那一点缓存起来,放到下一轮读取里。
lewis89
2020-12-26 08:52:32 +08:00
@zhs227 #3 老哥真及时,我刚在 StackOverflow 上 看到

Each send call is a kernel call. But kernel calls do not correspond to individual packets, unless you've disabled packet coalescing. I suggest you read about the Nagle algorithm.

https://stackoverflow.com/questions/28785437/tcp-sockets-send-buffer-size-efficiency
lewis89
2020-12-26 08:54:05 +08:00
@zhs227 #3 主要是多读几次 会不会造成 频繁上下文切换开销大的情况
lewis89
2020-12-26 08:55:39 +08:00
@zhs227 #3 好吧 我误解了,既然发送方有 nagle 那么 read 方 自然不会被拆
lewis89
2020-12-26 09:04:34 +08:00
@zhs227 #3 Indeed, the wikipedia article strongly recommends you buffer writes yourself and disable Nagle. Reduced cost of kernel calls is another benefit.
lewis89
2020-12-26 09:05:15 +08:00
@zhs227 #3 这又是什么说法,启用 NODELAY,可以减少系统调用
carlclone
2020-12-26 09:14:04 +08:00
意思是你自己在 user space 做缓存,而不是发给内核,内核帮你做缓存
carlclone
2020-12-26 09:15:15 +08:00
缓冲..打错了
zhs227
2020-12-26 09:52:52 +08:00
nagle 算法最主要的是如果你发送连续的小包,他会等一个计时器的长度,如果计时器的长度里有可以拼到一起的数据,就会拼在一起发送。这样会以延迟换取网络上发送的包数。但对于某些时间敏感的内容,比如 ssh,telnet,Nagle 算法并不合适。

上面说可以减少系统调用的应该是让应用自己凑到一定长度再发。

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

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

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

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

© 2021 V2EX