【问题标题】:TCP Operation Timed OutTCP 操作超时
【发布时间】:2009-09-26 02:32:07
【问题描述】:

我有一个用 C 语言编写的 TCP 服务器和客户端,它打开了一个应该永远打开的连接。在第一次发送时,errno 返回 0,这很好。在随后的发送中,它给了我一个 errno 60,即操作超时。服务器仍然接收到数据包,似乎没有任何问题。什么可能导致设置错误?是否最好忽略此错误,因为它似乎工作正常?

【问题讨论】:

  • send() 实际上返回 -1 吗?

标签: 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 变量不包含有意义的值。

      【讨论】:

        猜你喜欢
        • 2012-08-30
        • 2013-04-04
        • 2016-11-08
        • 2013-07-14
        • 2015-05-26
        • 2014-02-05
        • 2015-12-13
        • 1970-01-01
        相关资源
        最近更新 更多