在UDP正常通信中我的server和client都可以正常通信,可是在server广播消息时client接收不到广播消息而server可以接收到自己的广播消息!如何让client接收到UDP的广播消息?
在测试过程中发现client如果bind了相应的广播端口的话可以正常接收广播消息!
重要代码如下:
server:
//Bind端口
bool CUDPServer::BindPort(UNSHORT unBindPort)
{
//设置绑定方式
struct sockaddr_in ServerAddr;
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_port=htons(unBindPort); ///监听端口
ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY); ///本机 m_Socket=socket(AF_INET,SOCK_DGRAM,0);   
BOOL bBroadcast=TRUE;
setsockopt(m_Socket,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL));
if(SOCKET_ERROR == bind(m_Socket,(struct sockaddr*)&ServerAddr,sizeof(ServerAddr)))
{
return false;
}
return true;
}//发送广播消息
bool CUDPServer::BroadCase(char* szSend, DWORD dwSendSize)
{
SOCKADDR_IN BroadcastAddr = m_ClientAddr; 
BroadcastAddr.sin_family =     AF_INET;     
BroadcastAddr.sin_addr.s_addr =     htonl(INADDR_BROADCAST);     
BroadcastAddr.sin_port =     htons(8848);     
int nSiz = sizeof(SOCKADDR_IN);   

if(SOCKET_ERROR == sendto(m_Socket, szSend, dwSendSize,0,(struct sockaddr*)&BroadcastAddr, sizeof(BroadcastAddr)))
{
return false;
}
unsigned short* pUnBuff = (unsigned short* )szSend;
cout<<"CUDPClient::BroadCase:"<<inet_ntoa(BroadcastAddr.sin_addr)<<"-"<<"size:"<<pUnBuff[0]<<"-"<<"type:"<<pUnBuff[1]<<endl;
return true;
}client:
//Bind端口
bool CUDPClient::BindPort(std::string strBindIP, UNSHORT unBindPort)
{
m_ServerAddr.sin_family=AF_INET;
m_ServerAddr.sin_port=htons(unBindPort); ///server的监听端口
m_ServerAddr.sin_addr.s_addr=inet_addr(strBindIP.c_str()); ///server的地址

m_Socket=socket(AF_INET,SOCK_DGRAM,0);
//  if (SOCKET_ERROR == bind(m_Socket,(struct sockaddr *)&m_ServerAddr,sizeof(m_ServerAddr)))
//  {
//  return false;
//  }
return true;
}bool CUDPClient::Receive(char* szReceive, DWORD dwReceiveSize)
{
//非阻塞消息select使用
fd_set fdread;
//初始化fd_set
  FD_ZERO(&fdread);
//分配套接字句柄到相应的fd_set
FD_SET(m_Socket, &fdread);
select(0, &fdread, NULL, NULL, &m_tv);
if (FD_ISSET(m_Socket, &fdread))
{
int len = sizeof(m_ServerAddr);
if (SOCKET_ERROR == recvfrom(m_Socket, szReceive, dwReceiveSize, 0,
(struct sockaddr*)&m_ServerAddr, &len))
{
return false;
}
unsigned short* pUnBuff = (unsigned short* )szReceive;
cout<<"CUDPClient::Receive:"<<inet_ntoa(m_ServerAddr.sin_addr)<<"-"<<pUnBuff[0]<<"-"<<pUnBuff[1]<<endl;
}
return true;
}

解决方案 »

  1.   


    //udpserver主要代码:void main()
    {
    SOCKET socket1; InitWinsock();
    struct sockaddr_in local;
    struct sockaddr_in from;
    int fromlen =sizeof(from);
    local.sin_family=AF_INET;
    local.sin_port=htons(1000);             ///监听端口
    local.sin_addr.s_addr=INADDR_ANY;       ///本机 socket1=socket(AF_INET,SOCK_DGRAM,0);
    bind(socket1,(struct sockaddr*)&local,sizeof local);
    while (1)
    {
    char buffer[1024]="\0";
    printf("waiting for message from others-------------\n");
    if (recvfrom(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&from,&fromlen)!=SOCKET_ERROR)
    {
    printf("Received datagram from %s--%s\n",inet_ntoa(from.sin_addr),buffer);
    ////给cilent发信息
    sendto(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&from,fromlen); }
    Sleep(500);
    }
    closesocket(socket1);
    }//udpcilent主要代码:
    void main()
    {
    SOCKET socket1; InitWinsock();
    struct sockaddr_in server;
    int len =sizeof(server);
    server.sin_family=AF_INET;
    server.sin_port=htons(1000);                      ///server的监听端口
    server.sin_addr.s_addr=inet_addr("168.168.0.10"); ///server的地址  socket1=socket(AF_INET,SOCK_DGRAM,0);
    while (1)
    {
    char buffer[1024]="\0";
    printf("input message\n");
    scanf("%s",buffer);
    if (strcmp(buffer,"bye")==0)
    break;
    if (sendto(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&server,len)!=SOCKET_ERROR)
    {
    if (recvfrom(socket1,
                                            buffer,
                                            sizeof buffer,
                                            0,
                                            (struct sockaddr*)&server,&len) != SOCKET_ERROR)
    printf("rece from server:%s\n",buffer);
    }
    }
    closesocket(socket1);
    }
      

  2.   


    #include <WinSock2.h>
    #pragma comment(lib, "WS2_32.lib")
    #include <iostream>
    using namespace std;int _tmain(int argc, _TCHAR* argv[])
    {
    WSADATA wsaData;
    WORD wVersionRequestion = MAKEWORD(2, 2);
    if(0 != WSAStartup(wVersionRequestion, &wsaData))
    {
    cout<<"WSAStartup failed with error code:"<<GetLastError()<<endl;
    return -1;
    }
    if(2 != HIBYTE(wsaData.wVersion) || 2 != LOBYTE(wsaData.wVersion))
    {
    cout<<"Socket version not supported."<<endl;
    WSACleanup();
    return -1;
    }
    SOCKADDR_IN addr;
    SOCKADDR_IN from;
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = INADDR_ANY;
    addr.sin_port = htons(5050); from.sin_family = AF_INET;
    from.sin_addr.S_un.S_addr = INADDR_BROADCAST;
    from.sin_port = htons(5050);
    int len = sizeof(SOCKADDR); SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
    if(INVALID_SOCKET == s)
    {
    cout<<"socket failed with error code: "<<WSAGetLastError()<<endl;
    WSACleanup();
    return -1;
    } int optval = 1;
    setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&optval, sizeof(optval));
    if(SOCKET_ERROR == bind(s, (LPSOCKADDR)&addr, sizeof(SOCKADDR)))
    {
    cout<<"bind failed with error code: "<<WSAGetLastError()<<endl;
    closesocket(s);
    WSACleanup();
    return -1;
    }
    char buf[256] = {0};
    while(1)
    {
    recvfrom(s, buf, 256, 0, (LPSOCKADDR)&from, &len);
    Sleep(1000);
    cout<<buf<<endl;
    } WSACleanup();
    return 0;
    }
      

  3.   

    1、Client 需要 Bind 端口.
    2、广播分很多种,除了受限广播,还有指向子网的广播等。(INADDR_BROADCAST不是必须)
      

  4.   

    广播消息步骤:
    1。创建socket
    2. 打开socket的广播选项。
    3. 创建广播地址
    4. 开始广播