读UNP一书所作的小试验(1)

    近期开始认真阅读Richard Stevens 的经典著作《Unix  Networking Programming :volume 1》3rd。大牛的作品没说的,无论是技术还是文字都是精炼准确的典范。

     书中的某些论述和自己平时的认识有较大出入,所以还是以书中提供的代码为基础,作了些简单的实验来印证书中的观点吧。

    “5.12——服务器进程终止"

    第5章的内容是给予一个简单的并发式C/S模型:client调用connect成功连接服务器后,server进程执行fork,创建子进程为该client提供服务。

    本小节所讨论的问题是:在client成功connnect后,若kill掉server端对应的子进程,将会发生什么。

    按照书中描述,并经试验抓包证明,步骤如下:

    1.server端子进程终止,子进程所打开的socket要被关闭,这导致其向client发送FIN。

    2.SIGCHLD信号被发送至server父进程,由其正确处理。

    3.client端收到FIN后,响应一个ACK,这样就完成了TCP连接终止的前一半工作。
       此时运行netstat -an命令,可以观察到client端socket状态为CLOSE_WAIT,server子进程的socket状态为FIN_WAIT2。将观察结果 与书中图2-5相对照,可看出这是与图2.5相一致的。(注意在图2-5中主动断开的是client,而实验中主动断开的是server).

    4.如果现在client端向socket写数据,会有什么结果?这一操作是允许的,抓包证明,所写数据依然通过这个状态为CLOES_WAIT的socket发送出来。

    5.服务器接收到客户的数据后,由于先前打开socket的进程已终止,所以向客户响应一个RST。

    6.客户进程接收到RST后,连接彻底关闭。

    7.若此时client对socket进行读操作,都会发生错误,并将错误码(ECONNRESET)写入全局变量errno;

    8.若此时client对socket进行写操作,内核向该进程发送SIGPIPE信号,该信号的默认处理是终止进程。
   

实验的基础是书中提供的源代码 tcpserv04.c 和tcpcli01.c,并对tcpcli01.c作了如下改动(红色部分为添加的代码,"//"的是被删除的代码)

void stc_cli(FILE *fp ,int sockfd)
{
       .............................

      
while  ( Fgets (sendline ,  MAXLINE ,  fp)  !=   NULL )
    {

        Writen(sockfd
,  sendline ,   strlen (sendline));

        
sleep(1 );   //延时,以确保收到RST

        
if  (Readline(sockfd ,  recvline ,  MAXLINE)  ==   0 )
        {
        
//     err_quit("str_cli: server terminated prematurely");

                Readline(sockfd
,  recvline ,  MAXLINE);

               
if(errno=ECONNRESET)
                    printf("read error:connect reset by peer "
);

                Writen(sockfd
,  sendline ,   strlen (sendline));
             
//     return ;
        }

        
Fputs (recvline ,  stdout);
    }

}

void sig_pipe (int signo)
{
        printf("you have written to a socket who has received RST.Forbidden !/n");
        exit(1);
}


int  main(int argc, char **argv)
{

    .......................

    Signal(SIGPIPE,sig_pipe);

    Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
   

    str_cli(stdin, sockfd);        /* do it all */

    exit(0);
}

   

   





   
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值