首页 > 解决方案 > C++ - 绑定()失败

问题描述

我正在尝试学习 C++ 中的网络,并且正在尝试设置一个简单的演示,在该演示中我在端口 5000 上打开一个 TCP 服务器,然后立即关闭它。这是我的代码:

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>

int main()
{
    int port = 5000;
    std::cout << "Port: " << port << "\n";
    int socketdesc = socket(SOCK_STREAM, AF_INET, 0);

    if (socketdesc == 0)
    {
        std::cout << "Failed to create socket description.\n";
        return 1;
    }

    int opt = 1;

    if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
               &opt, sizeof(opt)))
    {
        std::cout << "Failed to attach socket.\n";
        return 1;
    }

    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);

    if (bind(socketdesc, (struct sockaddr *)&address,
         sizeof(address)) < 0)
    {
        std::cout << "Failed to bind socket!\n";
        return 1;
    }

    std::cout << "Listening with protocol TCP on port" << port << ".\n";

    if (listen(socketdesc, 3) < 0)
    {
        std::cout << "Failed to listen!\n";
        return 1;
    }

    if (shutdown(socketdesc, SHUT_RDWR) < 0)
    {
        std::cout << "Failed to close socket!\n";
        return 1;
    }

    std::cout << "TCP test succeeeded.\n";
    return 0;
}

尝试将套接字绑定到端口 5000 时出现错误。设置 TCP 服务器端口出了什么问题?

PS:选择位到底是什么(我正在关注教程并同时查看 sys/socket 的文档)?

标签: c++sockets

解决方案


在您到达之前,您的代码中有几个错误bind()

int socketdesc = socket(SOCK_STREAM, AF_INET, 0);

您有前 2 个参数值,调用需要看起来像这样:

int socketdesc = socket(AF_INET, SOCK_STREAM, 0);

如果 (socketdesc == 0)

socket()出错时返回 -1,而不是 0。

if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)))

setsockopt()出错时也返回 -1。

但更重要的是,您不能像这样在一次调用中组合多个套接字选项。您需要setsockopt()单独调用每个选项:

if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
...

if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0)
...

话虽如此,试试这个:

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main()
{
    int port = 5000;
    std::cout << "Port: " << port << "\n";

    int socketdesc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (socketdesc == -1)
    {
        std::cout << "Failed to create socket descriptor. " << strerror(errno) << "\n";
        return 1;
    }

    int opt = 1;

    if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
    {
        std::cout << "Failed to set SO_REUSEADDR option. " << strerror(errno) << "\n";
        return 1;
    }

    if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0)
    {
        std::cout << "Failed to set SO_REUSEPORT option. " << strerror(errno) << "\n";
        return 1;
    }

    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);

    if (bind(socketdesc, (struct sockaddr *)&address, sizeof(address)) < 0)
    {
        std::cout << "Failed to bind socket! " << strerror(errno) << "\n";
        return 1;
    }

    std::cout << "Listening with protocol TCP on port" << port << ".\n";

    if (listen(socketdesc, 3) < 0)
    {
        std::cout << "Failed to listen on socket! " << strerror(errno) << "\n";
        return 1;
    }

    if (shutdown(socketdesc, SHUT_RDWR) < 0)
    {
        std::cout << "Failed to close socket! " << strerror(errno) << "\n";
        return 1;
    }

    close(socketdesc);

    std::cout << "TCP test succeeeded.\n";
    return 0;
}

推荐阅读