套接字地址

套接字地址

2023-03-27 网络编程 socket
目录

1.套接字地址介绍

1.1 通用套接字地址

 #include <sys/socket.h>
struct sockaddr {
    unsigned short sa_family;
    char sa_data[14];
};

套接字地址 图1

图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 {
    unsigned short ss_family;
    char __ss_padding[118];
    unsigned long __ss_align;
};

套接字地址 图2

图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

图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

图4

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

sll_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 sun_family;
    char sun_path[108];
};

套接字地址 图5

图5解析:

sun_family:2字节地址族,AF_UNIX

sun_path:最大108字节系统路径,如:/tmp/test,由用户自己定义 作用: 域套接字编程使用

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

套接字地址 图6

图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.3 域套接字编程

 //申请域套接字地址内存空间
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, ...);
← 返回文章列表