英文:
How does TCP combine data when sending a big data packet which is over MSS?
问题
这是一个tcpdump演示。
- seq 1 - 52001是大数据,超过我的回环MSS(16384)。
- seq 52001 - 52013是小数据。
TCP如何知道seq 1 - 52001是一个组合的数据块,seq 52001 - 52013是另一个组合的数据块?
以下是我的客户端代码:
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:30000")
if err != nil {
fmt.Println("拨号失败,错误", err)
return
}
defer conn.Close()
msg := ""
for i := 0; i < 2000; i++ {
msg += `你好,你好。你好吗?`
}
conn.Write([]byte(msg))
conn.Write([]byte("演示内容"))
}
英文:
Here is a tcpdump demo.
- seq 1 - 52001 is big data, over my loopback MSS (16384).
- seq 52001 - 52013 is small data.
How does TCP know seq 1 - 52001 is a combined data block and seq 52001 - 52013 is another combined data block?
23:10:00.773752 IP localhost.56006 > localhost.30000: Flags [S], seq 3081455670, win 65535, options [mss 16344,nop,wscale 6,nop,nop,TS val 807676974 ecr 0,sackOK,eol], length 0
23:10:00.774059 IP localhost.30000 > localhost.56006: Flags [S.], seq 1040822423, ack 3081455671, win 65535, options [mss 16344,nop,wscale 6,nop,nop,TS val 3518795094 ecr 807676974,sackOK,eol], length 0
23:10:00.774101 IP localhost.56006 > localhost.30000: Flags [.], ack 1, win 6379, options [nop,nop,TS val 807676974 ecr 3518795094], length 0
23:10:00.774125 IP localhost.30000 > localhost.56006: Flags [.], ack 1, win 6379, options [nop,nop,TS val 3518795094 ecr 807676974], length 0
23:10:00.783835 IP localhost.56006 > localhost.30000: Flags [.], seq 1:16333, ack 1, win 6379, options [nop,nop,TS val 807676984 ecr 3518795094], length 16332
23:10:00.783840 IP localhost.56006 > localhost.30000: Flags [.], seq 16333:32665, ack 1, win 6379, options [nop,nop,TS val 807676984 ecr 3518795094], length 16332
23:10:00.783843 IP localhost.56006 > localhost.30000: Flags [.], seq 32665:48997, ack 1, win 6379, options [nop,nop,TS val 807676984 ecr 3518795094], length 16332
23:10:00.783847 IP localhost.56006 > localhost.30000: Flags [P.], seq 48997:52001, ack 1, win 6379, options [nop,nop,TS val 807676984 ecr 3518795094], length 3004
23:10:00.783861 IP localhost.56006 > localhost.30000: Flags [P.], seq 52001:52013, ack 1, win 6379, options [nop,nop,TS val 807676984 ecr 3518795094], length 12
23:10:00.783874 IP localhost.56006 > localhost.30000: Flags [F.], seq 52013, ack 1, win 6379, options [nop,nop,TS val 807676984 ecr 3518795094], length 0
23:10:00.784068 IP localhost.30000 > localhost.56006: Flags [.], ack 16333, win 6124, options [nop,nop,TS val 3518795104 ecr 807676984], length 0
23:10:00.784106 IP localhost.30000 > localhost.56006: Flags [.], ack 32665, win 5869, options [nop,nop,TS val 3518795104 ecr 807676984], length 0
23:10:00.784110 IP localhost.30000 > localhost.56006: Flags [.], ack 48997, win 5614, options [nop,nop,TS val 3518795104 ecr 807676984], length 0
23:10:00.784114 IP localhost.30000 > localhost.56006: Flags [.], ack 52001, win 5567, options [nop,nop,TS val 3518795104 ecr 807676984], length 0
23:10:00.784121 IP localhost.30000 > localhost.56006: Flags [.], ack 52013, win 5567, options [nop,nop,TS val 3518795104 ecr 807676984], length 0
23:10:00.784139 IP localhost.30000 > localhost.56006: Flags [.], ack 52014, win 5567, options [nop,nop,TS val 3518795104 ecr 807676984], length 0
23:10:00.798479 IP localhost.30000 > localhost.56006: Flags [F.], seq 1, ack 52014, win 5567, options [nop,nop,TS val 3518795119 ecr 807676984], length 0
23:10:00.798571 IP localhost.56006 > localhost.30000: Flags [.], ack 2, win 6379, options [nop,nop,TS val 807676999 ecr 3518795119], length 0
Here is my client code:
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:30000")
if err != nil {
fmt.Println("dial failed, err", err)
return
}
defer conn.Close()
msg := ""
for i := 0; i < 2000; i++ {
msg += `Hello, Hello. How are you?`
}
conn.Write([]byte(msg))
conn.Write([]byte("demo content"))
}
答案1
得分: 2
TCP如何知道序列1 - 52001是一个组合数据块,序列52001 - 52013是另一个组合数据块呢?
它并不知道。从TCP的角度来看,这只是一个没有任何内部结构的字节流。任何结构(比如一个“消息”)都需要由应用程序协议添加。
换句话说,你不能期望发送端的单次写入/发送会在接收端产生单次读取/接收。
英文:
> How does TCP know seq 1 - 52001 is a combined data block and seq 52001 - 52013 is another combined data block?
It doesn't. From the perspective of TCP this is only a byte stream without any internal structure. Any structure (like a "message") needs to be added by the application protocol.
Or in other words: you cannot expect that a single write/send in the sender will result in a single read/recv in the recpient.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论