c# windowsservice 启动 tcp监听_TCP回射服务器正常启动关闭

正常启动

我们一起来学习使用netstat调试网络程序。

启动服务器程序:./tcpserv01 &&表示后台启动)

服务器程序启动后,调用socket bind listen 和 accept,并阻塞于accept 调用。运行netstat程序来检查服务器监听套接字的状态,如下:LISTEN。有没有注意到-a选项可以查看所有监听套接字。我们的监听端口是9877,监听地址是通配地址0。

644d386ac8df91aa0597d40d1a1be973.png

启动客户程序:./tcpcli01 我修改了代码中IP地址为环回地址(127.0.0.1

客户端调用socketconnect,引起TCP三次握手,这是服务器的accept 开始忙活了,当三次握手完成,客户端的connect 和服务端的accept 均返回,连接建立。

  1. 客户端:调用str_cli函数,该函数阻塞于fgets 调用。
  2. 服务端:调用fork,由子进程调用str_echo函数,该函数阻塞于read 调用。
  3. 服务端:父进程再次阻塞于accept 函数并阻塞,等待下一个客户连接。

提示:客户端connect 在接收到三次握手的第二个握手报文返回,服务端accept 在接收到三次握手的第三个握手报文返回。

可以看出我们的子进程和客户端建立了TCP连接,服务端端口是9877,客户端端口是42120。

c482bd386d6fdbfb7e66822a55b42810.png

通过ps 来看看进程间的关系:ps -t pts/0 -o pid,ppid,tty,stat,args,wchan

提示:我在这里重启了客户端和服务端的程序,所以进程ID、端口可能会发生变化。

  • pts/0:0号伪终端,服务端跑的终端
  • pts/1:1号伪终端,客户端跑的终端

注意:STAT列的S表示进程在为等待某些资源而睡眠,有+号表示光标在该进程,可以输入数据。 当进程阻塞于acceptconnect时,输出inet_csk_accept。当进程阻塞于套接字输入或输出时,输出sk_wait_data。当进程阻塞于终端IO时,输出wait_woken

8a785199fa097007b7d07c877e8aacb7.png

正常关闭

提示:在分析正常关闭网络程序的时候,我们再次重启了程序,而这是不必要的,如果你时间充裕,能一次性把这些东西都研究懂,当下是正常启动后。

f2d54f50ec53e046ddf4859f43707220.png

现在们试图关闭客户端连接,我们输入EOF(Control+D)结束客户端连接,再看看连接状态,发现刚刚连接着的服务端没了,客户端状态变成TIME_WAIT,监听服务器不变,依然在等待。

0760f404f56940edcefaac9d22a8a655.png
  1. 当输入EOF字符,fgets 返回一个空指针,于是str_cli 返回。
  2. str_cli 返回到客户端的main 函数时,调用exit 结束进程。
  3. 结束进程会做很多事,其中包括关闭所有打开的描述符。所以,客户打开的套接字描述符由内核关闭,这将触发客户TCP发一个FIN报文给服务端,服务端收到FIN报文将回送一个ACK报文。此时,服务器套接字处于CLOSE_WAIT状态,客户套接字处于FIN_WAIT_2状态。
  4. 当服务端TCP上层接收到FIN报文时,处于阻塞状态的readline 函数返回0,str_echo返回。
  5. str_echo 返回到服务端的main 函数时,调用exit 结束进程。
  6. 服务端子进程中打开的所有描述符随即关闭,关闭服务端套接字将会触发TCP四次挥手的最后2个阶段,服务端内核将发送一个FIN报文给客户端,客户端收到FIN报文,发送一个ACK报文。至此,连接完全终止,客户套接字进入TIME_WAIT 状态。(上图)
  7. 服务端还需要注意一点,进程结束还需要做一件事:服务端子进程结束时,给父进程发送一个SIGCHLD 信号,由于我们没有在代码里捕获这个信号,并且这个信号的默认行为是被忽略。所以,就是下图我们看到的,父进程没有处理,子进程变成僵尸进程。

ab507721bb0bf653f0915e134df3a4ad.png

我们在运行一个客户端,然后发送EOF 字符,再次观察,如下图所示,我们发现又多了一个僵尸进程。(Z 表示僵尸进程)

bbbd1f5148fd8d142cc898712a17a46a.png

接下来,咱们一起学习一下如何徒手打僵尸,很简单擒贼先擒王,手动kill 掉僵尸的爸爸。

cc80737573fefa95e7c00f4cf7f84b80.png

参考文献:《UNIX网络编程 卷1:套接字联网API》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值