以下是 Socket 编程中关键结构体 的详细说明,包括 struct sockaddr_in
、struct sockaddr
、struct in_addr
等,以及它们的参数列表和典型用法:
1. 核心结构体
(1) struct sockaddr_in
(IPv4地址结构)
#include <netinet/in.h>
struct sockaddr_in {
sa_family_t sin_family; // 地址族:AF_INET(IPv4)
in_port_t sin_port; // 16位端口号(网络字节序)
struct in_addr sin_addr; // 32位IP地址(网络字节序)
char sin_zero[8]; // 填充字段(通常置0)
};
- 成员说明:
sin_family
: 固定为AF_INET
。sin_port
: 使用htons()
转换端口号(如htons(8080)
)。sin_addr
: IPv4地址,通过inet_addr("192.168.1.1")
或inet_pton()
赋值。
(2) struct sockaddr
(通用地址结构)
struct sockaddr {
sa_family_t sa_family; // 地址族(如 AF_INET, AF_INET6)
char sa_data[14]; // 协议特定地址信息
};
- 用途:
作为通用结构体,用于强制类型转换(实际使用中传递的是sockaddr_in
,但函数参数要求sockaddr*
)。
(3) struct in_addr
(IPv4地址存储)
struct in_addr {
uint32_t s_addr; // 32位网络字节序IP地址
};
2. IPv6结构体 (sockaddr_in6
)
#include <netinet/in.h>
struct sockaddr_in6 {
sa_family_t sin6_family; // AF_INET6
in_port_t sin6_port; // 端口号(网络字节序)
uint32_t sin6_flowinfo; // IPv6流标签
struct in6_addr sin6_addr; // IPv6地址
uint32_t sin6_scope_id; // Scope ID
};
struct in6_addr {
unsigned char s6_addr[16]; //128位IPv6地址
};
3. DNS解析相关 (hostent
)
#include <netdb.h>
struct hostent {
char *h_name; //主机正式名
char **h_aliases; //别名列表
int h_addrtype; //地址类型(AF_INET/AF_INET6)
int h_length; //地址长度
char **h_addr_list;//IP地址列表(网络字节序)
};
#define h_addr h_addr_list[0] //兼容旧代码的首个IP
4. Socket选项控制 (linger
)
#include <sys/socket.h>
//设置关闭时的延迟行为
struct linger {
int l_onoff; //启用标志(0=禁用,非0=启用)
int l_linger; //延迟时间(秒)
};
//示例:设置优雅关闭
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &optval, sizeof(optval));
5. IP无关通用结构体 (sockaddr_storage
)
#include <sys/socket.h>
struct sockaddr_storage {
sa_family_t ss_family;//地址族
char __ss_padding[_SS_PADSIZE];//对齐填充
};
- 用途:
兼容IPv4/IPv6的通用存储结构,避免内存溢出。
典型用法示例
(1) IPv4 Socket初始化
int sockfd = socket(AF_INET, SOCK_STREAM,0);
struct sockaddr_in addr;
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
inet_pton(AF_INET,"127.0.0.1",&(addrsin_addrsin_addrsin_addrsin_addrsin_addrsin_addrsin_addrsin_addrsin_addrsin_addr));
bind(sockfd,(const struct sockaddrddr*)&addraddraddraddraddr,sizeof(addraddraddraddraddr)));
(2) IPv4与通用结构的强制转换
connect(sockfd,(const struct sockaddrddr*)&ipv4ddr,sizeof(ipv4ddr));
如果需要具体场景的代码或其他细节补充,可以告诉我!
内容由零声教学AI助手提供,问题来源于学员提问