【问题标题】:TCP Operation Timed OutTCP 操作超时
【发布时间】:2009-09-26 02:32:07
【问题描述】:
我有一个用 C 语言编写的 TCP 服务器和客户端,它打开了一个应该永远打开的连接。在第一次发送时,errno 返回 0,这很好。在随后的发送中,它给了我一个 errno 60,即操作超时。服务器仍然接收到数据包,似乎没有任何问题。什么可能导致设置错误?是否最好忽略此错误,因为它似乎工作正常?
【问题讨论】:
标签:
c
unix
networking
tcp
【解决方案1】:
随机猜测:errno 仅在函数失败时设置。如果函数没有失败,errno 将保持原样。它不设置为0。以下是错误的:
send( … );
if (errno) {
perror("send");
}
相反,您必须检查发送的结果:
ssize_t res = send( … );
if (-1 == res) {
perror("send")
}
您可以通过以下程序确认这一点:
#include <stdio.h>
#include <unistd.h>
int main() {
char buf[16];
ssize_t res;
read(999, buf, sizeof(buf));
perror("read");
write(1, "hello world\n", 12);
perror("write");
}
哪个输出:
read: Bad file descriptor
hello world
write: Bad file descriptor
(注意:假设 STDOUT 为 fd 1)
【解决方案2】:
正如其他人所暗示的那样,您需要测试 Unix 系统函数的返回值......所有这些函数!......为了以防弹方式解释 errno 值。我建议您参考规范指南的第 6 项,Henry Spencer 的The Ten Commandments for C programmers:
如果一个函数被宣传为在遇到困难时返回一个错误代码,你应该检查那个代码,是的,即使检查是你的代码大小的三倍,而且你打字的手指会感到疼痛,因为如果你认为“这不可能发生在我身上”,神肯定会因你的傲慢而惩罚你。
【解决方案3】:
我认为你只测试了 errno 变量,而不是 send() 的返回值。
在函数返回值表明 errno 变量由函数设置后,您应该检查 errno 变量。如果函数没有报告设置了 errno,则 errno 变量不包含有意义的值。