C++ - bind() fails

C++ - bind() fails

本文关键字:fails bind C++      更新时间:2023-10-16

我正在尝试学习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 服务器端口有什么问题?

附言:opt位到底是什么(我正在遵循教程并同时查看sys/socket的文档(?

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

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

您有前 2 个参数值向后,调用需要如下所示:

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

如果(套接字描述 == 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;
}

我会把这个答案留在这里,即使这次不是这样。我认为这仍然是一个真实的案例,在网站上寻找答案的人可能会对此表示赞赏。

(上面代码的真正答案在评论中(


您需要关闭套接字,但您尚未在每个故障状态下都这样做。它将保持打开状态并阻止您再次绑定到它,即使该过程结束也是如此。

如果不是这种情况,则可能有其他程序使用该端口。尝试更改端口号。