#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];
while(1){
memset(data, 0x0, sizeof(data));
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;}
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");
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");
}
}