前情提要: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; }