Windows下可靠多播协议VC实现。。。

网上以及书上很多地方说道可靠多播,看后也明白点,但是很模糊。。。


也看了《 Windows网络编程》对照下,终于实现了。。


服务端部分代码:

// DlgReliableMulticast.cpp : implementation file
//

#include "stdafx.h"
#include "TestServer.h"
#include "DlgReliableMulticast.h"


// CDlgReliableMulticast dialog

IMPLEMENT_DYNAMIC(CDlgReliableMulticast, CDialog)

CDlgReliableMulticast::CDlgReliableMulticast(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgReliableMulticast::IDD, pParent)
{
	m_hWorkThread = NULL;
}

CDlgReliableMulticast::~CDlgReliableMulticast()
{
}

void CDlgReliableMulticast::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CDlgReliableMulticast, CDialog)
END_MESSAGE_MAP()


// CDlgReliableMulticast message handlers
BOOL CDlgReliableMulticast::OnInitDialog() {
	CDialog::OnInitDialog();

	InitNetwork();
	return TRUE;
}

void CDlgReliableMulticast::InitNetwork() {
	// Create thread
	DWORD dwThreadID = 0;
	m_hWorkThread = CreateThread(NULL, 0, NetworkThreadProc, this, CREATE_SUSPENDED, &dwThreadID);
	if (NULL == m_hWorkThread) { return; }

	SetThreadPriority(m_hWorkThread, THREAD_PRIORITY_HIGHEST);
	ResumeThread(m_hWorkThread);
}

DWORD WINAPI CDlgReliableMulticast::NetworkThreadProc(LPVOID lpvParam) {
	CDlgReliableMulticast *pThis = (CDlgReliableMulticast *)lpvParam;
	return pThis->ThreadProc();
}

DWORD CDlgReliableMulticast::ThreadProc()
{
	
	m_dwLocalIpAddr = ...;// 本机IP
	

	WSADATA wsaData;
	WSAStartup(MAKEWORD(2,2), &wsaData);

	m_hSocket = socket(AF_INET, SOCK_RDM, IPPROTO_RM);
	if( m_hSocket == INVALID_SOCKET ) {
		int nErr = WSAGetLastError();
		LogPrintf(_T("socket: ErrorCode: %d\n"), nErr);
	}

	// 绑定到INADDR_ANY
	sockaddr_in localAddr;
	memset(&localAddr, 0, sizeof(localAddr));
	localAddr.sin_family = AF_INET;
	localAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	localAddr.sin_port = htons(0);
	int nRet = bind(m_hSocket, (sockaddr*)&localAddr, sizeof(localAddr));
	if( nRet == SOCKET_ERROR ) {
		int nErr = WSAGetLastError();
		LogPrintf(_T("bind: ErrorCode: %d\n"), nErr);
	}

	// 设置外出接口
	ULONG ulSend = m_dwLocalIpAddr;
	nRet = setsockopt(m_hSocket, IPPROTO_RM, RM_SET_SEND_IF, (char*)&ulSend, sizeof(ulSend));
	if( nRet == SOCKET_ERROR ) {
		int nErr = WSAGetLastError();
		LogPrintf(_T("setsockopt: ErrorCode: %d\n"), nErr);
	}

	// 将套接字连接到将多播组地址
	sockaddr_in addrMulti;
	memset(&addrMulti, 0, sizeof(addrMulti));
	addrMulti.sin_family = AF_INET;
	addrMulti.sin_addr.S_un.S_addr = inet_addr("234.5.6.7");
	addrMulti.sin_port = htons(5150);
	nRet = connect(m_hSocket, (sockaddr*)&addrMulti, sizeof(addrMulti));
	if( nRet == SOCKET_ERROR ) {
		int nErr = WSAGetLastError();
		LogPrintf(_T("setsockopt: ErrorCode: %d\n"), nErr);
	}

	char buf[1024]={0};
	buf[0] = 'a';
	buf[1] = 'v';
	buf[2] = 'd';
	buf[3] = 'r';
	while(1) {
		nRet = send(m_hSocket, buf, sizeof(buf), 0);
		if( nRet == SOCKET_ERROR ) {
			int nErr = WSAGetLastError();
			LogPrintf(_T("send: ErrorCode: %d\n"), nErr);
		}
	}

	WSACleanup();
	return 0;
}



客户端:

// DlgReliableMulticast.cpp : implementation file
//

#include "stdafx.h"
#include "TestClient.h"
#include "DlgReliableMulticast.h"


// CDlgReliableMulticast dialog

IMPLEMENT_DYNAMIC(CDlgReliableMulticast, CDialog)

CDlgReliableMulticast::CDlgReliableMulticast(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgReliableMulticast::IDD, pParent)
{
	m_hWorkThread = NULL;
}

CDlgReliableMulticast::~CDlgReliableMulticast()
{
}

void CDlgReliableMulticast::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CDlgReliableMulticast, CDialog)
END_MESSAGE_MAP()


// CDlgReliableMulticast message handlers
BOOL CDlgReliableMulticast::OnInitDialog() {
	CDialog::OnInitDialog();

	InitNetwork();
	return TRUE;
}

void CDlgReliableMulticast::InitNetwork() {
	// Create thread
	DWORD dwThreadID = 0;
	m_hWorkThread = CreateThread(NULL, 0, NetworkThreadProc, this, CREATE_SUSPENDED, &dwThreadID);
	if (NULL == m_hWorkThread) { return; }

	SetThreadPriority(m_hWorkThread, THREAD_PRIORITY_HIGHEST);
	ResumeThread(m_hWorkThread);
}

DWORD WINAPI CDlgReliableMulticast::NetworkThreadProc(LPVOID lpvParam) {
	CDlgReliableMulticast *pThis = (CDlgReliableMulticast *)lpvParam;
	return pThis->ThreadProc();
}

DWORD CDlgReliableMulticast::ThreadProc()
{
	
	m_dwLocalIpAddr = ...; // 本机IP
	

	WSADATA wsaData;
	WSAStartup(MAKEWORD(2,2), &wsaData);

	m_hSocket = socket(AF_INET, SOCK_RDM, IPPROTO_RM);
	if( m_hSocket == INVALID_SOCKET ) {
		int nErr = WSAGetLastError();
		LogPrintf(_T("socket: ErrorCode: %d\n"), nErr);
	}

	sockaddr_in addrMulti;
	memset(&addrMulti, 0, sizeof(addrMulti));
	addrMulti.sin_family = AF_INET;
	addrMulti.sin_addr.S_un.S_addr = inet_addr("234.5.6.7");
	addrMulti.sin_port = htons(5150);
	int nRet = bind(m_hSocket, (sockaddr*)&addrMulti, sizeof(addrMulti));
	if( nRet == SOCKET_ERROR ) {
		int nErr = WSAGetLastError();
		LogPrintf(_T("bind: ErrorCode: %d\n"), nErr);
	}

	nRet = listen(m_hSocket, 10);
	if( nRet == SOCKET_ERROR ) {
		int nErr = WSAGetLastError();
		LogPrintf(_T("listen: ErrorCode: %d\n"), nErr);
	}

	ULONG localIpAddress = m_dwLocalIpAddr;
	nRet = setsockopt(m_hSocket, IPPROTO_RM, RM_ADD_RECEIVE_IF, (char*)&localIpAddress, sizeof(localIpAddress));
	if( nRet == SOCKET_ERROR ) {
		int nErr = WSAGetLastError();
		LogPrintf(_T("listen: ErrorCode: %d\n"), nErr);
	}

	sockaddr_in addrFrom;
	int fromLen = sizeof(addrFrom);
	SOCKET ns = accept(m_hSocket, (sockaddr*)&addrFrom, &fromLen);
	if( ns == INVALID_SOCKET ) {
		int nErr = WSAGetLastError();
		LogPrintf(_T("accept: ErrorCode: %d\n"), nErr);
	}
	closesocket(m_hSocket);

	// 
	while(1) {
		char buf[1024];
		int rc = recv(ns, buf, sizeof(buf), 0);
		if( rc == SOCKET_ERROR ) {
			int nErr = WSAGetLastError();
			LogPrintf(_T("recv : ErrorCode: %d\n"), nErr);
		} else {
			// 
		}
	}
	closesocket(ns);

	WSACleanup();

	return 0;
}




同时你必须在本机安装可靠多播协议,如下:





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值