Linux套接字地址结构,全面了解struct sockaddr_in等套接字地址

目录

1.套接字地址介绍

1.1 通用套接字地址

1.2 新的通用套接字地址

1.3 IPv4套接字地址

1.4 数据链路层套接字地址

1.5 域套接字地址

2.套接字地址内存对象模型

3.套接字地址关系

3.1 IPv4套接字编程

3.2 数据链路套接字编程

3.2 域套接字编程


1.套接字地址介绍

1.1 通用套接字地址

#include <sys/socket.h>

struct sockaddr {
  unsigned short sa_family;    
  char sa_data[14];
};

图 1

解析:

sa_family:2字节地址族

sa_data:14字节填充


作用:作为套接字函数参数使用

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,  struct sockaddr *src_addr, socklen_t *addrlen); 

1.2 新的通用套接字地址

#include <bits/socket.h>

struct sockaddr_storage {
  unsignedshort ss_family; 
  char __ss_padding[118];
  unsigned long __ss_align;
};

图 2

解析:

sa_family:2字节地址族

__ss_padding:118字节填充

__ss_align:8字节对齐字段


作用:
作为内存块使用,转换成其他套接字地址结构使用

1.3 IPv4套接字地址

#include <netinet/in.h>

struct sockaddr_in { 
  unsigned short sin_family;   
  unsigned short sin_port;  
  struct in_addr sin_addr;  
  unsigned char sin_zero[8];
};

struct in_addr {
  unsigned int  s_addr;
};

图 3

 

解析:
sin_family:2字节地址族,AF_INET

sin_port:2字节端口号,大端类型,可用htons函数转换为大端类型

sin_addr:4字节IP地址,大端类型,可用inet_addr函数转换字符IP地址为整型IP地址

sin_zero:8字节填充


作用:IPv4 TCP和UDP网路编程套接字地址

1.4 数据链路层套接字地址

#include <linux/if_packet.h>

struct sockaddr_ll {    
  unsigned short sll_family;    
  unsigned short sll_protocol;    
  int sll_ifindex;    
  unsigned short sll_hatype;    
  unsigned char sll_pkttype;    
  unsigned char sll_halen;    
  unsigned char sll_addr[8];
};

图4

 

解析:
sll_family:2字节地址族,PF_PACKET

ssl_protocol:2字节上层协议(以太网类型),大端类型,如IPPROTO_IP

sll_ifindex:4字节网络接口索引号,可通过if_nametoindex函数通过网口名获取

sll_hatype:2字节ARP硬件地址类型,如ARPHRD_ETHER

sll_pkttype:1字节分组类型,如:PACKET_OTHERHOST

sll_halen:1字节数据链路层地址长度

sll_addr:8字节数据链路层地址


作用:
数据链路层套接字编程地址

1.5 域套接字地址

#include <linux/un.h>

struct sockaddr_un {   
  unsigned short t sun_family;     
  char sun_path[108];   
};

 图5

解析:
sun_family:2字节地址族,AF_UNIX

sun_path:最大108字节系统路径,如:/tmp/test,由用户自己定义


作用:
域套接字编程使用

2.套接字地址内存对象模型

图6:套接字地址内存对象模型

 

3.套接字地址关系

3.1 IPv4套接字编程

//申请IPv4套接字地址内存空间
struct sockaddr_storage addr; 

//struct sockaddr_storage转换为struct sockaddr_in
struct sockaddr_in *in_addr = (struct sockaddr_in * )&addr;
in_addr->sin_family = AF_INET;
in_addr->sin_port = htons(1234);
in_addr->sin_addr.s_addr = inet_addr("192.168.1.2");

//struct sockaddr_in转换为struct sockaddr
bind(..., (struct sockaddr *)&in_addr, ...);
connect(..., (struct sockaddr *)&in_addr, ...);
......

3.2 数据链路套接字编程

//申请数据链路层套接字地址内存空间
struct sockaddr_storage addr;

//struct sockaddr_storage转换为struct sockaddr_ll 
struct sockaddr_ll *ll_addr = (struct sockaddr_ll *)&addr;
ll_addr->sll_family = PF_PACKET;
ll_addr->sll_protocol = htons(ETH_P_IP);
ll_addr->sll_ifindex = 2;
ll_addr->sll_hatype = ARPHRD_ETHER;
ll_addr->sll_pkttype = PACKET_OTHERHOST;
ll_addr->sll_halen = ETH_ALEN;
uint8_t mac[ETH_ALEN] = {0xf4,0x83,0xcd,0xa8,0xb3,0xcd};
memcpy(ll_addr.sll_addr, mac, ETH_ALEN);

//struct sockaddr_ll转换为struct sockaddr
bind(..., (struct sockaddr *)&ll_addr, ...);
connect(..., (struct sockaddr *)&ll_addr,...);
......

3.2 域套接字编程

//申请域套接字地址内存空间
struct sockaddr_storage addr;

//struct sockaddr_storage转换为struct sockaddr_un
struct sockaddr_un *un_addr = (struct sockaddr_un *)&addr;
un_addr->sun_family = AF_UNIX;
memcpy(&un_addr->sun_path, "/tmp/test", sizeof("/tmp/test"));

//struct sockaddr_un转换为struct sockaddr
bind(..., (struct sockaddr *)&un_addr, ...);
connect(..., (struct sockaddr *)&un_addr, ...);
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物联网心球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值