广播接收并解析地址应答
client
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<unistd.h>
int main()
{
char msg[128] = "I am broadCast request message!";
int brdcFd = socket(PF_INET, SOCK_DGRAM, 0);
if(brdcFd == -1){
printf("socket fail\n");
return -1;
}
int optval = 1;//这个值一定要设置,否则可能导致sendto()失败
setsockopt(brdcFd, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &optval, sizeof(int));
struct sockaddr_in theirAddr;
memset(&theirAddr, 0, sizeof(struct sockaddr_in));
theirAddr.sin_family = AF_INET;
theirAddr.sin_addr.s_addr = inet_addr("255.255.255.255");
theirAddr.sin_port = htons(4001);
int sendBytes = sendto(brdcFd, msg, strlen(msg), 0, (struct sockaddr *)&theirAddr, sizeof(struct sockaddr));
if(sendBytes == -1){
printf("sendto fail, errno=%d\n", errno);
return -1;
}
printf("sendto msg=%s, msgLen=%ld, sendBytes=%d\n", msg, strlen(msg), sendBytes);
while(1) {
char recvbuf[128] = {0};
struct sockaddr_in recvAddr;
int addrLen = sizeof(struct sockaddr_in);
int recvbytes = recvfrom(brdcFd, recvbuf, 128, 0, (struct sockaddr *)&recvAddr, &addrLen);
if(recvbytes != -1){
recvbuf[recvbytes] = '\0';
printf("recv from %s:%d, messgse:%s\n", inet_ntoa(recvAddr.sin_addr), ntohs(recvAddr.sin_port), recvbuf);
}else{
printf("recv fail\n");
}
}
close(brdcFd);
return 0;
}
server
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<arpa/inet.h>
#include<errno.h>
#include<unistd.h>
int main()
{
int sockListen = socket(AF_INET, SOCK_DGRAM, 0);
if(sockListen == -1){
printf("socket fail\n");
return -1;
}
int set = 1;
setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(int));
struct sockaddr_in recvAddr;
memset(&recvAddr, 0, sizeof(struct sockaddr_in));
recvAddr.sin_family = AF_INET;
recvAddr.sin_port = htons(4001);
recvAddr.sin_addr.s_addr = INADDR_ANY;
// 必须绑定,否则无法监听
if(bind(sockListen, (struct sockaddr *)&recvAddr, sizeof(struct sockaddr)) == -1){
printf("bind fail\n");
return -1;
}
char recvbuf[128] = {0};
int addrLen = sizeof(struct sockaddr_in);
int recvbytes = recvfrom(sockListen, recvbuf, 128, 0, (struct sockaddr *)&recvAddr, &addrLen);
if(recvbytes != -1){
recvbuf[recvbytes] = '\0';
printf("recv from %s:%d, msg:%s\n", inet_ntoa(recvAddr.sin_addr), ntohs(recvAddr.sin_port), recvbuf);
}else{
printf("recv fail\n");
}
char msg[128] = "I am responsed message!";
int sendBytes = sendto(sockListen, msg, strlen(msg), 0, (struct sockaddr *)&recvAddr, addrLen);
if(sendBytes== -1){
printf("sendto fail, errno=%d\n", errno);
} else {
printf("sendto msg=%s, msgLen=%ld, sendBytes=%d\n", msg, strlen(msg), sendBytes);
}
close(sockListen);
return 0;
}
网络信息获取
#include <arpa/inet.h>
#include <linux/rtnetlink.h>
#include <net/if.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
#include <sys/ioctl.h>
const char *dns_get()
{
static char dns[64] = {0};
FILE *dns_fd = popen("cat /etc/resolv.conf | grep 'nameserver'", "r");
assert(dns_fd);
char temp[128] = {0};
fread(temp, 1, 128, dns_fd);
sscanf(temp, "%*s%s", dns);
pclose(dns_fd);
return dns;
}
const char *mac_get()
{
static char dev_id[18] = { 0 };
const char *eth_path = "/sys/class/net/enp2s0/address"; // enp2s0 是网卡名字
if (access(eth_path, W_OK) < 0) {
FILE *fp = fopen(eth_path, "r");
assert(fp);
/* aa:bb:cc:dd:ee:ff, 17 bytes */
size_t nread = fread(dev_id, 1, 17, fp);
assert(nread == 17);
fclose(fp);
}
return dev_id;
}
const char *netmask_get_by_name(const char *interface_name)
{
static char netmask[32] = {0};
int sock_get_netmask = socket(AF_INET, SOCK_STREAM, 0);
if (sock_get_netmask == -1) {
printf("Failed to create socket.!\n");
return NULL;
}
struct sockaddr_in *sin;
struct ifreq ifr_ip;
memset(&ifr_ip, 0, sizeof(ifr_ip));
strncpy(ifr_ip.ifr_name, interface_name, sizeof(ifr_ip.ifr_name) - 1);
if( ioctl( sock_get_netmask, SIOCGIFNETMASK, &ifr_ip) < 0 ) {
return netmask;
}
sin = (struct sockaddr_in *)&ifr_ip.ifr_netmask;
strcpy(netmask, inet_ntoa(sin->sin_addr));
close( sock_get_netmask );
return netmask;
}
const char * get_default_ip()
{
static char default_ip[18] = {0};
struct ifreq *ifr;
struct ifconf conf;
char buff[BUFSIZ];
int num;
int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
conf.ifc_len = BUFSIZ;
conf.ifc_buf = buff;
ioctl(socket_fd, SIOCGIFCONF, &conf);
num = conf.ifc_len / sizeof(struct ifreq);
ifr = conf.ifc_req;
unsigned int ip_addr = 0;
/* 无法查询拔出网线的情况 */
for (int i=0; i<num; i++) {
struct sockaddr_in *sin = (struct sockaddr_in *)(&ifr->ifr_addr);
ioctl(socket_fd, SIOCGIFFLAGS, ifr);
if ((ifr->ifr_flags & IFF_LOOPBACK) != 0) {
ip_addr = 0;
} else {
ip_addr = sin->sin_addr.s_addr;
}
int up_and_running = (ifr->ifr_flags & ( IFF_UP | IFF_RUNNING )) == ( IFF_UP | IFF_RUNNING );
struct in_addr addr;
addr.s_addr = ip_addr;
printf("interface num %d, net-name: %s, net-ip: %s, netmask: %s, up: %d\n",
i,
ifr->ifr_ifrn.ifrn_name,
inet_ntoa(addr),
netmask_get_by_name(ifr->ifr_ifrn.ifrn_name),
up_and_running);
if (!strcasecmp(ifr->ifr_ifrn.ifrn_name, "eth0")) {
strcpy(default_ip, inet_ntoa(addr));
} else if (!strcasecmp(ifr->ifr_ifrn.ifrn_name, "wlan0")) {
strcpy(default_ip, inet_ntoa(addr));
} else if (strcasecmp(ifr->ifr_ifrn.ifrn_name, "usb0") != 0 && ((ifr->ifr_flags & IFF_LOOPBACK) != 0)) {
strcpy(default_ip, inet_ntoa(addr));// 除 lo, eth0, wlan0 和 usb0 外有效的网络
}
ifr++;
}
close(socket_fd);
return default_ip;
}
const char * get_default_gateway()
{
static char gateway[32] = {0};
char line[100], *p, *c, *g, *saveptr;
int ret = 0;
FILE *fp = fopen("/proc/net/route" , "r");
assert(fp);
while (fgets(line, 100, fp))
{
p = strtok_r(line, " \t", &saveptr);
c = strtok_r(NULL, " \t", &saveptr);
g = strtok_r(NULL, " \t", &saveptr);
if (p != NULL && c != NULL) {
if (strcmp(c, "00000000") == 0) {
if (g) {
char *p_end;
int gw = strtol(g, &p_end, 16);
struct in_addr addr;
addr.s_addr = gw;
strcpy(gateway, inet_ntoa(addr));
ret = 1;
}
break;
}
}
}
fclose(fp);
if (ret == 0)
return NULL;
return gateway;
}
const char * get_default_gateway_route()
{
char temp[128];
static char gateway[128];
FILE *gw_fd = popen("route -n | grep 'UG'", "r");
if(gw_fd) {
fread(temp,1,128, gw_fd);
sscanf(temp, "%*s%s", gateway);
pclose(gw_fd);
}
return gateway;
}
int main()
{
// netstat -r| grep default | cut -f 10 -d ' '
printf("dns_get=%s\n",dns_get());
printf("mac_get=%s\n",mac_get());
printf("get_default_ip=%s\n",get_default_ip());
printf("get_default_gateway=%s\n",get_default_gateway());
printf("get_default_gateway_route=%s\n",get_default_gateway_route());
return 0;
}