⟅UNIX网络编程⟆⦔TCP客户/服务器程序实例(二)

说在前面

目的

  • 通过本例来了解服务器和客户是如何启动、终止的,更重要的是了解在发生错误(例如客户主机崩溃、客户进程崩溃、网络连接断开)时将会发生啥。

正常启动

  • 启动服务器

    root@xxx:./server.out
    

    随后,服务器将调用socketbindlistenaccept,并且阻塞于accept。假设此时还未启动任何客户端。

  • 使用netstat命令
    注意:目前WSL不支持netstat命令,所以实验放到ubuntu上吧,详见issue

    打开另一个终端,并键入命令:

    netstat -a
    

    在这里插入图片描述
    可以看到结果中Local Address一列中端口号为9877的即为服务器程序。9877前面为 ∗ * ,表示通配地址。Foreign Address ∗ : ∗ *:* :,表示可接受任意地址和端口的外来连接。State一列为LISTEN,表示该套接字处于LISTEN状态。

  • 启动客户端
    这里我们选择在同一台主机上运行客户端程序。使用环回地址127.0.0.1。

    root@xxx:./client.out 127.0.0.1
    

    随后,客户端调用socketconnect,后者引起TCP三路握手。
    当三路握手完成后,服务器accept调用返回,客户端connect调用返回。此时,客户端进入str_cli函数(见上节),等待获取标准输入(fgets函数)。
    在这里插入图片描述
    服务器accept返回后,将调用fork产生子进程,子进程调用str_echo。在str_echo函数中,由于此时客户还未发送数据,将阻塞在读取(即read调用)。同时,父进程在fork返回后,再次调用accept,等待新的客户端连接。

  • 再次使用netstat命令

    netstat -a | grep 9877 # grep 9877表示抽取含有9877的项
    

    在这里插入图片描述
    可以看到有两个已连接的套接字,第一个的端口号为9877,即服务器子进程的套接字;第二个的端口号为44828,对应客户端的套接字。
    使用ps命令

    ps -t pts/* -o pid,ppid,tty,stat,args,wchan
    

    下面为 ∗ * 分别为2和18的输出,分别表示不同的终端号(我打开了俩终端,一个运行server,一个运行client)。WCHAN表示wait channel,表示当进程sleep 时,kernel 当前运行的函数。这里的值和书上的不同,可能有操作系统版本不同的原因。在这里插入图片描述在这里插入图片描述

  • 客户端标准输入
    在这里插入图片描述
    在我们输入“hello world!”后,屏幕上立即输出了另一行“hello world!”。
    该过程可以描述为:客户fgets获取标准输入→客户write发送数据→服务器read接收数据→服务器write回送数据→客户read接收数据→客户fputs标准输出。

正常终止

在这里插入图片描述

  • 客户端键入Ctrl+D,表示EOF字符
    客户:在输入EOF后,函数fgets返回空指针,str_cli返回;
    客户:str_cli返回后,进入main函数,调用exit终止进程;
    客户:进程终止时,会关闭该进程打开的所有描述符,因此客户套接字被关闭,客户TCP发送FIN给服务器;
    服务器:服务器响应ACK,并进入CLOSE_WAIT状态。
    客户:接收到ACK后,进入FIN_WAIT_2状态。
    服务器:服务器在接收FIN时,readline返回0,函数str_echo返回;并在main函数中调用exit终止进程。
    服务器:服务器关闭相应的套接字,发送FIN。
    客户:客户接收FIN后,返回ACK,进入TIME_WAIT状态。
    服务器:接收ACK后,连接彻底关闭。
    上述服务器指服务器子进程
    在这里插入图片描述

  • 使用netstat命令
    在这里插入图片描述
    可以看到,相关的套接字只有两个了,客户连接进入TIME_WAIT状态,服务器主进程(父进程)依然是LISTEN状态,服务器子进程关闭。

  • 使用ps命令
    在服务器子进程终止时,会给父进程发送一个SIGCHILD信号,在本节中并没有处理该信号。由于父进程没有处理该信号,子进程变成僵尸进程,使用ps命令可以看到defunct标志。
    在这里插入图片描述

处理僵尸进程

  • 见下一节
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值