linux - 网络处理

广播接收并解析地址应答

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值