sockaddr_in的一个小理解

之前一直认为是sockaddr设计时有缺陷,在编写网络通信时,都使用sockaddr_in,因为它将sockaddr中的

char sa_data[14]

拆分为了

unsigned short sin_port;     // 2 bytes
struct in_addr sin_addr;     // 4 bytes
char sin_zero[8];            // 8 bytes zero

这样就可以直观的获得IP地址和端口。


最近在获取网卡等信息的时候,使用ioctl()函数,发现需要一个数据结构是struct ifreq(如下ioctl()获取MAC地址)

ioctl(fd, SIOCGIFHWADDR, &(struct ifreq)ifr)

struct ifreq定义在if.h中,它有许多sockaddr结构的变量

struct ifreq {
#define IFHWADDRLEN	6
	union
	{
		char	ifrn_name[IFNAMSIZ];		/* if name, e.g. "en0" */
	} 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];	/* Just fits the size */
		char	ifru_newname[IFNAMSIZ];
		void *	ifru_data;
		struct	if_settings ifru_settings;
	} ifr_ifru;
};

就如同我们刚刚获得的MAC地址,我们通过ifr.ifr_hwaddr来获取它,而它的类型就是sockaddr!(ifr_hwaddr宏定义如下,也就是对应struct ifreq中的ifr_ifru.ifru_hwaddr)

#define ifr_hwaddr	ifr_ifru.ifru_hwaddr	/* MAC address */

也就是说,sockaddr_in可以视为sockaddr对于TCP/IP协议的拓展衍生,sockaddr可以存储的类型非常之多。

准确说应该是对于TCP/UDP的拓展,因为他们两个协议才定义了端口(Port)这个东西。(所以sockaddr_in.sin_family通常是AF_INET和AF_INET6两种类型)

我们平常几乎都是针对TCP/IP编程,所以对于编程者而言,几乎也就都使用sockaddr_in;而对于系统而言,它还是更喜欢使用sockaddr。比如我们在使用bind(),accept()等函数的时候就需要将sockaddr_in强制转换成sockaddr

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值