2017-07-26 71 views
0

我试图测试我的网站可以处理的流量,因此我创建了一个C程序来发送一堆连续的请求到我的网站(可能不是最好的方式,但我这样做只是因为我不知道C,不是因为我真的需要测试负载处理)。下面是相关的代码(如果你真的觉得你需要完整的源代码,请参阅here):unistd write()在连续100次套接字写入/读取后停止写入,程序返回3328错误代码

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

其中socket_id是既定的插座连接的ID,request是HTTP请求发送,并messageread的结果将被存储。这是HTTP GET请求:

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

我通过php脚本在我的网站上跟踪视图。

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

+0

你读过[this](https://en.wikipedia.org/wiki/HTTP_persistent_connection)吗? – jeff6times7

+1

'write'和'read'返回的值是什么,如果失败,errno的值是多少? (提示:使用'perror()'函数) – purplepsycho

+0

@ jeff6times7 HTTP 1.1(我正在使用的)默认是持久的。你建议使用还是不使用持久性? –

回答

0

服务器可能会关闭一个连接,因此您必须测试来自写入和读取函数的返回代码,并且如果出现故障,请重新建立连接。

+0

返回值总是有效的(从不是'-1'),所以这不是问题。 –

+1

@MuhammadYojer:'0'怎么样? – alk

3

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

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

正确的方法是,以声明该变量作为外部在包含文件:extern struct sockaddr_in servaddr;,只有限定它在一个单独的C文件。在你当前的源代码中,你甚至可以只在connector.c文件中声明它。

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

+0

我检查了返回值,它们总是有效的(从不'-1)。另外,我将'servaddr'从'connector.h'移动到'connector.c',并声明它是静态的,但是没有任何改变;在写入100个请求后,写入操作仍然停止。你可以看到更新的源代码[这里](https://github.com/MuhammadYojer/simple-load-tester)。 –

+1

@MuhammadYojer:不,您不检查** all **的读取和写入的返回值,但仅检查每秒,并从对等关闭的套接字读取将返回0.为什么不使用常见的'cr =读(...); if(cr <= 0){...}'? –

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); 
} 
相关问题