UDP組播實現

服務端(數據發送端)

////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <WINSOCK.H>
#include <stdio.h>
#define HELLO_PORT  7905    
#define HELLO_GROUP "228.4.5.6"    
#pragma comment(lib, "WSOCK32.lib")


struct sockaddr_in addr;
int fd, cnt;
DWORD __stdcall UdpSendThread(LPVOID param)
{
	/* set up destination address */
	char *message = "Hello, World!";
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(HELLO_GROUP);
	addr.sin_port = htons(HELLO_PORT);
	/* now just sendto() our destination! */
	while (1)
	{
		if (sendto(fd, message, strlen(message), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
		{
			perror("sendto");
			exit(1);
		}
		printf("Send %s\n", message);
		Sleep(1000);
	}
}

int main(int argc, char *argv[])
{
	WSADATA     wsaData;
	WORD wVersionRequested;
	wVersionRequested = MAKEWORD(2, 2);
	// Initialize Windows socket library
	WSAStartup(0x0202, &wsaData);	

	/* create what looks like an ordinary UDP socket */
	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		perror("socket");
		exit(1);
	}

	HANDLE hRecvThread = CreateThread(NULL, 0, UdpSendThread, NULL, 0, NULL);
	getchar();

	return 0;
}

客戶端(數據接收端)

//////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <WINSOCK.H>
#include <stdio.h>
#define HELLO_PORT  7905    
#define HELLO_GROUP "228.4.5.6"    
#pragma comment(lib, "WSOCK32.lib")

SOCKET client;

DWORD __stdcall UdpRecvThread(LPVOID param)
{
	//接收數據
	char recvbuf[1024];  //回頭注意重新設定緩衝區大小
	int n;
	DWORD dwWrite;    //DWORD在windows下常用來保存地址(或者存放指針)
	BOOL bRet;
	int len = sizeof(sockaddr_in);
	sockaddr_in serveraddress;
	while (1)
	{
		ZeroMemory(recvbuf, 1024);
		n = recvfrom(client, recvbuf, sizeof(recvbuf), 0, (sockaddr*)&serveraddress, &len);
		if (n == SOCKET_ERROR)
		{
			printf("recvfrom error:%d\n", WSAGetLastError());
			printf("接收數據錯誤!\n");
		}
		else
		{
			printf("收到數據:%s\r\n", recvbuf);
		}
		Sleep(1000);
	}
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{ 
	//初始化套接字
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		printf("初始化套接字失敗!\n");
		return -1;
	}
	printf("初始化套接字成功!\n");

	//建立客戶端SOCKET
	client = socket(AF_INET, SOCK_DGRAM, 0);
	if (client == INVALID_SOCKET)
	{
		printf("建立客戶端套接字失敗; %d\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}
	printf("建立客戶端套接字成功!\n");

	//socket綁定(注意:這裏綁定的端口一定要和發送端的發送端口一致)
	sockaddr_in bindaddr = { 0 };
	bindaddr.sin_family = AF_INET;
	bindaddr.sin_port = htons(HELLO_PORT);
	bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	if (bind(client, (struct sockaddr*)&bindaddr, sizeof(bindaddr)) < 0)
	{
		perror("bind");
		exit(1);
	}

	//加入組播
	struct ip_mreq mreq;
	memset(&mreq, 0, sizeof(struct ip_mreq));
	mreq.imr_multiaddr.s_addr = inet_addr(HELLO_GROUP);    //組播源地址
	mreq.imr_interface.s_addr = INADDR_ANY;       //本地地址
	int m = setsockopt(client, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&mreq, sizeof(mreq));
	if (m == SOCKET_ERROR)
	{
		perror("setsockopt");
		return -1;
	}

	HANDLE hRecvThread = CreateThread(NULL, 0, UdpRecvThread, NULL, 0, NULL);

	getchar();
	closesocket(client);
	WSACleanup();
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章