我正在使用多进程/多线程架构在C中使用服务器。一开始,我有一个主要的过程,分叉10个不同的过程。每个进程都创建一个线程池。每个进程也是其池的控制器(在需要时创建新线程/扩展池)。
进程还侦听套接字(其访问权限由主进程控制,共享内存区域中具有未命名的信号量),并在获取连接时将套接字文件描述符传递给其池中的一个线程。所选线程(由pthread_cond_signal
唤醒)使用recv
选项从MSG_DONTWAIT
读取套接字。
ssize_t readn, writen;
size_t nleft;
char *buff;
buff = malloc(sizeof(char) * BUFF_SIZE);
if (buff == NULL) {
perror("malloc");
return EXIT_FAILURE;
}
char *ptr = buff;
/*if (fcntl(connsd, F_SETFL, O_NONBLOCK) == -1) { // set to non-blocking
perror("fcntl");
exit(EXIT_FAILURE);
}*/
errno = 0;
nleft = BUFF_SIZE;
while(nleft > 0) {
if ((readn = recv(connsd, ptr, nleft, MSG_DONTWAIT)) < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
*ptr = '\0';
break;
}
else if (errno == EINTR)
readn = 0;
else {
perror("read");
return EXIT_FAILURE;
}
}
else if (readn == 0)
break;
if (buff[strlen(buff)-1] == '\0') {
break;
}
nleft -= readn;
ptr += readn;
}
问题在于,有时候,当我尝试使用Chrome(或Firefox)连接到服务器时,3个线程似乎接收到HTTP请求,但是由于这部分代码,每个线程都只是关闭连接。
if (buff[strlen(buff)-1] != '\0') {
printf("%s\n",buff);
fflush(stdout);
buff[strlen(buff)-1] = '\0';
}
errno = 0;
if (strlen(buff) < 1) {
perror("No string");
if (shutdown(connsd,SHUT_RDWR) < 0) {
perror("shutdown");
return EXIT_FAILURE;
}
if (close(connsd) < 0) {
perror("close");
return EXIT_FAILURE;
}
return EXIT_FAILURE;
}
其他时候我们有3个具有不同行为的线程:其中一个接收并从套接字读取第一个HTTP请求(GET / HTTP / 1.1)。第二个是空的(收到请求(因为它被唤醒(?))没有字符串读取)。第三个接收并读取另一个HTTP请求(GET /favicon.ico HTTP / 1.1)。
导致这些行为的问题在哪里?如果需要,我可以添加其他代码部分。
非常感谢你的时间。