【发布时间】:2014-10-06 01:55:07
【问题描述】:
我从以下网站下载了一个简单的静态 Web 服务器的源代码 http://www.ibm.com/developerworks/systems/library/es-nweb/sidefile1.html
但是,我对第 130 行感到困惑:
#ifdef LINUX
sleep(1); /* to allow socket to drain */
#endif
exit(1);
既然套接字没有关闭,是否意味着我需要等待客户端关闭套接字?
【问题讨论】:
-
代码太多要读,sleep在什么情况下使用?通常情况并非如此,您不应该在睡觉,而是在连接关闭或 EOF 之前读取套接字。
-
程序也需要休眠。
-
那个服务器是个笑话——不要在愤怒中使用它,不要研究它。
sleep是一种迷信:不可靠的代码首先在 Linux 上失败了,所以他们做了一些事情并再次尝试,结果恰好奏效了。另外:“ret =read(fd,buffer,BUFSIZE);/* 一次性读取 Web 请求 */” - 实际上需要recv(..., MSG_WAITALL),因为read可能会合法地返回部分消息,因为允许客户端将请求写入它喜欢的任何数据包(这甚至可能是出于瞬时缓冲考虑所必需的),并且数据包可能会被中间的网络硬件拆分(或重新组合)。 -
@codenheim:无论如何,TCP 代码的通用可移植性有点过于雄心勃勃,但在许多情况下,信号处理将使用
SA_RESTART或类似设置(毕竟,有多少代码检查例如@987654328 @ 或write在收到信号后申请部分成功?- 虚拟无,因此通常需要重新启动系统才能可靠,但不幸的是,在调用sigaction时默认情况下它不是打开的)。如果来自recv的任何 错误,关闭连接通常是合理的。 -
@TonyD:这对我来说并不是很有趣,但我真的觉得这是一个非常好的陈述。忽略
EINTR,如果您收到错误消息,那还有什么有用的事情要做,您真正关心的是发生了什么。要么对方拒绝了连接(第一次接收失败,ECONNREFUSE),要么你有一个严重的程序错误,比如使用了错误的描述符或内存分配问题。无论哪种方式,您都无法以有意义的方式继续。所以你的陈述非常好。