上一篇,通过抓包,我们总结了两者在效率和可靠性上的差别.这一篇,我们将认识socket如何处理多个请求
1、代码
这里使用之前tcp服务的代码
1.1、运行流程
- 启动tcp服务
- 使用tcpdump进行抓包

- 使用telnet连接tcp服务

- 执行tcp客户端脚本

1.2、查看目前的执行结果
- tcp服务端

- tcpdump抓包结果1

1.3、分析抓包结果1
- 序号1-4的数据包,是telnet客户端与tcp服务端建立三次握手
- 序号5-8的数据包,是tcp客户端与tcp服务端建立的三次握手
- 序号9-10数据包,则是tcp客户端往服务端发送数据"hello world"
1.4、telnet的终端输入数据“iamasb”
- telnet终端输出结果

- tcp客户端输出结果

- tcp服务端输出结果

- tcpdump抓包结果2

1.5、分析抓包结果2
- 序号11-12,则是telnet客户端往服务端发送数据"iamasb"
- 序号13-14,则是服务端往telnet客户端发送数据"iamasb"
- 序号15、16、23、24,则是服务端与telnet客户端释放连接的四次握手
- 序号17、19,则是服务端往tcp客户端发送数据"hello world"
- 序号18、20、21、22则是服务端与tcp客户端释放连接的四次握手
备注: 由于是在shell终端发送数据需要按回车,因此telnet客户端在发送数据时,追加了两个字符
2、案例分析
整个案例,以telnet客户端是否输入数据为分界点
2.1、输入数据前
从抓包结果1的截图中,可以看出:
- telnet和tcp客户端都与服务端通过三次握手,建立好连接
- tcp客户端往服务端发送数据,而服务端也接收完毕。从这个环节可以看出socket存在"缓冲区",来临时存放客户端发来的数据。但无法马上进行处理,是因为"服务端"处于阻塞状态。
从输入数据前,服务端的输出结果来看:
- 服务端在socket_read调用处,阻塞。等待telnet客户端发送数据,导致无法处理其它请求
2.2、输入数据后
服务端在socket_read调用处,获取数据"iamasb"后,向telnet客户端发送数据,并释放此socket连接。开始下一个循环。
服务端调用socket_accept获取新的socket连接,再次执行read/write操作,并释放此socket连接。
3、总结
- socket_accept和socket_read在调用时会进行阻塞
- 再处理多个客户端请求时,只能串行处理。即一个接着一个进行
- 在socket_accept获取新的socket连接前,此socket连接已在内核中建立好
- socket存在缓存区