【问题标题】:linux sockets accept always failinglinux套接字接受总是失败
【发布时间】:2016-06-16 23:00:20
【问题描述】:

我有一个相对简单的服务器,它应该打开一个服务器套接字并接受一个客户端套接字连接。

if(!(STARTUP))
{
// CAN Socket öffnen
can_soc = initialize_CAN();

// TCP Socket öffnen
tcp_soc = initialize_TCP(strtol(argv[1],NULL,10));

STARTUP = 1;
}


// Jede empfangene CAN Botschaft auf TCP umleiten
while(!(EXIT_FLAG))
{

if(!(CLIENT_CONNECTED)) // Wenn keiner verbunden ist, wird gelistened
{
    // LISTEN //
        listen(tcp_soc,2);

    std::cout << "Waiting for incoming TCP connection...\n";

    c = sizeof(struct sockaddr_in);

    tcp_client_soc = accept(tcp_soc, (struct sockaddr *)&client, (socklen_t*)&c);

    if(tcp_client_soc < 0)
    {
    std::cout << "ERROR: accept failed\n";
    EXIT_FLAG = 1;
    return 0;
    }
    else
    {
    std::cout << "Connection from " << inet_ntoa(client.sin_addr) << " accepted!\n";
    // --> NEUER CLIENT AKZEPTIERT //
    CLIENT_CONNECTED = 1;
    }
}
else            // ansonsten: CAN auf TCP leiten
{
    std::cout << "nop" << std::endl;
}

}

现在的问题是,程序总是在“ERROR:accept failed”处终止,这意味着accept总是在没有建立连接的情况下传递-1(没有设置O_NONBLOCK)。

int initialize_TCP(int pPort)
{
    int tcp_soc;

    std::cout << "Creating TCP socket and binding to PORT: " << pPort << "... ";

    tcp_soc = socket(AF_INET, SOCK_STREAM, 0);

    if(tcp_soc == -1)
    {
        std::cout << "ERROR: Could not create socket!\n";

    EXIT_FLAG = 1;
    }


    server.sin_addr.s_addr = INADDR_ANY;    //do not specify IP (got a server here)
    server.sin_family = AF_INET;
    server.sin_port = htons(pPort);

    // BIND //

    if(bind(tcp_soc,(struct sockaddr *)&server, sizeof(server)) < 0)
    {
        std::cout << "Binding failed! Restarting network service ...\n";

        system("/etc/init.d/networking restart");   //Restarted Network Servcie wenn Binding nicht geht

        std::cout << "Binding again... ";
        bind(tcp_soc,(struct sockaddr *)&server, sizeof(server));
        std::cout << "OK\n";
    }


    std::cout << "OK\n";
}

那么问题出在哪里?也许每次都有未知的连接进入?还是语法问题?

【问题讨论】:

  • 您在while 循环中调用listen()。它应该在循环之外,或者在bind() 成功之后更好地在initialize_TCP() 内部。无论哪种方式,当accept()(或任何其他套接字函数)失败时,errno 的值是多少?您应该将其输出到cout。此外,您也应该输出strerror() 的结果。另外,不要重新启动网络服务,这不是您的应用程序的责任。让用户去做。但是,如果您确实重新启动,您可能必须从头开始重新创建您的侦听套接字。您没有检查重试的bind() 是否失败。
  • 您还需要对socket(), listen(), bind(), ...应用相同的错误检查
  • 感谢@RemyLebeau,我实现了errno,它显示88,“非套接字类型的操作”,这意味着我假设套接字没有正确初始化?
  • @rele92:错误 88 是 ENOTSOCK,所以是的,您必须将无效的套接字描述符传递给 accept()

标签: linux sockets tcp server client


【解决方案1】:

发现问题,套接字不存在,因此 ERRNO 提供了代码 88。 这是由于没有正确返回套接字描述符造成的。

【讨论】:

    猜你喜欢
    • 2015-12-26
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 2020-03-26
    • 1970-01-01
    • 2011-04-29
    相关资源
    最近更新 更多