To understand what determines the initial value of tcp receive window, I run a simple test.
First, launch a dumb server which accepts connection but doesn't read any data from the connection.
Second, a client connect to the server and write chunks of data(8k per chunk).
// golang source code// can use 'nc -lk 8082', by ignore first connection to simulate the same situationpackage mainimport ("flag""log""net")func main() { listen := flag.String("listen", ":8081", "listen adddress") flag.Parse() ln, err := net.Listen("tcp", *listen) if err != nil { log.Printf("listen failed: %s", err) return } for { conn, err := ln.Accept() if err != nil { // handle error } go func(conn net.Conn) { // do nothing }(conn) }}
by tcpdump, I find the server receives data much more than the receive window negotiated during connection establish. Even reveive window increases can be observed.
tcpdump1(run server in ubuntu 16.04):
-- env$ cat /proc/sys/net/core/rmem_default212992$ cat /proc/sys/net/ipv4/tcp_rmem4096 87380 6291456
09:16:43.440365 IP u1804.48032 > 192.168.56.2.8082: Flags [S], seq 607790617, win 64240, options [mss 1460,sackOK,TS val 4153349898 ecr 0,nop,wscale 7], length 009:16:43.440574 IP 192.168.56.2.8082 > u1804.48032: Flags [S.], seq 1837853654, ack 607790618, win 28960, options [mss 1460,sackOK,TS val 772376 ecr 4153349898,nop,wscale 7], length 009:16:43.440601 IP u1804.48032 > 192.168.56.2.8082: Flags [.], ack 1, win 502, options [nop,nop,TS val 4153349898 ecr 772376], length 009:16:43.440698 IP u1804.48032 > 192.168.56.2.8082: Flags [.], seq 1:7241, ack 1, win 502, options [nop,nop,TS val 4153349898 ecr 772376], length 724009:16:43.440716 IP u1804.48032 > 192.168.56.2.8082: Flags [P.], seq 7241:8193, ack 1, win 502, options [nop,nop,TS val 4153349898 ecr 772376], length 95209:16:43.440874 IP 192.168.56.2.8082 > u1804.48032: Flags [.], ack 8193, win 355, options [nop,nop,TS val 772376 ecr 4153349898], length 009:16:44.441277 IP u1804.48032 > 192.168.56.2.8082: Flags [.], seq 8193:15433, ack 1, win 502, options [nop,nop,TS val 4153350899 ecr 772376], length 724009:16:44.441327 IP u1804.48032 > 192.168.56.2.8082: Flags [P.], seq 15433:16385, ack 1, win 502, options [nop,nop,TS val 4153350899 ecr 772376], length 952*1 09:16:44.441496 IP 192.168.56.2.8082 > u1804.48032: Flags [.], ack 16385, win 483, options [nop,nop,TS val 772626 ecr 4153350899], length 009:16:45.442320 IP u1804.48032 > 192.168.56.2.8082: Flags [.], seq 16385:23625, ack 1, win 502, options [nop,nop,TS val 4153351900 ecr 772626], length 724009:16:45.442378 IP u1804.48032 > 192.168.56.2.8082: Flags [P.], seq 23625:24577, ack 1, win 502, options [nop,nop,TS val 4153351900 ecr 772626], length 952*2 09:16:45.442658 IP 192.168.56.2.8082 > u1804.48032: Flags [.], ack 24577, win 611, options [nop,nop,TS val 772876 ecr 4153351900], length 009:16:46.447317 IP u1804.48032 > 192.168.56.2.8082: Flags [.], seq 24577:31817, ack 1, win 502, options [nop,nop,TS val 4153352905 ecr 772876], length 724009:16:46.447396 IP u1804.48032 > 192.168.56.2.8082: Flags [P.], seq 31817:32769, ack 1, win 502, options [nop,nop,TS val 4153352905 ecr 772876], length 95209:16:46.447660 IP 192.168.56.2.8082 > u1804.48032: Flags [.], ack 32769, win 739, options [nop,nop,TS val 773127 ecr 4153352905], length 009:16:47.448064 IP u1804.48032 > 192.168.56.2.8082: Flags [.], seq 32769:40009, ack 1, win 502, options [nop,nop,TS val 4153353905 ecr 773127], length 724009:16:47.448096 IP u1804.48032 > 192.168.56.2.8082: Flags [P.], seq 40009:40961, ack 1, win 502, options [nop,nop,TS val 4153353905 ecr 773127], length 95209:16:47.448247 IP 192.168.56.2.8082 > u1804.48032: Flags [.], ack 40961, win 867, options [nop,nop,TS val 773378 ecr 4153353905], length 009:16:48.448367 IP u1804.48032 > 192.168.56.2.8082: Flags [.], seq 40961:48201, ack 1, win 502, options [nop,nop,TS val 4153354906 ecr 773378], length 724009:16:48.448441 IP u1804.48032 > 192.168.56.2.8082: Flags [P.], seq 48201:49153, ack 1, win 502, options [nop,nop,TS val 4153354906 ecr 773378], length 952...09:17:14.620853 IP u1804.48032 > 192.168.56.2.8082: Flags [.], seq 253953:256849, ack 1, win 502, options [nop,nop,TS val 4153381078 ecr 779931], length 289609:17:14.621044 IP u1804.48032 > 192.168.56.2.8082: Flags [.], seq 256849:258817, ack 1, win 502, options [nop,nop,TS val 4153381078 ecr 779931], length 196809:17:14.659787 IP 192.168.56.2.8082 > u1804.48032: Flags [.], ack 258817, win 0, options [nop,nop,TS val 780181 ecr 4153381078], length 009:17:14.905816 IP u1804.48032 > 192.168.56.2.8082: Flags [.], ack 1, win 502, options [nop,nop,TS val 4153381363 ecr 780181], length 009:17:14.906092 IP 192.168.56.2.8082 > u1804.48032: Flags [.], ack 258817, win 0, options [nop,nop,TS val 780242 ecr 4153381078], length 0
the initial receive window is 28960, but at last receive 258817 bytes data. from *1 to *2, the receive window incress from 483*128=61824 to 611*128=78208.
tcpdump2(run server in ubuntu 18.04):
-- env$ cat /proc/sys/net/core/rmem_default212992$ cat /proc/sys/net/ipv4/tcp_rmem4096 131072 6291456
10:13:33.155121 IP 192.168.56.2.46744 > u1804.8082: Flags [S], seq 3313268285, win 29200, options [mss 1460,sackOK,TS val 1624801 ecr 0,nop,wscale 7], length 010:13:33.155156 IP u1804.8082 > 192.168.56.2.46744: Flags [S.], seq 2202909113, ack 3313268286, win 65160, options [mss 1460,sackOK,TS val 4156759577 ecr 1624801,nop,wscale 7], length 010:13:33.155282 IP 192.168.56.2.46744 > u1804.8082: Flags [.], ack 1, win 229, options [nop,nop,TS val 1624801 ecr 4156759577], length 010:13:33.155520 IP 192.168.56.2.46744 > u1804.8082: Flags [P.], seq 1:8193, ack 1, win 229, options [nop,nop,TS val 1624801 ecr 4156759577], length 819210:13:33.155534 IP u1804.8082 > 192.168.56.2.46744: Flags [.], ack 8193, win 466, options [nop,nop,TS val 4156759577 ecr 1624801], length 010:13:34.160972 IP 192.168.56.2.46744 > u1804.8082: Flags [P.], seq 8193:16385, ack 1, win 229, options [nop,nop,TS val 1625053 ecr 4156759577], length 819210:13:34.161031 IP u1804.8082 > 192.168.56.2.46744: Flags [.], ack 16385, win 421, options [nop,nop,TS val 4156760583 ecr 1625053], length 010:13:35.161874 IP 192.168.56.2.46744 > u1804.8082: Flags [P.], seq 16385:24577, ack 1, win 229, options [nop,nop,TS val 1625303 ecr 4156760583], length 819210:13:35.161906 IP u1804.8082 > 192.168.56.2.46744: Flags [.], ack 24577, win 376, options [nop,nop,TS val 4156761583 ecr 1625303], length 010:13:36.162625 IP 192.168.56.2.46744 > u1804.8082: Flags [P.], seq 24577:32769, ack 1, win 229, options [nop,nop,TS val 1625553 ecr 4156761583], length 819210:13:36.162668 IP u1804.8082 > 192.168.56.2.46744: Flags [.], ack 32769, win 330, options [nop,nop,TS val 4156762584 ecr 1625553], length 010:13:37.163096 IP 192.168.56.2.46744 > u1804.8082: Flags [P.], seq 32769:40961, ack 1, win 229, options [nop,nop,TS val 1625803 ecr 4156762584], length 819210:13:37.163151 IP u1804.8082 > 192.168.56.2.46744: Flags [.], ack 40961, win 285, options [nop,nop,TS val 4156763585 ecr 1625803], length 0...10:13:42.204138 IP u1804.8082 > 192.168.56.2.46744: Flags [.], ack 81921, win 58, options [nop,nop,TS val 4156768626 ecr 1627054,nop,nop,sack 1 {80969:81921}], length 010:13:43.166198 IP 192.168.56.2.46744 > u1804.8082: Flags [.], seq 81921:89345, ack 1, win 229, options [nop,nop,TS val 1627304 ecr 4156768626], length 742410:13:43.209677 IP u1804.8082 > 192.168.56.2.46744: Flags [.], ack 89345, win 0, options [nop,nop,TS val 4156769631 ecr 1627304], length 010:13:43.432659 IP 192.168.56.2.46744 > u1804.8082: Flags [.], ack 1, win 229, options [nop,nop,TS val 1627371 ecr 4156769631], length 010:13:43.432685 IP u1804.8082 > 192.168.56.2.46744: Flags [.], ack 89345, win 0, options [nop,nop,TS val 4156769854 ecr 1627304], length 010:13:43.880600 IP 192.168.56.2.46744 > u1804.8082: Flags [.], ack 1, win 229, options [nop,nop,TS val 1627483 ecr 4156769854], length 0
the initial receive window is 65160, but at last receive 89345bytes data.
how to explain tcp reveive window increases?