UNIX网络编程7 利用tdpdump理解socket相关函数和数据包的时序

本次测试的主要原因是不了解connect() accept()和三次握手的先后顺序。为了能够方便获得时序关系,在程序关键点都插入了printTimeLog()打印出时间戳和日志信息,并且在服务端listen()和accept()之间插入长时间的sleep(),在客户端connect()和send()之间也插入一定时间的sleep(),然后一次启动tcpdump和server以及client,根据程序输出的时序日志和tcpdump抓到的包的时间戳,就可以很清楚的了解socket相关函数和TCP数据包的时序关系。

结论是:
服务端listen()调用之后,就已经出于等待连接的状态,即便不调用accept(),客户端connent()后会立即返回(此时已经完成了三次握手,没必要等到服务端accept()),然后客户端还可以立即发送数据(seq和ack都正常,没必要等到服务端accept())。服务端accept()和三次握手甚至和后续的收发数据都没有关系,它的作用仅仅是返回连接好的客户端socketfd,然后服务端才能从这个fd中读取收到的数据

服务端、客户端的流程、时序和tcpdump数据包时序之间的关系图(徒手画的,方便):
UNIX网络编程7 利用tdpdump理解socket相关函数和数据包的时序_第1张图片

时序日志输出函数如下,该函数只能精确到秒:
      14 void printTimeLog(const char * message)
-     15 {
|     16     time_t now;
|     17     struct tm *tm_now;
|     18     time(&now);
|     19     tm_now = localtime(&now);
|     20     printf("%d:%d:%d\t%s\n", tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec, message);
|     21 } 

附程序输出的时序日志和tcpdump抓到的包:
[ec2-user@ip-172-31-11-211 cplus]$ ./server
23:9:55     After listen..
23:9:55     Sleep 10 secs before accept
23:10:5     Accept returned.
accept client 127.0.0.1: 49885   //accept一个连接后交给fork出的子进程处理
23:10:5     Sleep 10 secs before accept  //这里是父进程
23:10:5     Receive message    //子进程recv消息
Receive message size: 131072  //recv返回的消息字节数


[ec2-user@ip-172-31-11-211 cplus]$ ./client
23:9:57     Connected! Sleep 5secs before sending message  //客户端调用connect()后
23:10:2     Sending message.   // send()前
23:10:2     Send end.  //send()后

send len: 131072

tcpdump数据
[ec2-user@ip-172-31-11-211 cplus]$ sudo tcpdump -i lo "port 8888"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes

三次握手:
23: 09:57.310212 IP localhost.56770 > localhost.ddi-tcp-1: Flags [S], seq 604166018, win 65495, options [mss 65495,sackOK,TS val 7610958 ecr 0,nop,wscale 6], length 0
23:09:57.310223 IP localhost.ddi-tcp-1 > localhost.56770: Flags [S.], seq 483585084, ack 604166019, win 65483, options [mss 65495,sackOK,TS val 7610958 ecr 7610958,nop,wscale 6], length 0
23: 09:57.310232 IP localhost.56770 > localhost.ddi-tcp-1: Flags [.], ack 1, win 1024, options [nop,nop,TS val 7610958 ecr 7610958], length 0

23: 10:02.310867 IP localhost.56770 > localhost.ddi-tcp-1: Flags [.], seq 1:32742, ack 1, win 1024, options [nop,nop,TS val 7615959 ecr 7610958], length 32741
23:10:02.310878 IP localhost.ddi-tcp-1 > localhost.56770: Flags [.], ack 32742, win 1658, options [nop,nop,TS val 7615959 ecr 7615959], length 0

23:10:02.310907 IP localhost.56770 > localhost.ddi-tcp-1: Flags [P.], seq 32742:65483, ack 1, win 1024, options [nop,nop,TS val 7615959 ecr 7610958], length 32741
23:10:02.310956 IP localhost.56770 > localhost.ddi-tcp-1: Flags [.], seq 65483:98224, ack 1, win 1024, options [nop,nop,TS val 7615959 ecr 7615959], length 32741
23:10:02.310963 IP localhost.56770 > localhost.ddi-tcp-1: Flags [P.], seq 98224:130965, ack 1, win 1024, options [nop,nop,TS val 7615959 ecr 7615959], length 32741
23:10:02.350410 IP localhost.ddi-tcp-1 > localhost.56770: Flags [.], ack 130965, win 124, options [nop,nop,TS val 7615999 ecr 7615959], length 0

23:10:02.350461 IP localhost.56770 > localhost.ddi-tcp-1: Flags [P.], seq 130965:131073, ack 1, win 1024, options [nop,nop,TS val 7615999 ecr 7615999], length 108
23: 10:02.390461 IP localhost.ddi-tcp-1 > localhost.56770: Flags [.], ack 131073, win 123, options [nop,nop,TS val 7616039 ecr 7615999], length 0

23:10:05.596584 IP localhost.ddi-tcp-1 > localhost.56770: Flags [.], ack 131073, win 2047, options [nop,nop,TS val 7619245 ecr 7615999], length 0

四次挥手,合并成了3个包
23:10:23.503458 IP localhost.56770 > localhost.ddi-tcp-1: Flags [F.], seq 131073, ack 1, win 1024, options [nop,nop,TS val 7637152 ecr 7619245], length 0
23:10:23.503543 IP localhost.ddi-tcp-1 > localhost.56770: Flags [F.], seq 1, ack 131074, win 2047, options [nop,nop,TS val 7637152 ecr 7637152], length 0
23:10:23.503556 IP localhost.56770 > localhost.ddi-tcp-1: Flags [.], ack 2, win 1024, options [nop,nop,TS val 7637152 ecr 7637152], length 0

你可能感兴趣的:(socket,网络编程,connect,accept,返回时间)