[英]unistd write() stops writing after 100 consecutive socket write/reads, program returns 3328 error code
我試圖測試我的網站可以處理的流量,因此我創建了一個C程序來向我的網站發送一堆連續的請求(可能不是最好的方法,但是我這樣做是因為我真的不知道C,不是因為我真的需要測試負載處理)。 這是相關的代碼(如果您確實感覺需要完整的源代碼,請參見此處 ):
while(1) {
sleep(1);
write(socket_id, request, strlen(request));
read(socket_id, message, 1024 * 1024);
}
其中socket_id
是已建立的套接字連接的ID, request
是要發送的HTTP請求,以及將存儲read
結果的message
。 這是HTTP GET請求:
GET / HTTP/1.1
Host: website.com
From: ...
我正在通過我網站上的php腳本跟蹤視圖。
無論線程sleep
多長時間,在進行100次寫入/讀取后,它仍然會崩潰。 為什么是這樣?
您的代碼很糟糕,因為您從不測試讀寫的返回值,因此在關閉服務器端后仍可以嘗試訪問套接字,但這不會導致崩潰。
但是在查看了您的github代碼之后,我注意到您定義了 struct sockaddr_in servaddr;
在.h文件中,該文件包含在2個不同的c文件中。 確實有些編譯器可以允許它,但是它不符合C,因為它不遵守單一定義規則。 實際上,您在一個程序中定義了兩次相同的變量,從而導致未定義的行為。
正確的方法是在包含文件中將變量聲明為外部變量: extern struct sockaddr_in servaddr;
,並且只能在一個c文件中進行定義 。 在當前源中,您甚至只能在connector.c文件中聲明它。
但是總的來說,全局變量是一個噩夢,因為它們可能會在意外的時間從意外的地方更改,並導致使用錯誤的值。 至少servaddr
應該在connector.c中聲明為靜態。
服務器可能會關閉連接,因此您必須測試寫入和讀取功能的返回碼,如果出現故障,請重新建立連接。
每次read
/ write
調用都應經過測試,並應在發生錯誤時重新建立連接:
在文件main.c
,而不是
//set up the connection
socket_id = get_socket();
get_ip_address("example.com");
establish_connection(socket_id);
/*...*/
//send the request
while(1) {
if(write(socket_id, request, strlen(request)) == -1 || read(socket_id, message, 1024 * 1024) == -1) {
establish_connection(socket_id);
write(socket_id, request, strlen(request));
read(socket_id, message, 1024 * 1024);
}else {
write(socket_id, request, strlen(request));
read(socket_id, message, 1024 * 1024);
}
}
您應該編寫如下內容:
/* query should be declared before this point */
while (1)
{
/* set up the connection */
socket_id = get_socket();
get_ip_address("example.com");
establish_connection(socket_id);
/* send the request */
while (1)
{
if (write(socket_id, request, strlen(request))<=0)
{
/* something goes wrong while writing, exit the inner while loop */
perror("write");
break;
}
if (read(socket_id, message, 1024 * 1024)<=0)
{
/* something goes wrong while reading, exit the inner while loop */
perror("read");
break;
}
}
/* if this point is reach, that means that one write or read call goes wrong */
close(socket_id);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.