我已经为C中的HTTP服务器编写了一些代码。它适用于少量客户端(可能在100-500ish范围内),但当被要求面对大量并发用户时,它会耗尽记忆。我想知道为什么会这样。
这是从客户端读取数据然后返回响应的代码。顺便说一句,客户端和服务器套接字是非阻塞的:
int handle_client(char *root, int c) {
int size = sizeof(char) * BUFSIZ + 1, len = strlen(SEND_HTTP_NOT_FOUND);
char *buffer = malloc(size), *data = NULL, not_found_error[200] = SEND_HTTP_NOT_FOUND, internal_error[200] = SEND_HTTP_INTERNAL_SERVER_ERROR;
if (!buffer) {
log_error(errno);
return -1;
}
bzero(buffer, size);
while (1) {
if (read(c, buffer, size) <= 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
log_error(errno);
free(buffer);
if (c) close(c);
return -1;
} else {
int not_found = 0;
data = parse_content(root, buffer, not_found);
if (!data) {
if (not_found) {
if (write(c, not_found_error, len) <= 0)
log_error(errno);
} else {
if (write(c, internal_error, len) <= 0)
log_error(errno);
}
free(buffer);
if (c) close(c);
return -1;
}
break;
}
}
}
if (write(c, data, strlen(data)) <= 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
log_error(errno);
close(c);
free(data);
free(buffer);
return -1;
}
}
close(c);
free(data);
free(buffer);
return 0;
}
为了测试此代码,我使用了siege
:
siege --file=try_me.txt -c 1000 -v
try_me.txt
2个请求索引页面的URL和一个名为test.txt
的文件。经过一段时间用1000个并发用户轰炸它后,会发生这种情况:
siege
输出:
HTTP/1.1 200 0.14 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.14 secs: 158 bytes ==> GET /test.txt
HTTP/1.1 200 0.14 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.14 secs: 158 bytes ==> GET /test.txt
HTTP/1.1 200 0.13 secs: 158 bytes ==> GET /test.txt
HTTP/1.1 200 0.13 secs: 158 bytes ==> GET /test.txt
HTTP/1.1 200 0.13 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.13 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.13 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.13 secs: 158 bytes ==> GET /test.txt
HTTP/1.1 200 0.13 secs: 158 bytes ==> GET /test.txt
HTTP/1.1 200 0.14 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.13 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.13 secs: 158 bytes ==> GET /test.txt
HTTP/1.1 200 0.13 secs: 158 bytes ==> GET /test.txt
HTTP/1.1 200 0.13 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.13 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.13 secs: 158 bytes ==> GET /test.txt
HTTP/1.1 200 0.13 secs: 225 bytes ==> GET /
HTTP/1.1 200 0.14 secs: 225 bytes ==> GET /
HTTP/1.1 500 0.14 secs: 41 bytes ==> GET /
HTTP/1.1 500 0.14 secs: 41 bytes ==> GET /
HTTP/1.1 500 0.14 secs: 41 bytes ==> GET /
HTTP/1.1 500 0.13 secs: 41 bytes ==> GET /
HTTP/1.1 500 0.13 secs: 41 bytes ==> GET /
HTTP/1.1 500 0.13 secs: 41 bytes ==> GET /
HTTP/1.1 500 0.13 secs: 41 bytes ==> GET /
HTTP/1.1 500 1.13 secs: 41 bytes ==> GET /test.txt
HTTP/1.1 500 0.13 secs: 41 bytes ==> GET /test.txt
HTTP/1.1 500 0.13 secs: 41 bytes ==> GET /
HTTP/1.1 500 0.13 secs: 41 bytes ==> GET /
HTTP/1.1 500 1.12 secs: 41 bytes ==> GET /test.txt
HTTP/1.1 500 0.12 secs: 41 bytes ==> GET /test.txt
HTTP/1.1 500 0.13 secs: 41 bytes ==> GET /
HTTP/1.1 500 0.14 secs: 41 bytes ==> GET /test.txt
我的节目输出:
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
[ERROR] tcp_server.h:140 (function handle_client): Cannot allocate memory (error code: 12)
我的3个问题是:
感谢您的帮助。请随时询问澄清或信息。
答案 0 :(得分:0)
好的,所以我设法确定问题发生的位置。每个人的建议和评论都帮助我改进了我的代码,并进一步帮助解决了问题,所以我感谢你。 这个问题在我写的另一个函数中排成一行,我在其中分配了一个长{{1}}的数组!这显然不是很节省内存。
所以,再一次,我想感谢您的意见和建议!