簡體   English   中英

unistd write()在連續100次套接字讀/寫后停止寫,程序返回3328錯誤代碼

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM