自己动手写web服务器三(eb服务器是如何处理浏览器取消的请求的 )


        对于web服务器,要尽量的减小服务器的负担。如果,浏览器已经取消请求连接,web服务器就不应该再向浏览器发送页面的数据了。我本次是测试web服务器是如何知道浏览器已经取消了请求哪?

        如果浏览器取消请求,web服务器继续向浏览器发送请求,将会造成web服务器的崩溃。在高级语言中种称之为异常也叫做异常中断,但是在C语言中没有。可是,C语言中的信号量提供了类似异常的功能。但是很多书上对linux信号这一块将的都不是很相信,经过查资料发现,其中的SIGPIPE信号比较符合要求,经过测试发现当浏览器取消请求时,服务端可以通过捕获此信号来进行处理,避免服务器端崩溃。经过测试发现不是浏览器已取消请求。那是在什么时候服务器在可以接受到SIGPIPE信号?下面我们看下测试。

 

主要代码:本代码和结论只经过本人的简单测试,可能存在问题。请相信自己的能力,敢于质疑。欢迎提供更好的、更快、更简洁的代码或者方法和指出错误。在ubuntu12.04使用gcc4.6.3版本编译,在vc中如出现错误,请谅解。)

 

  1. res_socket = socket_listen( "127.0.0.1", 1024) ;  
  2.   
  3.    signal (SIGPIPE, test);//test函数只在屏幕中输出了 test close   
  4.     while(1){  
  5.         conn_socket = accept( res_socket, (struct sockaddr * )&client_addr, &len );  
  6.          tmp = read (conn_socket, buf, MAX-1);  
  7.         printf ("sleep\n");  
  8.         sleep (5);  
  9.         printf ("sleep end\n");  
  10.          sprintf (buf, "HTTP/1.0 %d %s\r\nServer: Reage Web Server\r\n", 200, "OK");  
  11.          sprintf (buf, "%sContent-Type: text/html\r\n\r\n", buf );  
  12.         printf ("1\n");  
  13.         write (conn_socket, buf, strlen (buf));  
  14.         printf ("2\n");  
  15.         strcpy (buf, "test html");  
  16.         write (conn_socket, buf, strlen (buf));  
  17.         printf ("3\n");  
  18.         close(conn_socket);  
  19. }  
res_socket = socket_listen( "127.0.0.1", 1024) ;

   signal (SIGPIPE, test);//test函数只在屏幕中输出了 test close
    while(1){
        conn_socket = accept( res_socket, (struct sockaddr * )&client_addr, &len );
         tmp = read (conn_socket, buf, MAX-1);
        printf ("sleep\n");
        sleep (5);
        printf ("sleep end\n");
         sprintf (buf, "HTTP/1.0 %d %s\r\nServer: Reage Web Server\r\n", 200, "OK");
         sprintf (buf, "%sContent-Type: text/html\r\n\r\n", buf );
        printf ("1\n");
        write (conn_socket, buf, strlen (buf));
        printf ("2\n");
        strcpy (buf, "test html");
        write (conn_socket, buf, strlen (buf));
        printf ("3\n");
        close(conn_socket);
}


结果图如下:

 

测试方法:首先运行本程序。然后再浏览器中输入 “http://localhost:1024”网址,然后请求网站。随后,按”ESC”键。这样取消浏览器请求,因为我在代码中在服务器接收请求后,等5s以后才处理请求,所以在处理请求的时候浏览器已经取消了请求,但是第一次发送数据的时候,web服务器没有收到SIGPIPE信号。(难道我错了吗?没有,稍后解释),但是当第二次向浏览器发送数据的时候,web服务器收到信号,也就大家在屏幕看到的2和3中间显示的”test close”。

相信大家看过后还会有一些问题的。一下我是我当时想不通,经过看书找到相关资料。仅供参考。一下答案是自己总结,有错误,请谅解,并指出。

 

1.       为什么浏览器取消请求的时候,web服务器收到的是SIGPIPE信号的?

SIGPIPE是在讲管道时候提起的,在《Unix环境高级编程》是这样说的”如果写一个读端已被关闭的管道,则会产生信号SIGPIPE,如果忽略该信号或者捕捉该信号并从器处理程序返回,则write返回-1,errno设置为EPIE”; 但是怎么在浏览器取消请求的时候,web服务器收到的使SIGPIPE,但是《Unix环境高级编程》是这样介绍管道:“管道是UNIX系统IPC的最古老形式,并且所有系统中都提供此种通信机制。“,然后说了 PIPE管道,FIFO管道、UNIX域套接字、命名流管道。所以说这些都是属于管道的。

 2.       为什么web服务器在第一次发送数据和浏览器关闭连接的时候没有收到SIGPIPE信号?

 我没有找到合适答案,希望有人提供答案的。

稍后功能整理到Reage Web Server 中。
 
 

转载于:https://my.oschina.net/rentiansheng/blog/94972

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值