您好我正在尝试编写一个非常简单的网络服务器。它将响应任何请求相同的简单网页。这是代码片段:
while(1) {
if ((newFd = accept(s, (struct sockaddr *) &clientAddr, &sockAddrSize)) == ERROR) {
printf("error accept\n");
close(s);
return;
}
pid = fork();
if(pid == 0) {
handle_request(newFd);
close(newFd);
return;
}
}
句柄重新设定功能是:
void handle_request(int newFd) {
int readBytes;
int sendBytes;
readBytes = recv(newFd, buffer, BUFFSIZE, 0);
sendBytes = send(newFd, page, strlen(page), 0);
printf("I have send %d B out of %d B\n", sendBytes, strlen(page));
}
其中page是简单的全局变量:
char *page = "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>Hello</h1>\r\n";
会发生什么,浏览器正在等待(似乎接收数据,选项卡中的圆圈正在旋转)并且什么也没显示(尝试过Firefox和Chromium)。只有在我杀死主进程(使用accept())之后它才会显示页面。
我不知道哪里可能有问题,我想我做得对。我为新进程发送响应并关闭accept返回的描述符并关闭子进程。
答案 0 :(得分:0)
浏览器“挂起”,因为它仍在等待数据。它有两种方法可以知道没有更多的数据。通过标题说明内容的长度(content-length
),或者通过服务器关闭套接字来指示服务器已完成发送。
您的代码中存在两个主要问题,您没有在主进程和分叉进程中关闭套接字但是您只是返回,我怀疑您是在主进程中运行它而不是但事实上,在分叉的孩子中调用exit()是一种好习惯。如果你不这样做,他们将继续运行,并可能导致一些讨厌和难以发现的错误。如果你没有在while循环中关闭newFd
,你最终会用完套接字描述符,你的服务器将无法接受新的请求。