UDP如何接收广播消息

时间:2022-12-15 16:52:07
在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;
}

7 个解决方案

#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


 顶!!!

#3


1楼,没有看到和广播相关的内容呀!

#4



#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;
}

#5


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

#6


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

#7


知道原因了,客户端要绑定端口后才可以接收广播!

#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


 顶!!!

#3


1楼,没有看到和广播相关的内容呀!

#4



#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;
}

#5


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

#6


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

#7


知道原因了,客户端要绑定端口后才可以接收广播!