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 data128;

//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)datai);}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)datai);}

printf("\n\n");

}

}

相关推荐
戴为沐1 天前
Linux内存扩容指南
linux
zylyehuo1 天前
Linux 彻底且安全地删除文件
linux
用户805533698032 天前
主线 U-Boot 上 RK3506:和闭源 rkbin 拔河的三个隐性契约
linux·嵌入式
用户034095297912 天前
linux fcitx 5 雾凇拼音 设置在中文输入法下仍然输入英文标点
linux
Web3探索者4 天前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
zylyehuo4 天前
Linux系统中网线与USB网络共享冲突
linux
Sokach10155 天前
Linux Shell 脚本从零到能用:一个新手的一天学习总结
linux
AlfredZhao6 天前
Docker 容器时区不对,`timedatectl` 不存在怎么办?
linux·timezone
zzzzzz3107 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
XIAOHEZIcode7 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏