简单的组播例子

组播,广播,单播比较常用。

假设有一个组播地址,A加入该组播地址,那么B,C,D...(B,C,D加没加入该组播地址没有关系)向该组播地址发送数据,A均能收到。

B端(发送端)代码:

DWORD CDlgBMulticast::ThreadProc()
{
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2,2), &wsaData);

	m_hSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);

	// 构建组播地址
	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(MULTICAST_IPADDRESS);
	addr.sin_port = htons(MULTICAST_PORT);

	char *message="Hello, World!";
	while (1) {
		// 向组播地址发送数据
		int nSend = sendto(m_hSocket, message, strlen(message), 0, (struct sockaddr *) &addr, sizeof(addr));
		if( nSend == SOCKET_ERROR ) {
			int nErr = WSAGetLastError();
			LogPrintf(_T("WSAErrorCode: %d\n"), nErr);
		}

		Sleep(1);
	}

	WSACleanup();

	return TRUE;
}



/

A端(接收端)代码

DWORD CDlgAMulticast::ThreadProc()
{
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2,2), &wsaData);

	int nRet;
	m_hSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);

	BOOL yes = TRUE;
	nRet = setsockopt(m_hSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes) );
	if(nRet == SOCKET_ERROR) {
		return 0;
	}

	// 本地地址结构
	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(MULTICAST_PORT);

	// 将套接字绑定到本地地址结构
	bind(m_hSocket, (struct sockaddr *) &addr, sizeof(addr));

	// 加入组播地址
	ip_mreq mreq;
	mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_IPADDRESS);
	mreq.imr_interface.s_addr = htonl(INADDR_ANY);
	setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq));

	int len = sizeof(addr);
	char msgbuf[16] ={0};
	// 循环从组播地址接收数据
	while (1) {
		int nbytes = recvfrom(m_hSocket, msgbuf, sizeof(msgbuf), 0, (struct sockaddr *) &addr, (socklen_t *)&len);

		int a=2;
	}

	WSACleanup();

	return TRUE;
}



这里我本来打算用m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);来构建套接字,

但是无法接受到消息,可见,组播必须使用数据包套接字。。。






SOCK_STREAM套接口(流套接口)的性质

1、不保留任何消息的边界

      举一个例子:本地主机通过两次独立的write(2)调用向远程主机发送数据,第一次本地进程写入25字节的数据,并通过套接口发送到远程进程,第二次再写入30字节的数据发往远程进程,总共55字节的数据,而远程进程从套接口接收数据时,将消息作为一个完整的单元来接收,或是通过若干次独立的读操作来将数据取走,即接受端并不知道这55字节的数据是分25字节和30字节两次来发送的。

2、有序性  可以保证接受的数据字节与发送是顺序完全一致(意味着通信之前必须建立一个连接)

3、无错性   可以保证接受的数据在接收端被无错的接受。如果有错误发生,在尝试完所有的错误恢复措施后仍无法消除错误,流套接口就会报告错误。所进行的错误恢复措施尝试是完全自动的,不需编程者的指导。


SOCK_DGRAM套接口

特征:

1、分组在发送后,可能无序地到达接收端

2、分组可能丢失。如果发生丢失,不会采取任何补救的措施,而且接受端也不必知道有分租丢失。

3、数据报分组有尺寸大小的限制,如果超出限制,在某些路由器和节点上就无法传送。

4、分组是在不建立连接的情况下被发送到远程进程的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值