UDP Bind问题给出10022错误提示

发布于 2021-11-16 16:37:41 字数 2794 浏览 472 评论 2

要求是:设备与主机之间是UDP通信,当刷新设备时,需要释放socket资源,然后再新建socket资源。(没有设置socket的地址重用属性,因为要防止会带来其他的隐患,比方说接收到旧的错误消息)

sock为类成员变量

port也为类成员变量

(一些错误校验都省略了)

第一个版本:

bool InitSocket()

{

    sock = socket(AF_INET, SOCK_DGRAM, 0);

    SOCKADDR_IN sockSrc;
     sockSrc.sin_family = AF_INET;
     sockSrc.sin_port = htons(port);
     sockSrc.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
     int times = 0;
     while(times < 1000000 && SOCKET_ERROR == bind(sock, (SOCKADDR *)&sockSrc, sizeof(SOCKADDR)))

    { 
          qDebug("CanThread: Bind socket error! Reason %d", WSAGetLastError());
          times++;
          Sleep(200);

   }

}


绑定说明:对于绑定经常会给出10048错误提示,在此时的情况下,出现10048的原因是在释放socket资源后系统没有真正的立即释放掉,此时绑定就会出现10048这个错误。系统真正的释放时间应该在2~4分钟。这里使用while循环绑定的理由:考虑到udp的特性,我们可以连续绑定的,直到绑定成功,这主要是针对10048错误而言的,以为过一段时间系统会真正的释放socket资源,此时我们就可以用了,使用循环主要是我们不知道系统何时释放该socket资源。

第二个版本:

typedef sturct tag_UDP_SOCKET_PORT

{

      SOCKET sock;

     int port;

}UDP_SOCKET_PORT;

DWORD WINAPI bindUDPThread(LPVOID lpParam)

{

     UDP_SOCKET_PORT *usp = (UDP_SOCKET_PORT*)lpParam;

    SOCKADDR_IN sockSrc;
      sockSrc.sin_family = AF_INET;
      sockSrc.sin_port = htons(usp->port);
      sockSrc.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
      int Ret;
      while(1)

      {
           Ret = bind(usp->sock, (SOCKADDR *)&sockSrc, sizeof(SOCKADDR));
           if(SOCKET_ERROR == Ret)

          {
                int tmpRet = WSAGetLastError();
                qDebug("Bind Socket Error!Reason:%d,port = %d",WSAGetLastError(),port);
           }
           else
           {
                break;
           }
           Sleep(2000);
  }

     delte lpParam;

     return 0;

}

bool InitSocket()

{

    sock = socket(AF_INET, SOCK_DGRAM, 0);

    SOCKADDR_IN sockSrc;
     sockSrc.sin_family = AF_INET;
     sockSrc.sin_port = htons(port);
     sockSrc.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
     int times = 0;
     while(times < 10 && SOCKET_ERROR == bind(sock, (SOCKADDR *)&sockSrc, sizeof(SOCKADDR)))

    {
          qDebug("CanThread: Bind socket error! Reason %d", WSAGetLastError());
          times++;
          Sleep(200);

   }

   if(times >= 10)

   {

                //当十次没有绑定成功的话,就开启一个线程专门用于绑定

         UDP_SOCKET_PORT *usp = new UDP_SOCKET_PORT;

        usp->sock = sock;

        usp->port = port;

          CreateThread(NULL,0,bindUDPThread,usp,NULL,NULL);

   }

}

疑问:

第一个版本中输出的错误提示总是10048

第二个版本中,新建的线程却给出10022,搞不懂。。。


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

带上头具痛哭 2021-11-18 08:10:37

该端口是被我的软件占用的,在刚开启系统时,我会检测一下我本系统所使用的固定端口,如果发现固定端口被其他进程占用,则直接杀死该进程。在系统正常运行时,该端口只被本系统使用,当刷新设备时,需要重新绑定端口,此时有可能出现10048(地址已使用)的错误提示,使用循环就是确保在系统真正释放socket资源后第一时间绑定成功,不使用第一种方法是因为第一种方法将卡死系统。

妖妓 2021-11-17 13:00:56

你应该只bind一次而不是把bind放在while里面。你为什么要while bind, 如果端口被占用你永远不能bind成功.

诡异的代码

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文