发送端:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <net/if.h>
#include <errno.h>
#define SRC_PORT 6000
#define DST_PORT 6001
#define MAC_SIZE 18
#define IP_SIZE 16
#define UDP_DATA_LEN 1024
#define ETHX "eth0"
#define DST_IP ((192 << 24) + (168 << 16) + (2 << 8) + 198) /* 192.168.2.198 */
// function declare
int get_local_mac(const char *eth_inf, char *mac); // 获取本机mac
int get_local_ip(const char *eth_inf, char *ip); // 获取本机ip
// 获取本机mac
int get_local_mac(const char *eth_inf, char *mac)
{
struct ifreq ifr;
int sd;
bzero(&ifr, sizeof(struct ifreq));
if( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("get %s mac address socket creat error\n", eth_inf);
return -1;
}
strncpy(ifr.ifr_name, eth_inf, sizeof(ifr.ifr_name) - 1);
if(ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
{
printf("get %s mac address error\n", eth_inf);
close(sd);
return -1;
}
snprintf(mac, MAC_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char)ifr.ifr_hwaddr.sa_data[0],
(unsigned char)ifr.ifr_hwaddr.sa_data[1],
(unsigned char)ifr.ifr_hwaddr.sa_data[2],
(unsigned char)ifr.ifr_hwaddr.sa_data[3],
(unsigned char)ifr.ifr_hwaddr.sa_data[4],
(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
close(sd);
return 0;
}
//获取网卡对应IP地址[其中eth是网卡名字 如“eth0” “eth1”等,ipaddr是输出参数]
// 获取本机ip
int get_local_ip(const char *eth_inf, char *ip)
{
int sd;
struct sockaddr_in sin;
struct ifreq ifr;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == sd)
{
printf("socket error: %s\n", strerror(errno));
return -1;
}
strncpy(ifr.ifr_name, eth_inf, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ - 1] = 0;
// if error: No such device
if (ioctl(sd, SIOCGIFADDR, &ifr) < 0)
{
printf("ioctl error: %s\n", strerror(errno));
close(sd);
return -1;
}
memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));
close(sd);
return 0;
}
int main(int argc, char **argv)
{
struct sockaddr_in addr, mcast_addr;
int fd;
struct ip_mreq ipmr;
char ip[IP_SIZE];
char mac_addr[MAC_SIZE];
int ret = -1;
unsigned char chrUDP[UDP_DATA_LEN] =
{0xaa,0xaa};
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) // UDP
{
perror("create socket failed!");
return -1;
}
get_local_mac(ETHX, mac_addr);
printf("local %s mac: %s\n", ETHX, mac_addr);
get_local_ip(ETHX, ip);
printf("local %s ip: %s\n", ETHX, ip);
// 绑定到发送端网卡 IP 和 端口
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
inet_pton(AF_INET, ip, &addr.sin_addr.s_addr);
addr.sin_port = htons(SRC_PORT);
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
{
perror("bind:");
close(fd);
return -1;
}
/*
// 另一种绑定到发送端网卡的方法
struct ifreq if_eth0;
strncpy(if_eth0.ifr_name, ETHX, IFNAMSIZ);
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&if_eth0, sizeof(if_eth0)) < 0)
{
perror("bind:");
close(fd);
return -1;
}
*/
/*
// 广播包
memset(&mcast_addr, 0, sizeof(mcast_addr));
mcast_addr.sin_family = AF_INET;
mcast_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); //INADDR_BROADCAST
mcast_addr.sin_port = htons(DST_PORT);
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&mcast_addr, sizeof(mcast_addr)) < 0)
{
perror("setsockopt:");
close(fd);
return -1;
}
*/
/*
// 接收缓冲区
int nRecvBuf=32*1024; //设置为32K
setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
//发送缓冲区
int nSendBuf=32*1024; //设置为32K
setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
*/
// 设置接收端 IP 和 端口
memset(&mcast_addr, 0, sizeof(mcast_addr));
mcast_addr.sin_family = AF_INET;
mcast_addr.sin_addr.s_addr = htonl(DST_IP); //DST_IP
mcast_addr.sin_port = htons(DST_PORT);
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&mcast_addr, sizeof(mcast_addr)) < 0)
{
perror("setsockopt:");
close(fd);
return -1;
}
uint32_t fIndex = 0;
while(1){
fIndex++;
memcpy(chrUDP , &fIndex, sizeof(fIndex));
if (sendto(fd, (const char *)chrUDP, sizeof(chrUDP), 0, (struct sockaddr *)&mcast_addr, sizeof(mcast_addr)) < 0)
{
perror("sendto");
return -1;
}
//printf("%d send ok! %ld bytes\n", fIndex, sizeof(chrUDP));
struct timeval delay;
delay.tv_sec = 0;
delay.tv_usec = 1000000; // 1us
select(0, NULL, NULL, NULL, &delay);
}
setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mcast_addr, sizeof(mcast_addr));
close(fd);
return 0;
}
接收端:
#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>
using namespace std;
int main()
{
setvbuf(stdout,NULL,_IONBF,0);
fflush(stdout);
struct sockaddr_in addrto;
bzero(&addrto,sizeof(struct sockaddr_in));
addrto.sin_family=AF_INET;
addrto.sin_addr.s_addr=htonl(INADDR_ANY);
addrto.sin_port=htons(6001);
socklen_t len=sizeof(addrto);
int sock=-1;
if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
cout<<"socket error..."<<endl;
return -1;
}
const int opt=-1;
int nb=0;
nb=setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char*)&opt,sizeof(opt));
if(nb==-1)
{
cout<<"set socket errror..."<<endl;
return -1;
}
if(bind(sock,(struct sockaddr*)&(addrto),len)==-1)
{
cout<<"bind error..."<<endl;
return -1;
}
char msg[100]={0};
while(1)
{
int ret=recvfrom(sock,msg,100,0,(struct sockaddr*)&addrto,&len);
if(ret<=0)
{
cout<<"read error..."<<endl;
}
else
{
printf("%s\t",msg);
}
sleep(1);
}
return 0;
}