关于多播通信的疑问

paer_1 2010-11-01 04:38:34
当实现多播通信时,为什么接受方与发送方在同一台主机时,发送方发送一个消息时,接受方会接受到三个消息。而接受方与发送方在不同主机时,发送方发送一个消息时,接受方只会接受到一个消息。以下是我写的代码:
发送方:

sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(4567);
addr.sin_addr.s_addr=INADDR_BROADCAST;
SOCKET s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(INVALID_SOCKET==s)
{
printf("创建套接字失败\r\n");
getchar();
return -1;
}

BOOL bBroadCast=TRUE;
setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadCast,sizeof(bBroadCast));

printf("开始向端口4567上发送数据\r\n");
char szBuf[]="Hello everyone!\r\n";
while(true)
{
sendto(s,szBuf,strlen(szBuf),0,(const sockaddr*)&addr,sizeof(addr));
Sleep(5000);

}

closesocket(s);


接受方:

sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(4567);
addr.sin_addr.s_addr=INADDR_ANY;
SOCKET s=socket(AF_INET,SOCK_DGRAM,0);
if(INVALID_SOCKET==s)
{
printf("创建套接字失败\r\n");
getchar();
return -1;
}
if(SOCKET_ERROR==bind(s,(const sockaddr*)&addr,sizeof(addr)))
{
printf("绑定套接字失败\r\n");
getchar();
return -2;
}
printf("开始在端口4567上监听数据...\r\n");
while(true)
{
char szBuf[1024];
sockaddr_in addrRemote;
int iSize=sizeof(addrRemote);
int iLen=recvfrom(s,szBuf,strlen(szBuf),0,(sockaddr*)&addrRemote,&iSize);
if(iLen!=SOCKET_ERROR)
{
szBuf[iLen]='\0';
printf("接受到广播数据:%s\r\n",szBuf);

printf("远程地址;%s 端口:%d\r\n",
inet_ntoa(addrRemote.sin_addr),ntohs(addrRemote.sin_port));
}
}
closesocket(s);
...全文
98 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
TA_V_SFIQ_SFIQ 2010-11-02
  • 打赏
  • 举报
回复
可以试下楼上的
种菜的 2010-11-02
  • 打赏
  • 举报
回复
另外楼主用的是广播,简单一点,在接收端讲代码语句:
addr.sin_addr.s_addr=INADDR_ANY;
改为:
addr.sin_addr.s_addr = inet_addr(ip地址);
这样就只收到一个数据包。
种菜的 2010-11-02
  • 打赏
  • 举报
回复
楼主的意思很明确,多播和广播只适合于udp协议,之所以你收到3个包是因为广播会向每个接口发送数据包,而你的机器上有至少3个网络接口,一个是无线,一个是有线,还有一个是虚拟机的,甚至有多个市虚拟机网络接口,这种情况楼主可以这样做:
一种情况是: 不论是多播还是广播主要在接收端指定ip地址,只从该ip上接收数据,这样就只会接到一个数据包,百分之百成功,我的聊天程序就是这么干的。
另外一种情况是:如果楼主用的是多播,那么在接收端,将要用来接收发送数据包的网卡接口加入多播地址,这样的话,数据包发送时只会通过这个接口向那些加入了多播地址的网络接口发送数据,其它接口是收不到的。这些我以前花了1个上午4个小时都验证过,不是乱说啊,百分之百成功的。
另外建议楼主看看unix网络编程这本书的多播和广播那几章,讲的非常清楚,挺不错的。
ouyh12345 2010-11-02
  • 打赏
  • 举报
回复
需要在socket层上再定义一层协议
因为有些通知可以直接抛弃
m_tornado 2010-11-01
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 paer_1 的回复:]

怎么设置回环?
[/Quote]
setsockopt()里有设置~
paer_1 2010-11-01
  • 打赏
  • 举报
回复
这个程序基于UDP广播通信的,现在的问题是发送方与接收方在同一主机时,如何做到接收方只收到一次消息?
paer_1 2010-11-01
  • 打赏
  • 举报
回复
怎么设置回环?
ouyh12345 2010-11-01
  • 打赏
  • 举报
回复
有没有设置回环?

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧