c++ - 无明显原因的 WSA 10049 错误

标签 c++ sockets networking

我一直在尝试用 C++ 编写一个简单的聊天程序,但遇到了一个套接字问题。以下代码正在返回

上次错误代码为(1):0
最后一个错误代码是(2): 0
上次错误代码为 (3):10049
最后的错误代码是 (4): 10022

在检查 MSDN 页面的 WSA 错误后,我发现 10022 是一个无效参数,而 10049 试图绑定(bind)到一个不可用的地址。我得出的结论是 10049 错误导致了 10022 错误,因为我正在尝试监听未绑定(bind)的套接字。

之后,尝试了几个不同的地址以找到任何可用地址,包括 127.x.x.x、192.168.x.x、0.0.0.0,但均无效。我跳入 CMD,看到其他进程正在使用这些地址谁能给我指出正确的方向来找到这个问题的根源?

#include "stdafx.h"
using namespace std;

int main()
{
     long SUCCESSFUL;
     WSAData WinSockData;
     WORD DLLVERSION;

     DLLVERSION = MAKEWORD(2, 1);

     SUCCESSFUL = WSAStartup(DLLVERSION, &WinSockData);

     SOCKADDR_IN ADDRESS;
     int AddressSize = sizeof(ADDRESS);

     SOCKET sock_CONNECTION;

     const CHAR addr[15] = "127.0.0.1";
     char buffer [sizeof(in_addr)];

     printf("Last error code was(1): %d\n", WSAGetLastError());

     sock_CONNECTION = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     ADDRESS.sin_addr.s_addr = inet_pton(AF_INET, (const CHAR*)&addr, &buffer);
     ADDRESS.sin_family = AF_INET;
     ADDRESS.sin_port = htons(444);

     printf("Last error code was(2): %d\n", WSAGetLastError());


     bind(sock_CONNECTION, (SOCKADDR *)&ADDRESS, AddressSize);

     printf("Last error code was(3): %d\n", WSAGetLastError());

     listen(sock_CONNECTION, 5);

     printf("Last error code was(4): %d\n", WSAGetLastError());
     //note to self: don't use %x when referring to WSAGetLastError, returns untrue value outside WSAerror regular field
     pause();
     return 0;
}

最佳答案

首先,一般注意事项:您需要检查您调用的每个函数的返回值,并且只有在返回值表明该函数返回错误时才打印出 WSAGetLastError() 的值。否则,您只会通过查看先前调用遗留的错误代码值而使自己感到困惑,而与最近调用的调用没有任何关系。也就是说,不是这样做:

bind(sock_CONNECTION, (SOCKADDR *)&ADDRESS, AddressSize);
printf("Last error code was(3): %d\n", WSAGetLastError());

...你应该这样做:

if (bind(sock_CONNECTION, (SOCKADDR *)&ADDRESS, AddressSize) != 0)
{
    printf("bind() failed, last error code was(3): %d\n", WSAGetLastError());
}

... 和您调用的所有其他函数类似。 (请注意,不同的函数返回不同的值以指示错误,因此您需要阅读每个函数的文档页面以找出测试成功与失败的返回值的正确方法)

也就是说,我认为具体问题在这里:

 ADDRESS.sin_addr.s_addr = inet_pton(AF_INET, (const CHAR*)&addr, &buffer);

inet_pton () 不返回地址;相反,它返回“如果地址对指定的地址族有效,则返回 1,如果地址在指定的地址族中不可解析,则返回 0,如果发生某些系统错误(在这种情况下将设置 errno),则返回 -1”。因此,您写入 ADDRESS.sin_addr.s_addr 的值是 -1、0 或 1;这些都不是 bind() 想要使用的有效地址。 (好吧,实际上可以使用0;见下文,但仍然调用错误)

调用 inet_pton() 的正确方法应该是这样的:

int result = inet_pton(AF_INET, addr, &ADDRESS.sin_addr);
if (result != 1) printf("inet_pton() failed, error code %d\n", WSAGetLastError());

...但我怀疑对于您可能想要执行的操作(接受任何网络接口(interface)上的连接),您根本不需要调用 inet_pton()。相反,您可以将 ADDRESS.sin_addr.s_addr 设置为 INADDR_ANY,然后 bind() 将绑定(bind)您的套接字,无论它们来自哪个网络接口(interface),它都会接受传入的 TCP 连接。

 // INADDR_ANY (aka 0) means "I don't care which network interface, accept connections on any of them"
 ADDRESS.sin_addr.s_addr = INADDR_ANY;

关于c++ - 无明显原因的 WSA 10049 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35307583/

相关文章:

python - Mininet API 中两个节点之间是否存在链接

windows - Windows TraceRt 报告的数字是什么意思

c++ - OpenMP 代码远比串行慢 - 内存或线程开销瓶颈?

c++ - 具有模板化派生类的基类纯虚函数

c++ - 使用注入(inject)的类名调用成员函数

python - Python 中的 ZMQ : New socket object for each incoming connection

java - connect(localhost) 抛出异常,connect(私有(private)地址) 阻塞

java - 如何使两个单独的客户端共享来自服务器的相同数据?

android - Appmobi 应用程序可在 Wifi 上运行,但在 3g 上出现黑屏

c++ - qt 删除布局代码