I have to implement keep-alive attribute in http server on sockets in linux. Here is code of function that read, parse request and send response back.
static void *parse_request(void *ptr)
{
struct parse_arg *arg = (struct parse_arg *) ptr;
char buf[MAX_MSG];
ssize_t bytes_read;
char *msg;
char version[MAX_MSG];
int is_implemented = 0;
int result;
//Wait until the socket will be ready to read data
do {
fd_set readfds;
struct timeval tv = { };
tv.tv_sec = TIMEOUT_SECS;
FD_ZERO(&readfds);
FD_SET(arg->sock, &readfds);
result = select(arg->sock + 1, &readfds, NULL, NULL, &tv);
//read input data
if(result > 0) {
if(FD_ISSET(arg->sock, &readfds)) {
bytes_read =
read(arg->sock, buf, sizeof(char) * MAX_MSG);
if (bytes_read == -1) {
perror("Error when reading request");
return (void *)-1;
}
if (bytes_read == 0) {
fprintf(stderr,
"Client disconnected unexpectedly
");
close(arg->sock);
return (void *)-1;
}
msg = buf;
printf("REQUEST:%s", msg);
msg[bytes_read] = '';
//parse HTTP method, path to file, HTTP version
if (msg == strstr(msg, GET))
is_implemented = 1;
msg += strlen(GET) + 1;
char *path_begin = msg;
msg = strchr(msg, ' ');
*msg = '';
++msg;
strcpy(arg->c_arg->root, path_begin);
char *version_begin = msg;
msg = strstr(msg, "
");
*msg = '';
strcpy(version, version_begin);
if (!is_implemented) {
not_implemented(arg->sock, version);
return (void *)-1;
}
int version_check = !strcmp(version, "HTTP/1.0")
|| !strcmp(version, "HTTP/1.1");
if (!version_check) {
bad_request(arg->sock, version);
return (void *)-1;
}
serve_request(arg->sock, arg->c_arg, version);
}
} else if (result < 0) {
perror("Error in select");
return (void *)-1;
} else {
close(arg->sock);
}
} while (result == -1);
return (void *)0;
}
I have some problem with select(). When I launch server and try to open only one page, it doesn't open. But when I close this page and open new ones, they open and work nice. Could anyone tell me where a problem may be?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…