0

我正在尝试测试我的网站可以处理的流量,因此我创建了一个 C 程序来向我的网站发送一堆连续的请求(可能不是最好的方法,但我这样做只是因为我真的不知道C,不是因为我真的需要测试负载处理)。以下是相关代码(如果您真的觉得需要完整源代码,请参见此处):

while(1) {
        sleep(1);
        write(socket_id, request, strlen(request));
        read(socket_id, message, 1024 * 1024);
}

其中socket_id是已建立的套接字连接的 id,request是要发送的 HTTP 请求,以及将存储message结果的位置。read这是 HTTP GET 请求:

GET / HTTP/1.1
Host: website.com
From: ...

我正在通过我网站中的 php 脚本跟踪浏览量。

无论线程多长时间sleep,它在 100 次写入/读取后仍然崩溃。为什么是这样?

4

3 回答 3

3

您的代码很糟糕,因为您从不测试 read 和 write 的返回值,因此您仍然可以在服务器端关闭套接字后尝试访问套接字,但这不会导致崩溃。

但是在查看了您的 github 代码后,我注意到您在 .h 文件中定义 struct sockaddr_in servaddr;了该文件,该文件包含在 2 个不同的 c 文件中。确实有些编译器可以允许它,但它不符合 C,因为它不遵守单一定义规则。事实上,您在一个程序中定义了两次相同的变量,导致未定义的行为。

正确的方法是在包含文件中将变量声明为外部变量:extern struct sockaddr_in servaddr;,并且只在一个单独的 c 文件中定义它。在您当前的源代码中,您甚至只能在 connector.c 文件中声明它。

但总的来说,全局变量是一场噩梦,因为它们可能会在意想不到的时间从意想不到的地方被更改,并导致使用错误的值。至少servaddr应该在 connector.c 中声明为静态的。

于 2017-07-26T08:38:49.633 回答
0

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);
}
于 2017-07-27T08:36:02.063 回答
0

服务器可能会关闭连接,因此您必须测试写入和读取函数的返回码,如果失败,则重新建立连接。

于 2017-07-26T07:02:42.963 回答