【问题标题】:Accept fails on invalid argument, followed by bad file descriptor接受无效参数失败,后跟错误的文件描述符
【发布时间】:2014-08-26 14:53:22
【问题描述】:

我们的服务器在过去几个月中一直运行良好。然而,出乎意料 - 昨天 - 服务器未能接受带有“无效参数”的连接,随后出现“错误文件描述符”。

我检查过的每个网站/建议都说我应该在bind() 之后和accept() 之前有一个listen()。我有,而且我还在检查listen() 上的错误。

我正确地将客户端 sockaddr_in 的大小传递给 accept(),并将其初始化为客户端 sockaddr_in 变量的大小。

我还检查以确保我使用AF_INETsockaddr_in(而不是AF_UNIXsockaddr_un

有什么想法吗?

基本伪代码:

struct sockaddr_in server;
struct sockaddr_in client;
socklen_t client_size;

if ((mysock = socket(AF_INET, SOCK_STREAM, 0)) < 0) exit;

memset(&server, 0, sizeof(server));
// Set socket options
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = 8000;

if (bind(mysock, (struct sockaddr *) &server, sizeof(server)) < 0) exit;

if (listen(mysock, 100) < 0) exit;

while (1)
{
    clientsock = accept(mysock, (struct sockaddr *) &client, &client_size);
    if (clientsock == -1)
        printf("Accept failed() - %s\n", strerr(errno));
    else
        //do server stuff here
}

前一分钟它运行良好,然后它开始打印大量“Accept failed()”错误,第一个是 Invalid Argument,其余的是 Bad file descriptor

那台服务器上没有任何变化(我们知道)。

注意:clientsock 和 mysock 已初始化。我只是没有在这里展示。如果您看到括号问题,那是复制粘贴问题,而不是代码问题。就像我说的,服务器已经很好了很长时间了。

【问题讨论】:

  • 您不能将8000 作为端口号,它应该按网络字节顺序排列(可能与您的主机字节顺序相同,但如果您使用的是普通 PC,那么您需要使用htons函数)。另外,你不是说SOCK_STREAM吗?
  • 关于你的错误,你可能想了解operator precedence
  • "如果您发现括号有问题,那是复制粘贴问题,而不是代码问题。" 复制粘贴不会更改级别、顺序或括号。请始终显示“真实”代码,我们不是在这里追逐拼写错误等。谢谢!
  • @alk 我意识到我应该尽可能多地粘贴真实代码。有时这是不可能的,就像这种情况一样。
  • @JoachimPileborg 我已经更正了有关运算符优先级的括号,是的 SOCK_STREAM。

标签: c linux sockets networking tcp


【解决方案1】:

由于&lt;-operator 绑定得比=-operator 更紧密

if (mysock = socket(AF_INET, SOCKSTREAM, 0) < 0) exit;

应该是这样的

if ((mysock = socket(AF_INET, SOCKSTREAM, 0)) < 0) 
  exit;

甚至更好(更明显,虽然更安全),像这样:

mysock = socket(AF_INET, SOCKSTREAM, 0);
if (0 > mysock)
{
  exit;
}

【讨论】:

  • 我会改变它。但是,为什么这台服务器已经运行了几个月没有任何问题,然后突然启动它。我们杀死它并重新启动它,从那以后它一直正常运行。
  • 另外,这实际上是我的问题中的一个错字。实际代码在您的第一个建议中设置了括号。
  • 我添加了 +1,因为括号问题是我的错字。
  • @Sagar:你想说它运行没有错误,然后根据你的问题显示错误,然后你重新启动,然后它再次运行没有错误?
  • 没错!这就是让我困惑的地方。它运行良好,但突然我们开始看到一大堆错误的文件描述符错误。我们必须执行 kill -9 并重新启动服务器,从那时起它就一直正常运行。
猜你喜欢
  • 1970-01-01
  • 2016-10-14
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多