网络相关

第一部分  获取本机IP地址

#include<unistd.h>
#include<netdb.h>
#include<arpa/inet.h>

string get_local_ip() {
	char hname[128];
	struct hostent *hent;
	
	gethostname(hname, sizeof(hnameme));
	hent = gethostbyname(hname);
	
	return inet_ntoa(*(struct in_addr *)(hent->h_addr));
}
	


其中各个函数以及结构体的用法:

#include <netdb.h>
struct hostent {
	char *h_name;
	char *h_aliases;
	short h_addrtype;
	short h_length;
	char **h_addr_list;
};
#define h_addr  h_addr_list[0];
// 因为一个机器可能有多个网络接口,所以地址是一个链表,其中默认取的第一个。

#include <unistd.h>
void gethostname(char *host_name, int name_len);
// 返回主机的标准主机名


#include<netdb.h>
struct hostent* gethostbyname(const char *host_name);
// 返回对应于给定主机名的主机信息


#include<arap/inet.h>
char *inet_ntoa(struct in_addr);
// 返回点十进制的字符串在静态内存中的指针;
// 功能:将网络地址转换成点分十进制的字符串


#include<arpa/inet.h>
struct in_addr {
	in_addr_t s_addr;
}
// 结构体in_addr用来表示一个32位的IPv4地址,其中in_addr_t一般为32位的unsigned int,其字节顺序为网络顺序,即该无符号整数采用大端字节序。

struct in_addr {
	unio {
		struct {
			u_char s_b1, s_b2, s_b3, s_b4;
		} S_un_b; // An IPv4 address formatted as four u_chars.
		
		struct {
			u_short s_w1, s_w2;
		} S_un_w; // An IPv4 address formatted as two u_shorts.
		
		u_long S_addr; // An IPv4 address formatted as a u_long
	} S_un;
	
#define s_addr S_un.S_addr
};

第二部分 遍历网络接口信息,获取每个网卡的信息,包括IP地址

这样就可以根据指定的网卡获取相应的IP地址。

#include <iostream>
#include<ifaddrs.h>
#include<netinet/in.h>
#include<arpa/inet.h>

using namespace std;

int main() {
	struct ifaddrs *if_addr_struct = NULL;
	void *tmp_addr_ptr = NULL;
	
	getifaddrs(&if_addr_struct);
	
	struct ifaddrs *if_addr_struct_orign = if_addr_struct;
	while (if_addr_struct != NULL) {
		if (if_addr_struct != NULL) {
			if (if_addr_struct->ifa_addr->sa_family == AF_INET) { // ipv4
				tmp_addr_ptr = &((struct sockaddr_in *)if_addr_struct->ifa_addr)->sin_addr;
				char address[16];
				
				inet_ntop(AF_INET, tmp_addr_ptr, address, sizeof(address));
				cout << "Interface Name: " << if_addr_struct->ifa_name << endl;
				cout << "Interface IP: " << address << endl;
			} else if (if_addr_struct->ifa_addr->sa_family == AF_INET6) { // ipv6
				tmp_addr_ptr = &((struct sockaddr_in *)if_addr_struct->ifa_addr)->sin_addr;
				char address[128];
				
				inet_ntop(AF_INET6, tmp_addr_ptr, address, sizeof(address));
				cout << "Interface Name: " << if_addr_struct->ifa_name << endl;
				cout << "Interface IP: "<< address << endl;
			}
		}
		
		if_addr_struct = if_addr_struct->ifa_next;
	}
	
	if (if_addr_struct_orign) {
		freeifaddrs(if_addr_struct_orign);
	}
	return 0;
}

其中涉及到的方法,包括in_addr和点分十进制IP地址之间转换的方法

#include<arpa/inet.h>
char *inet_ntoa(struct in_addr);
//返回点分十进制的字符串在静态内存中的指针;
//函数功能: 将网络地址转换成“.”间隔的字符串格式

int inet_aton(const char *string, struct in_addr *addr);
// 将一个IP地址串转换成32位的网络序列IP地址

#include<arpa/inet.h>
in_addr_t inet_addr(const char *ip);
//将点分十进制的IP转换成一个长整形数(u_long类型);
//函数功能:点分十进制IP转换成网络字节IP

#include<arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
//将网络二进制结构到ASCII类型的地址,参数的作用和inet_pton相同
//将二进制整数转换成点分十进制,参数socklen_t指向dst缓冲区的大小,避免溢出。如果缓冲区太小,则返回空指针。并将errno置为ENOSPC。

int inet_pton(int af, const char *src, void *dst);
//这个函数将字符串转换成网络地址,第一个参数af是地址族,第二个参数src是来源地址,第三个参数为转换后的数据
//inet_pton是inet_addr的扩展,支持多地址族 AF_INET、AF_INET6
 
/* 
上述5个方法全部都是struct in_addr和点分十进制IP地址串之间的转换。其中前三个方法的缺陷就是,不能处理IPv6。
The function inet_ntoa() converts a network address in a struct in_addr to a dots-and-numbers format string. The "n" in nota stands for network, and the "a“ stands for ASCII
for historical reasons(so it's "Network To ASCII"-the "toa" suffix has an analogous friend in C library called atoi() which converts ASCII string to integer.

The function inet_aton is the opposite, converting from a dots-and-numbers string into a in_addr_t (which is the type of field s_addr in struct in_addr)

The function inet_addr() is an older function that does basically the same thing as inet_aton().

其中最后的inet_ntop()和inet_pton()是最新的。建议使用。
n表示network, p代表printable
*/


结构体信息

#include<ifaddrs.h>
struct ifaddrs {
	struct ifaddrs	*ifa_next;	//next item in list
	char			*ifa_name;	//name of interface
	unsigned int 	ifa_flags;	//flags from SIOCGIFFLAGS
	struct sockaddr	*ifa_addr;	//address of interface
	struct sockaddr	*ifa_netmask; //netmask of interface
	union {
		struct sockaddr	*ifu_broadaddr;	//broadcast address of interface
		struct sockaddr	*ifu_dstaddr;	//point-to-point destination address
	} ifa_ifu;
	#define 	ifa_broadaddr	ifa_ifu.ifu_broadaddr
	#define		ifa_dstaddr		ifa_ifu.ifa_dstaddr
	void		*ifa_data;	//address-specific data
}
//该结构体用于存放网络接口相关的所有参数,可以通过它查询IP地址等


struct sockaddr {
	unsigned short sa_family;	//address family, AF_XXX
	char	sa_char[14];	//14 bytes of protocol address
};

#include<netinet/in.h>
struct sockaddr_in {
	short int	sin_family;	//address family
	unsigned short int	sin_port;	//port number
	struct in_addr	sin_addr;	//internet address
	unsigned char sin_zero[8];	//same size as struct sockaddr
};





你可能感兴趣的:(网络相关)