------------------------1 建立连接 ------------------------
终端输入命令: ./tcpserv & ,使服务器端程序后台执行
在同一个终端输入 ./tcpcli 127.0.0.1 命令执行客户端程序
通过命令:netstat –a | grep 9877 查看相关套接字状态,其中“*”表示地址通配符,服务器众所周知的端口号设定为9877。
State 状态含义:
LISTEN 监听状态,即服务器端一个套接字处于监听状态,具有通配本地IP地址,本地端口为9877,
下述6列的含义依次为:
Proto Recv-Q Send-Q Local Address ForeignAddress State
------------------------2 终止连接 ------------------------
当客户端终止连接时(Ctrl + D),则 netstat –a | grep 9877 查看客户进入TIME_WAIT状态,而服务器监听套接字仍处于LISTEN状态,即等待另一个客户连接。
客户调用socket和connect,后者引起TCP的三路握手过程,当三路握手过程完成后,客户中connect和服务器中accept均返回,连接建立。此时会有三个睡眠(已阻塞的进程):
客户进程—fgets调用,因为未输入过任何文本,条件为sk_wait_data
服务器父进程—再次调用accept并阻塞,等待下一个客户连接,即inet_csk_wait_for_connect
服务器子进程—子进程read等待客户输入一行文本期间阻塞,n_tty_read
Ctrl+D结束客户进程后,查看进程状态和条件如下图所示,与上图对比,可以发现PID-6807 的客户进程已经不存在了,而PID-6808负责与其通信的服务器端子进程状态为Z,WCHAN条件说明为exit,即已终止。
在客户服务器连接的进程终止后,一部分工作为主动关闭,即四分组交换序列终止连接的过程;另一部分工作为服务器子进程终止时,给父进程发送一个SIGCHLD信号,但程序1中父进程并没有处理,这就导致子进程状态为Z,即僵死状态(S表示为等待某些资源而睡眠);对于进入僵死状态的进程,必须通过POSIX信号处理进行清理。