无法绑定winsock套接字

Posted

技术标签:

【中文标题】无法绑定winsock套接字【英文标题】:Can't bind winsock socket 【发布时间】:2021-11-16 03:24:00 【问题描述】:

我对 c++ 网络很陌生,所以我一直在看一些教程,但我似乎无法找出为什么我不能绑定我的套接字。有人可以向我解释我做错了什么吗?这是我绑定套接字的代码。

#include <stdlib.h>
#include <winsock2.h>

#pragma comment (lib,"ws2_32.lib")
#pragma warning( disable : 4996)
#define PORT 17027
int main()

    //creating socket
    SOCKET listenSocket = INVALID_SOCKET;
    listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    //bind socket
    struct sockaddr_in address;
    memset(&address, 0, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_port = htons(PORT);

    int bindValue = bind(listenSocket, (struct sockaddr *)&address, sizeof(address));
    if (bindValue == SOCKET_ERROR) 
        std::cout << WSAGetLastError() << std::endl; 
        return 1;
    

输出:无法绑定:10038

【问题讨论】:

【参考方案1】:

错误10038WSAENOTSOCK(“非套接字上的套接字操作”),这意味着您正在对无效的SOCKET 调用bind()。事实上,您并没有检查socket() 是否成功。事实并非如此,因为您没有先调用WSAStartup(),所以socket() 失败并出现WSANOTINITIALISED 错误(“尚未执行成功的WSAStartup”)。

WSAStartup 函数必须是应用程序或 DLL 调用的第一个 Windows 套接字函数。它允许应用程序或 DLL 指定所需的 Windows 套接字版本并检索特定 Windows 套接字实现的详细信息。 应用程序或 DLL 只能在成功调用 WSAStartup 后发出进一步的 Windows Sockets 函数。

【讨论】:

您应该从这个答案中得到的一件事是始终检查返回码并确保您了解返回的值意味着什么。在网络编程中,您必须对返回码保持虔诚,因为它们很少只是工作/失败。例如,recv 告诉您读取了多少数据(这并不总是要求的数据量)或套接字礼貌地断开连接或发生错误,您将不得不再次调用 @987654331 @ 找出错误是什么。【参考方案2】:

您必须说明要将套接字绑定到哪个接口。这是通过设置sockaddr_in 结构的sin_addr 成员来完成的。

例如,要绑定到通配符接口INADDR_ANY(以便能够接收来自所有接口的连接),您可以执行以下操作:

address.sin_addr.s_addr = htonl(INADDR_ANY);

要绑定到特定接口,您可以执行以下操作:

address.sin_addr.s_addr = inet_addr("interface IP here");

关于错误报告,Winsock API 没有为错误设置errnoerrnoperror() 使用)。相反,您需要使用WSAGetLastError() 获取错误代码,并使用FormatMessage() 获取错误描述。

【讨论】:

我只是尝试添加“address.sin_addr.s_addr = htonl(INADDR_ANY);”部分并将 perror 部分更改为 WSAGetLastError 但它仍然不起作用,我没有收到任何错误。 @ReaperB_G 你打印WSAGetLAstError()的结果吗?喜欢if (bindValue == SOCKET_ERROR) std::cout &lt;&lt; WSAGetLastError() &lt;&lt; '\n'; return 1; 是的,我把错误函数弄错了。但现在我收到错误 10038。 @ReaperB_G 如果您按照我链接到的文档,并按照它到error codes,您将看到10038 表示WSAENOTSOCK,即“非套接字上的套接字操作”。 socket 调用成功了吗?你检查过吗?我敢打赌它没有成功,因为你忘了调用WSAStartup 函数。请记住始终检查 所有 函数的错误。 好的,我添加了 WSAStartup 函数,然后调用了套接字设置并修复了它,感谢您的帮助。

以上是关于无法绑定winsock套接字的主要内容,如果未能解决你的问题,请参考以下文章

Winsock API TCP/IP网络通信

连接前的 WinSock 绑定导致 WSAEADDRNOTAVAIL - 请求的地址在其上下文中无效

套接字程序 Python vs C++ (Winsock)

Windows socket api 绑定函数编译问题

Winsock编程基础2(UDP流程)

从winsock数据中检测用户?