linux之UDP之组播通信

#include "socketudp.h"

#include <iostream>

#include <stdio.h>

#include <sys/socket.h>

#include <unistd.h>

#include <sys/types.h>

#include <netdb.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <string.h>

extern "C"{

#include "iniparser.h"

}

using namespace std;

int socket_udp_Handle;

pthread_t socket_udp_thread;

pthread_mutex_t socket_udp_mutex;

#define SOCKETIPIP "192.168.0.197"

#define UdpRecvPort 6789

#define UdpRecvIP "239.0.0.1"

#define UdpSendPort 4567

#define UdpSendIP "239.0.0.2"

void* func_udp_thread_socket(void *arg){

printf("**************************************************\n");

printf("*************func_udp_thread_socket***************\n");

printf("**************************************************\n");

int ret = 0;

//定义本地IP端口

struct sockaddr_in addr;

bzero(&addr, sizeof(struct sockaddr_in));

addr.sin_family = AF_INET;

addr.sin_port = htons(UdpRecvPort);

addr.sin_addr.s_addr = htonl(INADDR_ANY);

printf("local sockaddr_in:IP:%s Port:%d\n",inet_ntoa(addr.sin_addr),UdpRecvPort);

//创建socket套接字

socket_udp_Handle = socket(AF_INET, SOCK_DGRAM, 0);

printf("socket(AF_INET, SOCK_DGRAM, 0) ret:%d\n",socket_udp_Handle);

if(socket_udp_Handle < 0){return NULL;}

//端口复用

int reuse = 1;

ret = setsockopt(socket_udp_Handle, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

printf("setsockopt(socket_udp_Handle, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) ret:%d\n",ret);

if (ret < 0) {return NULL;}

//加入多播组

struct ip_mreq vmreq;

inet_pton(AF_INET,UdpRecvIP,&vmreq.imr_multiaddr); // 组播地址

inet_pton(AF_INET,SOCKETIPIP,&vmreq.imr_interface); // 需要添加到组的ip

ret=setsockopt(socket_udp_Handle,IPPROTO_IP,IP_ADD_MEMBERSHIP,&vmreq,sizeof(vmreq));

printf("setsockopt(socket_udp_Handle,IPPROTO_IP,IP_ADD_MEMBERSHIP,&vmreq,sizeof(vmreq)) ret:%d\n",ret);

if (ret < 0) {return NULL;}

//多播发送

struct in_addr interface_addr;

inet_pton(AF_INET, SOCKETIPIP, &interface_addr);

ret = setsockopt(socket_udp_Handle, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr));

printf("setsockopt(socket_udp_Handle, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr)) ret:%d\n",ret);

if (ret < 0) {return NULL;}

//绑定本机IP端口

ret = bind(socket_udp_Handle, (struct sockaddr*)&(addr), sizeof(struct sockaddr_in));

printf("bind(sock,IP:%s,Port:%d ret:%d\n",inet_ntoa(addr.sin_addr),UdpRecvPort,ret);

if(ret == -1){return NULL;}

//用来记录对方的IP端口

struct sockaddr_in from;

bzero(&from, sizeof(struct sockaddr_in));

//存放接收到的数据

char data[128];

//7.开始接收处理

while(1){

memset(data, 0x0, sizeof(data));

//1.开始接收数据

int len = sizeof(sockaddr_in);

int ret = recvfrom(socket_udp_Handle, data, 128, 0, (struct sockaddr*)&from, (socklen_t*)&len);

if(ret != 128){sleep(20);continue;}

//2.接收到一个数据包

string ip = inet_ntoa(from.sin_addr);

int port = ntohs(from.sin_port);

printf("1.Recv From: IP%s Port:%d ret:%d Data:",ip.c_str(),port,ret);

for(int i = 0; i< 10; i++){printf("%02X ", (unsigned char)data[i]);}printf("\n");

//3.发送数据包

struct sockaddr_in sendaddr;

memset(&sendaddr, 0, sizeof(sendaddr));

sendaddr.sin_family = AF_INET;

sendaddr.sin_port = htons(UdpSendPort);

sendaddr.sin_addr.s_addr = inet_addr(UdpSendIP);

ret = sendto(socket_udp_Handle, (const char*)data, 128, 0, (struct sockaddr*)&sendaddr, sizeof(sockaddr_in));

printf("2.Send To : IP:%s Port:%d ret:%d Data:",UdpSendIP,UdpSendPort,ret);

for(int i = 0; i< 10; i++){printf("%02X ", (unsigned char)data[i]);}

printf("\n\n");

}

}

相关推荐
2023自学中3 分钟前
i.MX6ULL 板子的完整启动流程图(从上电 → 用户空间)
linux·嵌入式
闫利朋4 分钟前
Ubuntu 24.04 桌面安装向日葵完整指南
linux·运维·ubuntu
YSF2017_31 小时前
C语言16-makefile(3)——makefile的模式规则
linux·c语言·开发语言
不做无法实现的梦~2 小时前
Linux 上使用 CLion 开发嵌入式,并用 Codex CLI
linux·运维·服务器
张3232 小时前
Ansible拆分大型Playbook
linux·ansible
苦逼大学生被编程薄纱3 小时前
Ext 文件系统基础:Linux 存储基石入门(下)
linux·运维·服务器
Lumos_7773 小时前
Linux -- 进程
linux·运维·服务器
南境十里·墨染春水4 小时前
linux学习进展 进程间通讯——共享内存
linux·数据库·学习
小此方4 小时前
Re:Linux系统篇(五)指令篇 ·四:shell外壳程序及其工作原理
linux·运维·服务器
其实防守也摸鱼5 小时前
sqlmap下载和安装保姆级教程(附安装包)
linux·运维·服务器·测试工具·渗透测试·攻防·护网行动