无法绑定到套接字

时间:2016-02-09 12:38:44

标签: c++ sockets

代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
// #include <thread>
#include <arpa/inet.h>
#include <iostream>

using namespace std;

#define PORT 8888
#define BACKLOG 5

int main(int argc, char const *argv[]) {

    int status;
    struct addrinfo hints,
                    *res,
                    *temp;

    char ipstr [INET6_ADDRSTRLEN];
    int socket_fd;

    memset (&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;        // Allows both IPv4 and IPv6
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;        // Allows automatic fill-up of IP (allows using localhost)

    if ((status = getaddrinfo (NULL , "8000", &hints, &res)) != 0 ) {
        cout << "[-] Error: " << gai_strerror (status) << endl;
        exit (EXIT_FAILURE);
    }

    socket_fd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
    if (socket_fd == -1) {
        cout << "[-] Error : Socket couldn't be created" << endl;
        exit (EXIT_FAILURE);
    }

    if (bind (socket_fd, res->ai_addr, res->ai_addrlen) == -1 ) {
        cout << "[-] Error: Failed to bind to port" << endl;
        exit (EXIT_FAILURE);
    }

    if (connect (socket_fd, res->ai_addr, res->ai_addrlen) == -1) {
        cout << "[-] Error: Failed to connect to remote user" << endl;
        exit (EXIT_FAILURE);
    }

    freeaddrinfo (res);        // free the linked list returned by getaddrinfo ()
    return 0;
}

代码正在返回:
[ - ]错误:无法绑定到端口

如果我在getaddrinfo()的第一个参数上设置NULL(使其监听localHost)或提供一些地址,它无法解决问题,它无法将端口绑定到套接字。正如我通过更改端口的值尝试的那样,端口可用。代码有什么问题?

2 个答案:

答案 0 :(得分:2)

代码很好,所以第一次执行时一切都按预期工作。但是,后续执行同一程序将报告

[-] Error: Failed to bind to port

如果您运行netstat --tcp --numeric | grep 8000,您将看到端口8000上的套接字处于TIME_WAIT状态:

bash-4.2$ netstat --tcp --numeric | grep 8000
tcp        0      0 127.0.0.1:8000          127.0.0.1:8000          TIME_WAIT

表示连接已关闭,因此它将在操作系统指定的超时时间内终止(默认为4分钟)。超时到期后,程序执行时没有错误(再次只执行一次)。

答案 1 :(得分:0)

这里的东西没有意义。显示的代码尝试将套接字绑定到端口,然后立即将connect()绑定到同一端口。因此,即使绑定有效,connect()也会失败,因为没有任何东西正在侦听该端口。

现在,bind()失败的最可能原因是因为套接字意外终止后,内核将不允许同一个端口重复使用一分钟左右,因为许多安全性相关的原因太无聊,无法讨论。第一次运行此代码时,绑定应该成功,但connect()将失败,程序将退出;然后在接下来的一分钟左右,重新运行它将导致内核拒绝重用端口bind()失败。

要防止这种情况,您必须显式设置SO_REUSEADDR套接字选项。您会在Google中找到大量示例。这将允许您立即重新绑定相同的端口。现在,您需要做的就是弄清楚您希望通过connect()调用完成什么...

相关问题