关于在英特网组播问题.......很急在线等

tanggt006 2007-09-23 12:18:28
写了两个简单的控制台程序:Sender和Receiver,用于发送接收组播消息。
代码如下:
------------------------------------Sender.c
#include "stdafx.h"

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>

#define MCASTADDR "224.0.1.0" //本例使用的多播组地址。
#define MCASTPORT 6701 //本地端口号。
#define BUFSIZE 1024 //发送数据缓冲大小。

#pragma comment(lib, "Ws2_32.lib")

int main(int argc, char* argv[])
{
struct sockaddr_in remote;
SOCKET sock,sockM;
TCHAR sendbuf[BUFSIZE];
int len = sizeof( struct sockaddr_in);

// 初始化WinSock2.2
WSADATA wsd;
if( WSAStartup( MAKEWORD(2,2),&wsd) != 0 )
{
printf("WSAStartup() failed\n");
return -1;
}

if((sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("socket failed with:%d\n",WSAGetLastError());
WSACleanup();
return -1;
}

// 加入多播组
remote.sin_family = AF_INET;
remote.sin_port = htons(MCASTPORT);
remote.sin_addr.s_addr = inet_addr( MCASTADDR );
if(( sockM = WSAJoinLeaf(sock,(SOCKADDR*)&remote,sizeof(remote),NULL,NULL,NULL,NULL,
JL_BOTH)) == INVALID_SOCKET)
{
printf("WSAJoinLeaf() failed:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}

// 发送多播数据,当用户在控制台输入"QUIT"时退出。
while(1)
{
printf("SEND : ");
scanf("%s",sendbuf);
if( sendto(sockM,(char*)sendbuf,strlen(sendbuf),0,(struct
sockaddr*)&remote,sizeof(remote))==SOCKET_ERROR)
{
printf("sendto failed with: %d\n",WSAGetLastError());
closesocket(sockM);
closesocket(sock);
WSACleanup();
return -1;
}
if(strcmp(sendbuf,"QUIT")==0 || strcmp(sendbuf, "quit")==0)
break;
Sleep(500);
}

closesocket(sockM);
closesocket(sock);
WSACleanup();

return 0;
}


-----------------------------------------Receiver.c
#include "stdafx.h"

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>

#define MCASTADDR "224.0.1.0" //本例使用的多播组地址。
#define MCASTPORT 6701 //绑定的本地端口号。
#define BUFSIZE 1024 //接收数据缓冲大小。

#pragma comment(lib, "Ws2_32.lib")

int main(int argc, char* argv[])
{
struct sockaddr_in local;
struct sockaddr_in remote;
struct sockaddr_in from;
SOCKET sock,sockM;
TCHAR recvbuf[BUFSIZE];
/*struct ip_mreq mcast; // Winsock1.0 */

int len = sizeof(struct sockaddr_in);
int ret;
//初始化WinSock2.2
WSADATA wsd;
if( WSAStartup( MAKEWORD(2,2),&wsd) != 0 )
{
printf("WSAStartup() failed\n");
return -1;
}


/*创建一个SOCK_DGRAM类型的SOCKET
其中,WSA_FLAG_MULTIPOINT_C_LEAF表示IP多播在控制面层上属于"无根"类型;
WSA_FLAG_MULTIPOINT_D_LEAF表示IP多播在数据面层上属于"无根",有关控制面层和
数据面层有关概念请参阅MSDN说明。*/
if((sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,
WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("socket failed with:%d\n",WSAGetLastError());
WSACleanup();
return -1;
}

//将sock绑定到本机某端口上。
local.sin_family = AF_INET;
local.sin_port = htons(MCASTPORT);
local.sin_addr.s_addr = htonl(INADDR_ANY);
if( bind(sock,(struct sockaddr*)&local,sizeof(local)) == SOCKET_ERROR )
{
printf( "bind failed with:%d \n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}

//加入多播组
remote.sin_family = AF_INET;
remote.sin_port = htons(MCASTPORT);
remote.sin_addr.s_addr = inet_addr( MCASTADDR );

/* Winsock1.0 */
/*
mcast.imr_multiaddr.s_addr = inet_addr(MCASTADDR);
mcast.imr_interface.s_addr = INADDR_ANY;
if(
setsockopt(sockM,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast))
== SOCKET_ERROR)
{
printf("setsockopt(IP_ADD_MEMBERSHIP) failed:%d\n",WSAGetLastError());
closesocket(sockM);
 WSACleanup();
 return -1;
}
*/
/* Winsock2.0*/
if(( sockM = WSAJoinLeaf(sock,(SOCKADDR*)&remote,sizeof(remote),NULL,NULL,NULL,NULL,JL_BOTH)) == INVALID_SOCKET)
{
printf("WSAJoinLeaf() failed:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}

//接收多播数据,当接收到的数据为"QUIT"时退出。
while(1)
{
if(( ret = recvfrom(sock,recvbuf,BUFSIZE,0,(struct sockaddr*)&from,&len)) == SOCKET_ERROR)
{
printf("recvfrom failed with:%d\n",WSAGetLastError());
closesocket(sockM);
closesocket(sock);
WSACleanup();
return -1;
}
if( strcmp(recvbuf,"QUIT") == 0 )
break;
else
{
recvbuf[ret] = '\0';
printf("RECV:' %s ' FROM <%s> \n",recvbuf,inet_ntoa(from.sin_addr));
}
}

closesocket(sockM);
closesocket(sock);
WSACleanup();

return 0;
}


请问一下使用预留多播地址为224.0.1.0~238.255.255.255,可用于全球范围(如Internet)或网络协议 为什么不能在英特网上组播呢?

请知道的高手指教
...全文
166 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
tom_happy 2008-07-25
  • 打赏
  • 举报
回复
up 我也想知道
csl435 2007-11-15
  • 打赏
  • 举报
回复
关注此问题,也是我需要解决但不太了解的问题,我看的资料说是可以通过IGMP协议支持可以实现组播,如果INTERNET不能组播那,视频会议软件,视频网站没有用组播吗?难道是一个一个传的?或者用P2P?关注中..
vocanicy 2007-09-23
  • 打赏
  • 举报
回复
加入同一组播地址的计算机之间的路由器必须都支持组播,并且组播的“距离”受到TTL值限制



广域网的组播还是一个待解决的问题。


设想一个例子,
假设你加入了多播组224.0.1.x,你想通过Internet组播,这就要求TTL值无穷大。离你最近的路由器将你加入x组的信息发送给相邻的路由器,下一路由器又将信息继续传递出去。由于TTL的无穷大这个信息将全球范围内传递,结果是你导致了全球网络的瘫痪。
tanggt006 2007-09-23
  • 打赏
  • 举报
回复
给自己顶一下
tanggt006 2007-09-23
  • 打赏
  • 举报
回复
WO,WO 我这苦命的孩子,要如何决这个问题,QQ、MSN是如何实现群发的呢,有没有相关参考资料呢?
tanggt006 2007-09-23
  • 打赏
  • 举报
回复
谢谢sunnyroad与vocanicy(刺客)的回答,我看TCP/IP的协议答案是一样的,关键是我现在实在太急用,不然方法很多种。
草鞋工 2007-09-23
  • 打赏
  • 举报
回复
在Internet上不能使用,路由器一般都不会允许的,你还是想其他办法好了.
Avoid 2007-09-23
  • 打赏
  • 举报
回复
Internet组播...

哈哈,有点常识好不好。。。
vocanicy 2007-09-23
  • 打赏
  • 举报
回复
设置组播传播范围(TTL)的Socket API

WSAIoctl(hSocket, SIO_MULTICAST_SCOPE,
&nTTL, sizeof(nTTL),
NULL, 0,
(PULONG)&cbRet,
NULL, NULL);
vocanicy 2007-09-23
  • 打赏
  • 举报
回复
特此说明一下,上面的例子纯属虚构,不要误导了小朋友

想了解组播协议可以参见《TCP/IP详解 卷1:协议》

18,356

社区成员

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

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