Linux C 网络编程 - 获取本地 ip 地址,mac,通过域名获取对应的 ip
获取本地 ip 地址,mac,通过域名获取对应的 ip,
是网络编程可能遇到的比较常见的操作了,所以总结如下(封装了3个函数),
直接上代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h> #include <netdb.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h> #define MAC_SIZE 18
#define IP_SIZE 16 // function declare
int get_ip_by_domain(const char *domain, char *ip); // 根据域名获取ip
int get_local_mac(const char *eth_inf, char *mac); // 获取本机mac
int get_local_ip(const char *eth_inf, char *ip); // 获取本机ip /****** main test **********/
int main(void)
{
char ip[IP_SIZE];
char mac[MAC_SIZE];
const char *test_domain = "www.baidu.com";
const char *test_eth = "eth0"; get_ip_by_domain(test_domain, ip);
printf("%s ip: %s\n", test_domain, ip); get_local_mac(test_eth, mac);
printf("local %s mac: %s\n", test_eth, mac); get_local_ip(test_eth, ip);
printf("local %s ip: %s\n", test_eth, ip); return ;
} // 根据域名获取ip
int get_ip_by_domain(const char *domain, char *ip)
{
char **pptr;
struct hostent *hptr; hptr = gethostbyname(domain);
if(NULL == hptr)
{
printf("gethostbyname error for host:%s/n", domain);
return -;
} for(pptr = hptr->h_addr_list ; *pptr != NULL; pptr++)
{
if (NULL != inet_ntop(hptr->h_addrtype, *pptr, ip, IP_SIZE) )
{
return ; // 只获取第一个 ip
}
} return -;
} // 获取本机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, )) < )
{
printf("get %s mac address socket creat error\n", eth_inf);
return -;
} strncpy(ifr.ifr_name, eth_inf, sizeof(ifr.ifr_name) - ); if(ioctl(sd, SIOCGIFHWADDR, &ifr) < )
{
printf("get %s mac address error\n", eth_inf);
close(sd);
return -;
} snprintf(mac, MAC_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char)ifr.ifr_hwaddr.sa_data[],
(unsigned char)ifr.ifr_hwaddr.sa_data[],
(unsigned char)ifr.ifr_hwaddr.sa_data[],
(unsigned char)ifr.ifr_hwaddr.sa_data[],
(unsigned char)ifr.ifr_hwaddr.sa_data[],
(unsigned char)ifr.ifr_hwaddr.sa_data[]); close(sd); return ;
} // 获取本机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, );
if (- == sd)
{
printf("socket error: %s\n", strerror(errno));
return -;
} strncpy(ifr.ifr_name, eth_inf, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ - ] = ; // if error: No such device
if (ioctl(sd, SIOCGIFADDR, &ifr) < )
{
printf("ioctl error: %s\n", strerror(errno));
close(sd);
return -;
} memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr)); close(sd);
return ;
}
测试运行
结果如下:
ifreq 结构体分析和使用:
struct ifreq
{
#define IFHWADDRLEN 6
union
{
char ifrn_name[IFNAMSIZ];
} ifr_ifrn; union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ];
char ifru_newname[IFNAMSIZ];
void __user * ifru_data;
struct if_settings ifru_settings;
} ifr_ifru;
}; #define ifr_name ifr_ifrn.ifrn_name
#define ifr_hwaddr ifr_ifru.ifru_hwaddr
#define ifr_addr ifr_ifru.ifru_addr
#define ifr_dstaddr ifr_ifru.ifru_dstaddr
#define ifr_broadaddr ifr_ifru.ifru_broadaddr
#define ifr_netmask ifr_ifru.ifru_netmask
#define ifr_flags ifr_ifru.ifru_flags
#define ifr_metric ifr_ifru.ifru_ivalue
#define ifr_mtu ifr_ifru.ifru_mtu
#define ifr_map ifr_ifru.ifru_map
#define ifr_slave ifr_ifru.ifru_slave
#define ifr_data ifr_ifru.ifru_data
#define ifr_ifindex ifr_ifru.ifru_ivalue
#define ifr_bandwidth ifr_ifru.ifru_ivalue
#define ifr_qlen ifr_ifru.ifru_ivalue
#define ifr_newname ifr_ifru.ifru_newname
#define ifr_settings ifr_ifru.ifru_settings
基本介绍:
ifreq结构定义在/usr/include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的。其中包含了一个接口的名 字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。ifreq包含在ifconf结构中。而 ifconf结构通常是用来保存所有接口的信息的。
举例说明:
在Linux系统中,ifconfig命令是通过ioctl接口与内核通信,例如,当系统管理员输入如下命令来改变接口eth0的MTU大小:
ifconfig eth0 mtu 1250
ifconfig命令首先打开一个socket,然后通过系统管理员输入的参数初始化一个数据结构,并通过ioctl调用将数据传送到内核。SIOCSIFMTU是命令标识符。
struct ifreq data;
fd = socket(PF_INET, SOCK_DGRAM, 0);
< ... initialize "data" ...>
err = ioctl(fd, SIOCSIFMTU, &data);
Linux C 网络编程 - 获取本地 ip 地址,mac,通过域名获取对应的 ip的更多相关文章
- 嵌入式linux的网络编程(1)--TCP/IP协议概述
嵌入式linux的网络编程(1)--TCP/IP协议概述 1.OSI参考模型及TCP/IP参考模型 通信协议用于协调不同网络设备之间的信息交换,它们建立了设备之间互相识别的信息机制.大家一定都听说过著 ...
- 网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?
1.前言 标题虽然是为了解释有了 IP 地址,为什么还要用 MAC 地址,但是本文的重点在于理解为什么要有 IP 这样的东西.本文对读者的定位是知道 MAC 地址是什么,IP 地址是什么. (本文同步 ...
- 【TCP/IP网络编程】:03地址族与数据序列
上一篇文章介绍了套接字的创建过程,这篇文章主要讨论分配给套接字的IP地址和端口号的相关知识. IP地址和端口号 IP(Internet Protocol,网络协议)地址是收发网络数据而分配给计算机的值 ...
- 【C#】C#获取本地的内网(局域网)和外网(公网)IP地址的方法
1.获取本机的IP地址集合: /// <summary> /// 获取本机所有ip地址 /// </summary> /// <param name="netT ...
- Linux C网络编程学习笔记
Linux C网络编程总结报告 一.Linux C 网络编程知识介绍: 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户端:(client) 在网络程序中, ...
- LINUX socket网络编程
1. 网络中进程之间如何通信 进 程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系统为进程通信提供了相应设施,如 U ...
- Java网络编程之查找Internet地址
一.概述 连接到Internet上计算机都有一个称为Internet地址或IP地址的唯一的数来标识.由于IP很难记住,人们设计了域名系统(DNS),DNS可以将人们可以记忆的主机名与计算机可以记忆的I ...
- Linux C++ 网络编程学习系列(1)——端口复用实现
Linux C++ 网络编程学习系列(1)--端口复用实现 源码地址:https://github.com/whuwzp/linuxc/tree/master/portreuse 源码说明: serv ...
- 根据ip地址从第三方接口获取详细的地理位置
最近项目某个功能需要根据ip地址从第三方接口获取详细的地理位置,从网上找了很多例子,主要接口有新浪的,淘宝的,腾讯的.试了淘宝的,如果是数量级小的还可以,如果数量级达到上十万级就速度慢了,会导致系统崩 ...
- C# 设置IP地址及设置自动获取IP
原文:C# 设置IP地址及设置自动获取IP </pre><pre name="code" class="csharp">1.添加引用&q ...
随机推荐
- open()函数文件操作
open函数,该函数用于文件处理 操作文件时,一般需要经历如下步骤: (1)打开文件 (2)操作文件 一.打开文件 文件句柄 = open("文件路径","模式& ...
- thinkphp5.0目录结构
下载最新版框架后,解压缩到web目录下面,可以看到初始的目录结构如下: project 应用部署目录 ├─application 应用目录(可设置) │ ├─common 公共模块目录(可更改) │ ...
- MySQL常用知识
1.MySQL常用引擎有哪些? A:MySQL常用的引擎有InnoDB.MyISAM.Memory,默认时InnoDB InnoDB:磁盘表,支持事务,支持行级锁,B+Tree索引 优点:具有良好的A ...
- 记录一下最近犯得sb的翻车错误
首先是: 数据范围是long long范围,然后写了一个暴力,觉得过不去,于是开了int范围,最后写了个能骗过所有数据的骗分,然后没开longlong... 接着是: for(int i = l; i ...
- oracle date 看时间
SELECT to_char(DATE_TIME,'yyyy-MM-dd HH24:mi:ss') FROM AUDIT_EVENT;
- OpenVAS漏洞扫描基础教程之创建用户组与创建角色
OpenVAS漏洞扫描基础教程之创建用户组与创建角色 OpenVAS创建用户组 用户组就是指许多个用户的组合.在网络中,各个访问网络的用户的权限可能各不相同.所以,可以通过将具体相同权限的用户划为一组 ...
- Xcode_7_GM_seed.dmg下载
Xcode_7_GM_seed.dmg下载 Xcode_7_GM_seed.dmg 免费下载链接: http://pan.baidu.com/s/1pJ7oGAZ 密码: y5bx
- Python协程(上)
几个概念: event_loop 事件循环:程序开启一个无限的循环,程序员会把一些函数注册到事件循环上.当满足事件发生的时候,调用相应的协程函数. coroutine 协程:协程对象,指一个使用asy ...
- 【BZOJ 3106】 3106: [cqoi2013]棋盘游戏 (对抗搜索)
3106: [cqoi2013]棋盘游戏 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 544 Solved: 233 Description 一个 ...
- 【HDU 6021】 MG loves string (枚举+容斥原理)
MG loves string Accepts: 30 Submissions: 67 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...