前情提要:windows下程序,客户端服务端是同一个程序(不区分客户端服务端),在接收的程序中注释掉发送代码即可。
#include <iostream>
#include <winsock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 512
using namespace std;
int main()
{
//Declare and initialize variables
WSADATA wsaData = { 0 };
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
wprintf(L"WSAStartup failed: %d\n", iResult);
return -1;
}
//创建socket
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET) {
wprintf(L"socket function failed with error = %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
//设置组播选项
int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&opt, sizeof(opt));
//IP_MULTICAST_LOOP选项默认为1,表示可以收到自己发的数据,这里设置为0不收自己的数据
opt = 0;
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&opt, sizeof(opt));
struct sockaddr_in local_addr;
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(12345);
if (bind(sock, (struct sockaddr*)&local_addr, sizeof(local_addr)) == SOCKET_ERROR) {
// 绑定失败
return -1;
}
//加入组播组
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr("239.0.0.1"); // 组播地址
mreq.imr_interface.s_addr = htonl(INADDR_ANY); // 本地地址
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) < 0) {
// 加入组播组失败
return -1;
}
//向组播地址发送数据
struct sockaddr_in group_addr;
memset(&group_addr, 0, sizeof(group_addr));
group_addr.sin_family = AF_INET;
group_addr.sin_addr.s_addr = inet_addr("239.0.0.1"); // 组播地址
group_addr.sin_port = htons(12345);
//*******接受的程序中,注释掉下面的发送即可*****
char buf[1024];
strcpy_s(buf, "Hello, World!");
int n = sendto(sock, buf, strlen(buf), 0, (struct sockaddr*)&group_addr, sizeof(group_addr));
if (n < 0) {
// 发送失败
return -1;
}
memset(buf, '\0', 1024);
struct sockaddr_in sender_addr;
int addr_len = sizeof(sender_addr);
n = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&sender_addr, &addr_len);
if (n < 0) {
return -1;
}
printf("recv: %s\n", buf);
// 处理接收到的数据
closesocket(sock);
WSACleanup();
system("pause");
return 0;
}