自己动手写web服务器三(web服务器是如何处理浏览器取消的请求的)
2012-12-10 18:22
489 查看
对于web服务器,要尽量的减小服务器的负担。如果,浏览器已经取消请求连接,web服务器就不应该再向浏览器发送页面的数据了。我本次是测试web服务器是如何知道浏览器已经取消了请求哪?
如果浏览器取消请求,web服务器继续向浏览器发送请求,将会造成web服务器的崩溃。在高级语言中种称之为异常也叫做异常中断,但是在C语言中没有。可是,C语言中的信号量提供了类似异常的功能。但是很多书上对linux信号这一块将的都不是很详细,经过查资料发现,其中的SIGPIPE信号比较符合要求,经过测试发现当浏览器取消请求时,服务端可以通过捕获此信号来进行处理,避免服务器端崩溃。经过测试发现不是浏览器已取消请求。那是在什么时候服务器在可以接受到SIGPIPE信号?下面我们看下测试。
主要代码:(本代码和结论只经过本人的简单测试,可能存在问题。请相信自己的能力,敢于质疑。欢迎提供更好的、更快、更简洁的代码或者方法和指出错误。在ubuntu12.04使用gcc4.6.3版本编译,在vc中如出现错误,请谅解。)
结果图如下:
测试方法:首先运行本程序。然后再浏览器中输入 “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信号?
我没有找到合适答案,希望有人提供答案的。
测试代码及辅助文件地址:http://pan.baidu.com/share/link?shareid=132643&uk=2181414688
稍后功能整理到Reage Web Server 中。
blog地址:http://blog.csdn.net/rentiansheng/article/details/8279389
如果浏览器取消请求,web服务器继续向浏览器发送请求,将会造成web服务器的崩溃。在高级语言中种称之为异常也叫做异常中断,但是在C语言中没有。可是,C语言中的信号量提供了类似异常的功能。但是很多书上对linux信号这一块将的都不是很详细,经过查资料发现,其中的SIGPIPE信号比较符合要求,经过测试发现当浏览器取消请求时,服务端可以通过捕获此信号来进行处理,避免服务器端崩溃。经过测试发现不是浏览器已取消请求。那是在什么时候服务器在可以接受到SIGPIPE信号?下面我们看下测试。
主要代码:(本代码和结论只经过本人的简单测试,可能存在问题。请相信自己的能力,敢于质疑。欢迎提供更好的、更快、更简洁的代码或者方法和指出错误。在ubuntu12.04使用gcc4.6.3版本编译,在vc中如出现错误,请谅解。)
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信号?
我没有找到合适答案,希望有人提供答案的。
测试代码及辅助文件地址:http://pan.baidu.com/share/link?shareid=132643&uk=2181414688
稍后功能整理到Reage Web Server 中。
blog地址:http://blog.csdn.net/rentiansheng/article/details/8279389
相关文章推荐
- 自己动手写web服务器二(处理get请求)
- 自己动手写web服务器四(web服务器是如何通过压缩数据,web服务器的gzip模块的实现)
- 自己动手写web服务器一(浏览器的访问信息)
- 自己动手写web服务器一(浏览器的访问信息) - 任天胜的个人空间 - 开源中国社区
- 自己动手写web服务器四(web服务器是如何通过压缩数据,web服务器的gzip模块的实现)
- 自己动手写web服务器(上),深入底层了解ASP.NET浏览器与服务器通信原理
- 自己动手写web服务器(下),深入底层了解ASP.NET浏览器与服务器通信原理
- 自己动手写web服务器(上),深入底层了解ASP.NET浏览器与服务器通信原理
- 自己动手写web服务器(下),深入底层了解ASP.NET浏览器与服务器通信原理
- 自己的web服务器项目-静态请求和动态请求处理(二)
- Web服务器如何保证请求的独立处理
- 自己的web服务器项目-request请求和response响应处理(一)
- 自己动手写web服务器一(浏览器的访问信息)
- 自己动手写web服务器四(web服务器是如何通过压缩数据,web服务器的gzip模块的实现)
- 高性能Web服务器Nginx的配置与部署研究(3)Nginx请求处理机制
- 处理【由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面】
- 连接的用户过多 导致此错误的原因是:Web 服务器忙,因通信量过大而无法处理您的请求。
- 自己动手,写个Web服务器(Java版)——第三篇
- [置顶] 自己动手安装turbogears -- 搭建基本Python web开发服务器环境
- 自己动手写的Web服务器<一>