拿来即用的组播发送接收程序

简介: 拿来即用的组播发送接收程序

前情提要: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;
}
相关文章
|
网络架构
udp的简单整理
udp的简单整理
484 0
|
2月前
|
传感器 人工智能 机器人
具身智能9大开源工具全景解析:人形机器人开发必备指南
本文旨在对具身智能、人形机器人、协作机器人、AI机器人、端到端AI系统、AI Agent、AI Agentic、空间智能或世界模型等前沿领域中具有重要影响力的开源软件产品或工具进行深入分析,重点聚焦于支持这些先进AI能力实现的工具、平台和框架。
690 7
|
7月前
|
网络协议 开发者 Python
Socket如何实现客户端和服务器间的通信
通过上述示例,展示了如何使用Python的Socket模块实现基本的客户端和服务器间的通信。Socket提供了一种简单且强大的方式来建立和管理网络连接,适用于各种网络编程应用。理解和掌握Socket编程,可以帮助开发者构建高效、稳定的网络应用程序。
322 10
|
编解码 算法 网络协议
流量控制--5.Classless Queuing Disciplines (qdiscs)
流量控制--5.Classless Queuing Disciplines (qdiscs)
223 4
|
10月前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
709 6
|
算法 算法框架/工具 计算机视觉
Stable diffusion采样器详解
在我们使用SD web UI的过程中,有很多采样器可以选择,那么什么是采样器?它们是如何工作的?它们之间有什么区别?你应该使用哪一个?这篇文章将会给你想要的答案。
Stable diffusion采样器详解
|
9月前
|
Java 应用服务中间件 Spring
SpringBoot 响应请求是串行还是并行?
Spring Boot 在默认情况下通过 Servlet 容器的线程池实现并行处理 HTTP 请求。通过适当的线程池配置,可以进一步优化并发性能。此外,Spring Boot 提供了异步处理机制(如使用 `@Async` 注解)和反应式编程模型(Spring WebFlux),使得应用能够处理更高的并发负载。在具体项目中,可以根据需求选择合适的处理模型,以充分利用 Spring Boot 的并发处理能力。
252 21
|
移动开发 网络协议 Linux
Linux系统中查看路由表的命令(ip route)
Linux系统中查看路由表的命令(ip route)
1260 0
|
存储 程序员 定位技术
程序员必知:地图投影与ArcGIS坐标系转换
程序员必知:地图投影与ArcGIS坐标系转换
298 0

热门文章

最新文章