我想给udp socket绑定一个端口,可是怕被其它软件占用,所以把端口定义了一个范围,请问该如何实现???? 以前做法是直接绑定一个0端口,这样系统会给分配一个系统中未被使用的端口,可是我如何能给其添加一个范围呢?? 比如我想绑定(9001-9999)中一个系统没有被使用的端口?

解决方案 »

  1.   

    查看bind的返回值,如果错误就换个断口再bind,循环
      

  2.   

    // 给一段参考代码给你
    int CSocketBase::BindEx(SOCKET s, short port, DWORD ip /*=INADDR_ANY*/)
    {
    ASSERT(m_hSocket != INVALID_SOCKET);
    sockaddr_in LocalAddr;
    int   nTemp = port;
    int   nResult  = 0;
    BOOL bTautology = FALSE;
    do
    {
    LocalAddr.sin_family = AF_INET;
    LocalAddr.sin_addr.s_addr = htonl(ip);
    LocalAddr.sin_port = htons(nTemp);
    // Bind the socket handle on local host
    // If bind falied and error be WSAEADDRINUSE
    // then redistribute port
    nResult = bind(m_hSocket, (sockaddr*)&LocalAddr, sizeof(LocalAddr));
    if(nResult == SOCKET_ERROR)
    {
    int nError = WSAGetLastError();
    TRACE("bind() falied with error code %d\n", nError);
    if(nError == WSAEADDRINUSE)
    {
    bTautology = TRUE;
    nTemp++;
    }
    }
    else
    {
    bTautology = FALSE;
    }
    } while(bTautology); return nResult;
    }
      

  3.   

    首先谢谢大家的指点!
    循环检测的方法的确简单实用,但是我的bind这段代码是单独封装的,调用的地方很多,如此一下改动比较大!(请大家不要问我mynamelj(夏娃的诱惑)提供的代码也不需要太多的改动啊,因为我的实际情况描述起来一言难尽,请大家谅解)
    能不能有一种方式,在使用bind之前,采用set***之类的函数预先设定一下范围呢?
    十万火急!!!!!!!
      

  4.   

    可以啊,在循环的时候加个范围判断.还有一种方法,不晓是你是否采用,就是在bind函数中将端口号设置成0,系统会自动分配可用端口.
      

  5.   

    直接bind 0端口 范围是1024-65535 太大了,这样防火墙要把所有的端口放开才行,所以我想设定一个比较小的范围!
      

  6.   

    用下面的函数可检测端口是否被使用中
             const static BOOL PortUsedUDP(ULONG uPort)
    {
    MIB_UDPTABLE UdpTable[100];
    DWORD nSize = sizeof(UdpTable);
    if(NO_ERROR == GetUdpTable(&UdpTable[0],&nSize,TRUE))
    {
    DWORD nCount = UdpTable[0].dwNumEntries;
    if (nCount > 0)
    {
    for(DWORD i=0;i<nCount;i++)
    {
    MIB_UDPROW UdpRow = UdpTable[0].table[i];
    DWORD temp1 = UdpRow.dwLocalPort;
    int temp2 = temp1 / 256 + (temp1 % 256) * 256;
    if(temp2 == uPort)
    {
    return TRUE;
    }
    }
    }
    return FALSE;
    }
    return FALSE;
    }
      

  7.   

    再使用个for循环检测到一个未被使用的PORT就行了...
      

  8.   

    const static BOOL PortUsedUDP(ULONG uPort)
    能兼容Linux吗?
      

  9.   

    不是说要UDP的吗
    TCP如果需要明天我贴上来
    Linux的应该不行的...
      

  10.   

    谢谢 cxxstars(新新)
    其实udp就可以满足我的要求了,不过我想再封装的时候顺便把tcp的也做了,免得日后用的时候费脑筋!呵呵!
      

  11.   

    呵呵 自己改了 就是把GetUdpTable换成GetTcpTable,对应的参数换成tcp的吧?
      

  12.   

    就是那样做的了..
    今天整天都有事,不好意思啊
             const static BOOL PortUsedTCP(ULONG uPort)
    {
    MIB_TCPTABLE TcpTable[100];
    DWORD nSize = sizeof(TcpTable);
    if(NO_ERROR == GetTcpTable(&TcpTable[0],&nSize,TRUE))
    {
    DWORD nCount = TcpTable[0].dwNumEntries;
    if (nCount > 0)
    {
    for(DWORD i=0;i<nCount;i++)
    {
    MIB_TCPROW TcpRow = TcpTable[0].table[i];
    DWORD temp1 = TcpRow.dwLocalPort;
    int temp2 = temp1 / 256 + (temp1 % 256) * 256;
    if(temp2 == uPort)
    {
    return TRUE;
    }
    }
    }
    return FALSE;
    }
    return FALSE;
    }
      

  13.   

    有个问题,如果多线程的程序启动后,每个线程都使用PortUsedUDP方法监测一个没有使用的端口,然后去绑定,如此一来必然会出现两个线程同时发现一个端口没有绑定,导致其中一个绑定失败;我们可以通过锁来解决线程间的互斥,如果是多进程或者说这个多线程程序同时启动两个以上的进程,如何避免绑定失败呢?
    不知道我说清楚了没有,最近天天加班到很晚,状态不是很好!
      

  14.   

    先用PortUsedUDP
    然后Bind有问题再继续就可以一般很少冲突的了
      

  15.   

    进程互斥可使用CMutex...
    或者 CreateMutetex(Handle)
    都是系统提供的