1.Socket地址结构
1.1 IPv4
ipv4的套接字地址结构占用20个字节
struct in_addr{
in_addr_t s_addr; //32-bit
}
struct sockaddr_in{
uint8_t sin_len; // 1-byte
sa_family_t sin_family; // uint_8 8位无符号整数
in_port_t sin_port; // uint_16 16位
struct sin_addr; //4个字节
char sin_zero[8]; // 8字节
}
从进程向内核传递套接字地址结构的四个函数:
bind、connect、sendto、sendmsg
内核到进程传递套接字的函数:
accept、recvfrom、secvmsg、getpeername、getsockname
通用套接字地质结构,其唯一用途就是将特定套接字地址结构指针强制转换为通用结构:
struct sockaddr{
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
}
bind(sockfd, (struct sockaddr *)&serv, sizeof(serv));//强制转换
1.2 IPv6(28字节)
略
1.3 新的套接字地址结构
struct sockaddr_storage {
uint8_t ss_len;
sa_family_t ss_family;
//用户透明字段,必须类型强制装换为适合ss_family地址结构,、
//才能访问其他字段
}
1.4 字节排序函数
鉴定little-endian和big-endian字节序的函数:
void ByteOrder(){
union {
short value;
char c[sizeof(short)];
} un;
un.value = 0x0102;
if(sizeof(shor) == 2){
if(un.c[0] == 1 && un.c[1] == 2){
printf("big-endian\n");
}else if(un.c[0] == 2 && un.c[1] == 1){
printf("little-endian\n");
}else{
printf("unknow\n");
}
}else{
printf("sizeof(short) = %d\n", sizeof(short));
}
}
字节序转换函数:根据函数名,意义很明确
htons、htonl、ntohs、ntohl;
1.5 地址转换
主要使用inet这两个函数:
int inet_pton(int family, const char *strptr, void *addrptr);
const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
//使用
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13);
if(inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0){
}
1.6 用read和write读写套接字时,可能出现比请求的字节数少的现象,原因在于内核的套接字缓冲区满了。