您的位置:首页 > 理论基础 > 计算机网络

UNIX网络编程学习(11)--分析TCP回射服务+客户程序:正常启动与正常终止

2012-03-26 10:26 387 查看
分析TCP回射服务+客户程序:

启动服务器程序后,netstat -a,后终端出现:

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address           Foreign Address         State     

tcp        0      0 *:9877                  *:*                     LISTEN    

其中本地端口为9877正是我们启动的服务器应用

启动我们的客户/服务器程序对,

通过三次握手,连接建立。接着发生的步骤:

1.客户端调用str_cli 函数,该函数将阻塞于fgets调用。因为我们还没键入一行文本

2.当服务器中的accept返回时,服务器调用fork,再由子进程调用str_echo。str_echo调用readline,readline调用read,

read在等待客户送入一行文本期间阻塞

3.另一方面,服务器父进程再次调用accept并阻塞,等待下一个客户连接

终端netstat -a后,终端显示:

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address           Foreign Address         State     

tcp        0      0 *:9877                  *:*                     LISTEN    

tcp        0      0 localhost.localdoma:ipp *:*                     LISTEN    

tcp        0      0 *:daytime               *:*                     LISTEN    

tcp        0      0 localhost.localdo:55817 localhost.localdom:9877 ESTABLISHED

tcp        0      0 localhost.localdom:9877 localhost.localdo:55817 ESTABLISHED

tcp6       0      0 ubuntu:ipp              [::]:*                  LISTEN    

udp        0      0 *:52444                 *:*    

 第二个ESTABLISHED的本地端口号为9877,可判断出其对应服务器子进程的套接口;第一个ESTABLISHED的本地端口号是55817,

可判断出其对应客户进程的套接口。

         
zhouzhou@ubuntu:~/Desktop$ ps -a -o pid,ppid,stat,args,wchan

  PID  PPID STAT COMMAND                     WCHAN

 8780  8779 S+   sh -c LD_LIBRARY_PATH=$LD_L wait

 8781  8780 S+   /home/fupeng/Desktop/codebl inet_csk_wait_for_connect

 8993  8992 S+   sh -c LD_LIBRARY_PATH=$LD_L wait

 8994  8993 S+   /home/fupeng/Desktop/codebl n_tty_read

 8995  8781 S+   /home/fupeng/Desktop/codebl sk_wait_data

 9194  4449 R+   ps -a -o pid,ppid,stat,args -

简略:

  PID  PPID STAT COMMAND                     WCHAN

 

 8781  8780 S+   /home/fupeng/Desktop/codebl inet_csk_wait_for_connect   判断为父进程

 

 8994  8993 S+   /home/fupeng/Desktop/codebl n_tty_read                  判断为客户程序

 8995  8781 S+   /home/fupeng/Desktop/codebl sk_wait_data   判断为子进程

服务器和客户程序都启动时:

zhouzhou@ubuntu:~/Desktop$ netstat -a | grep 9877

tcp        0      0 *:9877                  *:*                     LISTEN    

tcp        0      0 localhost.localdom:9877 localhost.localdo:54491 ESTABLISHED

tcp        0      0 localhost.localdo:54491 localhost.localdom:9877 ESTABLISHED

客户端(ctrl+d结束后,),会经历如下:客户端会经历一个TIME_WAIT  状态。

zhouzhou@ubuntu:~/Desktop$ netstat -a | grep 9877

tcp        0      0 *:9877                  *:*                     LISTEN    

tcp        0      0 localhost.localdo:54491 localhost.localdom:9877 TIME_WAIT 

zhouzhou@ubuntu:~/Desktop$ netstat -a | grep 9877

tcp        0      0 *:9877                  *:*                     LISTEN

当前连接的客户端(本地端口号)进入了TIME_WAIT状态,而监听服务器仍在等待另一个客户连接。

正常终止客户和服务器的步骤:

1.当我们键入<Ctr-D>EOF字符时,fgets返回一个空指针,str_cli函数返回。

2.当str_cli返回到客户的main函数时,main通过exit终止。

3.进程终止时的一部分操作是关闭所有打开的描述字,客户打开的描述字由内核关闭。这导致客户tcp发送一个FIN给服务器,服务器TCP则以ACK响应,这是TCP连接终止的前半部操作。至此,服务器接口处于CLOSE_WAIT状态,客户套接口处于FIN_WAIT_2状态。

4.当服务器TCP接受FIN时,服务器子进程阻塞于readline调用,于是readline返回0.这导致str_echo函数返回服务器子进程的main函数

5.服务器子进程通过调用exit来终止。

6.服务器子进程打开的所有描述字随之关闭。由子进程关闭已连接套接口引发TCP连接终止序列最后两个分节:一个是从服务器到客户的FIN;另一个是从客户到服务器的ACK。至此,连接完全终止,客户套接口进入TIME_WAIT状态

7.进程终止处理的另一部分内容是:在服务器子进程终止时,会给父进程发送一个SIGCHLD信号。该信号的缺省行为被忽略。

这时,我们查看进程,子进程进入僵尸状态。

zhouzhou@ubuntu:~/Desktop$ ps -a -o pid,ppid,stat,args,wchan

  PID  PPID STAT COMMAND                     WCHAN

 8780  8779 S+   sh -c LD_LIBRARY_PATH=$LD_L wait

 8781  8780 S+   /home/fupeng/Desktop/codebl inet_csk_wait_for_connect

 8995  8781 Z+   [unp2] <defunct>            exit

 9355  8781 Z+   [unp2] <defunct>            exit

 9581  4449 R+   ps -a -o pid,ppid,stat,args -

后续,我们将学习去清理僵死进程。

 

 

 

 

 

 

 

 

 

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐