对于web服务器,要尽量的减小服务器的负担。如果,浏览器已经取消请求连接,web服务器就不应该再向浏览器发送页面的数据了。我本次是测试web服务器是如何知道浏览器已经取消了请求哪?
如果浏览器取消请求,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信号?
我没有找到合适答案,希望有人提供答案的。