【问题标题】:bind() fails with windows socket error 10049bind() 失败并出现 Windows 套接字错误 10049
【发布时间】:2013-01-16 19:18:09
【问题描述】:

我尝试使用 IPv6 和 UDP 用 C 语言制作客户端/服务器程序。当程序绑定套接字时,它返回 WSAError 10049。我知道这是地址名称的问题,但看不出是什么问题。我希望有人可以提供帮助。

struct sockaddr_in6 server, client;
SOCKET sock;
char buffer[BUFFERSIZE];
LPTSTR recvBuff[1024];
DWORD recvBuffLen = 1024UL;
int len = sizeof(client);

WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(1,1);
WSAStartup(wVersionRequested, &wsaData);

sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0)
    error("Fehler beim Anlegen des Sockets");

server.sin6_family = AF_INET6;
server.sin6_port = htons(6000);
server.sin6_addr = in6addr_any;

if (bind(sock, (struct sockaddr *) &server, sizeof(server)) == -1)
    error("Fehler beim binden des Sockets");

【问题讨论】:

  • 是的,它已定义,我将代码更改为实际值
  • 根据许多 Linux 教程,您必须在 memset 和 sockaddr_in6 中加上零。 (我知道是 Windows,但值得一试)

标签: c windows sockets bind


【解决方案1】:

This normally results from an attempt to bind to an address that is not valid for the local computer..

您应该在这里使用PF_INET 而不是AF_INET。它们具有相同的值,但您没有在此处指定地址族AF,而是指定了协议族PF。这只是一个风格推荐。

我建议memset 将以下数组、结构归零:

struct sockaddr_in6 server, client;
SOCKET sock;
char buffer[BUFFERSIZE];
LPTSTR recvBuff[1024];

【讨论】:

    【解决方案2】:

    在您可以使用sockaddr_in6 结构之前,您必须将memset 归零:

      memset(server, 0, sizeof(struct sockaddr_in6));
    

    原因是struct sockaddr_in6 结构包含您未初始化的其他字段(例如sin6_scope_id)并且可能包含垃圾。

    【讨论】:

    • 或者:struct sockaddr_in6 server = {0}, client = {0};
    【解决方案3】:

    我也遇到了同样的错误。

    @askMish 's answer说的很对,一开始没看懂,后来发现了。

    这通常是由于尝试绑定到对本地计算机无效的地址造成的。

    通常我们的计算机在某个网关下。

    如果我们运行ipconfig,我们会发现 IP 地址是 192.168.something。

    这就是我们可以用来在代码中绑定的 IP。

    而其他人应该与公共 IP 连接(如果你可以上网,你肯定有一个。)比如 47.93.something 如果他们与你在同一个局域网中。

    你需要在你的网关上找到那个IP(可能是你家人的路由)。

    【讨论】:

      【解决方案4】:

      我在 windows 下调用bind() 时遇到了同样的错误代码。

      在我的案例中,原因与最初发布者的代码不同,但我想其他人会犯和我一样的错误:

      我使用inet_addr()-函数生成了我希望在本地绑定服务器的本地地址。 我以这种方式将这个结果分配给本地地址结构struct sockaddr_in localaddr:

      localaddr.sin_addr.s_addr = htonl(inaddr);

      但是inet_addr()已经以字节网络顺序返回地址,所以我的代码中调用htonl(inaddr)是错误的,导致错误10049:

      SOCKET tcpsock_bindlisten(unsigned short port, const char* bindaddr)
      {
          SOCKET srvsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
      
          unsigned long inaddr = bindaddr ? inet_addr(bindaddr) : INADDR_ANY;
      
          struct sockaddr_in localaddr;
          memset(&localaddr, 0, sizeof(struct sockaddr_in));
          localaddr.sin_family        = AF_INET;
          localaddr.sin_port          = htons(port);  
      
          // ERROR HERE! address returned from inet_addr is already in network-byte-order!
          localaddr.sin_addr.s_addr   = htonl(inaddr); 
      
          // CORRECT THIS WAY:
          localaddr.sin_addr.s_addr   = inaddr;   
      
          if (bind(srvsock, (struct sockaddr *) &localaddr, sizeof(localaddr)) != 0)
          {
              print_socketerror("tcpsock bind()");
              return INVALID_SOCKET;
          }
      
          if (listen(srvsock, SVRSOCK_BACKLOG) != 0)
          {
              print_socketerror("tcpsock listen()");
              return INVALID_SOCKET;
          }
      
          return srvsock;
      }
      

      当使用“所有本地接口”(INADDR_ANY) 调用 bind() 时,它起作用了,因为这种巧合INADDR_ANY == htonl(INADDR_ANY):

      int main()
      {
          ...
          // this works for this special case:
          SOCKET svrsock1 = tcpsock_bindlisten(4444, NULL); 
      
          // did not work!
          SOCKET svrsock2 = tcpsock_bindlisten(5555, "192.168.0.123"); 
      }
      

      【讨论】:

      • 同样的原因。您尝试绑定的 IP 地址是非本地的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      • 1970-01-01
      • 2019-09-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-14
      相关资源
      最近更新 更多