组播和广播
上一篇 / 下一篇 2007-07-09 20:07:28 / 个人分类:c++
IP组播地址用于标识一个IP组播组。IANA把D类地址空间分配给IP组播,范围从224.0.0.0到239.255.255.255,IP组播地址前四位均为1110。
从224.0.0.0至224.0.0.255被IANA保留为网络协议使用。例如:244.0.0.1全主机组244.0.0.2全多播路由器组244.0.0.3全DVMRP路由器组244.0.0.5全OSPF路由器组。在这一范围的多播包不会被转发出本地网络,也不会考虑多播包的TTL值。
地址从239.0.0.0至239.255.255.255作为管理范围地址,保留为私有内部域使用。
如下图所示,以太网和FDDI的MAC地址01:00:5E:00:00:00到01:00:5E:

这是我的一段代码,但是不起作用!
SOCKET s;
struct ip_mreq ipmr;
struct sockaddr_in local,from;
char recvbuf[2480];
int len=sizeof(struct sockaddr_in);
long ret;
s=socket(AF_INET,SOCK_DGRAM,0);
local.sin_family=AF_INET;
local.sin_addr.s_addr=htonl(INADDR_ANY);
local.sin_port=htons(5520);
ipmr.imr_multiaddr.s_addr=inet_addr("224.2.223.193");
ipmr.imr_interface.s_addr=htonl(INADDR_ANY);
bind(s,(SOCKADDR *)&local,sizeof(local));
if (setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char
*)&ipmr,sizeof(ipmr))==SOCKET_ERROR) {
TRACE("SetSocketOpt失败\n");
return;
}
else {
TRACE("设置组播成功\n");
}
while (1) {
if ((ret=recvfrom(s,recvbuf,2480,0,(struct sockaddr
*)&from,&len))==SOCKET_ERROR) {
TRACE("recvfrom failed\n");
}
else {
TRACE("TestSocket---------%s,length=%d\n",inet_ntoa(from.sin_addr),ret);
}
}问题点数:100、回复次数:3Top
1楼xuying()回复于2002-06-12 10:29:42得分60
组播不需要什么特殊的设置。下面是的代码在win2k 局域网环境下试验通过:
//发送方程序 sender.c
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#define BUFFSIZE 2048
#define IP_ADDR
"224.8.8.1"
#define DEST_PORT
8888
int main(int argc,char *argv[])
{
int sockfd;
struct sockaddr_in addr;
char szError[100];
char buf[] = "Hello, World!";
int ttl = 255 ; // Arbitrary
TTL value.
WSADATA WSAData;
WORD wVersionRequested;
wVersionRequested =
MAKEWORD(2, 2);
if (WSAStartup
(wVersionRequested , &WSAData) != 0)
{
printf
("recver:Initialize Winsock error!");
exit(1);
}
if (LOBYTE(WSAData.wVersion)
!= 2 || HIBYTE(WSAData.wVersion) != 2
) {
WSACleanup(
);
printf
("setsockopt failed! Error: %d", WSAGetLastError
());
exit(1);
}
addr.sin_family = AF_INET;
addr.sin_port =
htons(DEST_PORT);
addr.sin_addr.s_addr =
inet_addr(IP_ADDR);
if
((sockfd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
printf("sender:new a socket error!\n");
exit(1);
}
if(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
(char *)&ttl, sizeof(ttl))!=0)
{
printf("error setsockopt IP_MULTICAST_TTL\n");
exit(1);
}
/*
if (bind(sockfd,(struct
sockaddr *)&recver_addr,sizeof(recver_addr)) < 0)
{
closesocket(sockfd);
printf("recver:bind socket error!\n");
exit(1);
}
*/
if (sendto (sockfd, buf,
sizeof(buf) , 0, (struct sockaddr
*)&addr, sizeof(addr))
== SOCKET_ERROR)
{
wsprintf (szError,
TEXT("sendto failed! Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError,
TEXT("Error"), MB_OK);
closesocket (sockfd);
return FALSE;
}
else
{
printf("send ok\n");
}
// Close Sock.
closesocket (sockfd);
WSACleanup ();
return 0;
}
// 接收方程序 receivers.c
//#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#define BUFFSIZE 2048
#define RECV_IP_ADDR
"224.8.8.1"
#define DEST_PORT
8888
int main(int argc,char *argv[])
{
int sockfd;
int sock_reuse = 1;
struct ip_mreq multicast;
struct sockaddr_in
recver_addr;
char szError[100];
int index = 0,
// Integer
index
iRecvLen;
// Length
of recv_sin
char szMessageA[1024*320];
// ASCII string
TCHAR szMessageW[1024*320];
//
Unicode string
WSADATA WSAData;
WORD wVersionRequested;
wVersionRequested =
MAKEWORD(2, 2);
if (WSAStartup
(wVersionRequested , &WSAData) != 0)
{
printf
("recver:Initialize Winsock error!");
exit(1);
}
if (LOBYTE(WSAData.wVersion)
!= 2 || HIBYTE(WSAData.wVersion) != 2
) {
WSACleanup(
);
printf
("setsockopt failed! Error: %d",
WSAGetLastError ());
exit(1);
}
multicast.imr_multiaddr.s_addr =
inet_addr(RECV_IP_ADDR);
multicast.imr_interface.s_addr =
htonl(INADDR_ANY);
recver_addr.sin_family =
AF_INET;
recver_addr.sin_port =
htons(DEST_PORT);
recver_addr.sin_addr.s_addr =
INADDR_ANY;
if
((sockfd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
printf("recver:new a socket error!\n");
exit(1);
}
if (setsockopt(sockfd,
SOL_SOCKET, SO_REUSEADDR, (char *)&sock_reuse,
sizeof(sock_reuse)) < 0) {
printf("recver : socket options set
error");
exit(1);
}
if (bind(sockfd,(struct
sockaddr *)&recver_addr,sizeof(recver_addr)) < 0)
{
closesocket(sockfd);
printf("recver:bind socket error!\n");
exit(1);
}
if
(setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char
*)&multicast,sizeof(multicast)) < 0 ) {
sprintf
(szError, TEXT("setsockopt failed! Error:
%d"), WSAGetLastError ());
printf("%s\n", szError);
closesocket(sockfd);
exit(1);
}
printf("Receive on %s:%d\n",
RECV_IP_ADDR, DEST_PORT);
iRecvLen = sizeof (recver_addr);
memset(szMessageA, 0, sizeof(szMessageA));
// Receive data from the
multicasting group server.
if (recvfrom (sockfd,
szMessageA,
sizeof(szMessageA),
0,
(struct sockaddr FAR
*) &recver_addr,
&iRecvLen) ==
SOCKET_ERROR)
{
wsprintf (szError,
TEXT("recvfrom failed! Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError,
TEXT("Error"), MB_OK);
closesocket (sockfd);
return FALSE;
}
else
{
// Convert the ASCII
string to a Unicode string.
for (index = 0;
index <= sizeof (szMessageA); index++)
szMessageW[index] =
szMessageA[index];
MessageBox (NULL, szMessageW,
TEXT("Info"), MB_OK);
}
// Disable receiving on Sock
before closing it.
shutdown (sockfd, 0x00);
// Close Sock.
closesocket (sockfd);
WSACleanup ();
return 0;
}
Top
2楼djhdu(小火花)回复于2002-06-12 10:45:16得分0
哦,是不是只要发送给这个组播地址,其它组播接收程序就都可以收到?Top
3楼xuying()回复于2002-06-12 11:02:33得分40
发送程序很简单,只要给组播地址发就可以了。
接收的时候要先加入组播组。就是下面这一段程序:
if (setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char
*)&multicast,sizeof(multicast)) < 0 ) {
sprintf
(szError, TEXT("setsockopt failed! Error:
%d"), WSAGetLastError ());
printf("%s\n", szError);
closesocket(sockfd);
exit(1);
Top
4楼xuying()回复于2002-06-12 11:03:34得分0
发送程序很简单,只要给组播地址发就可以了。
接收的时候要先加入组播组。就是下面这一段程序:
if (setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char
*)&multicast,sizeof(multicast)) < 0 ) {
sprintf
(szError, TEXT("setsockopt failed! Error:
%d"), WSAGetLastError ());
printf("%s\n", szError);
closesocket(sockfd);
exit(1);
Linux网络编程一步一步学-UDP方式广播通讯
关键词:broadcast UDP 广播 recvfrom sendto
和前一篇文章<Linux网络编程一步一步学-UDP方式点对点通讯>一样,只是在客户端源代码里加一行设置socket属性为广播方式即可。
需要加的一句是:
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
源代码变成下面的:
|
编译这个程序用下列命令:
gcc -Wall broadc-udpclient.c -o client
运行程序用下列命令:
./client 192.168.0.255 7838
就会往192.168.0网络内所有主机发消息。
其它主机如果运行了服务端:
./server自己的IP地址7838
则都会收到上述客户端发的消息了。
TAG:
标题搜索
我的存档
数据统计
- 访问量: 81837
- 日志数: 105
- 图片数: 2
- 文件数: 5
- 书签数: 46
- 建立时间: 2006-09-20
- 更新时间: 2008-08-27
