新浪博客

套接字地址结构

2017-06-29 19:55阅读:
1、IPv4套接字地址结构
struct in_addr{
in_addr_t s_addr; //32位IPv4地址、网络字节序
};
struct sockaddr_in{
uint8_t sin_len;
sa_family_t sin_family; //协议类型,IPv4对应的是AF_INET
in_port_t sin_port; //16位TCP/UDP端口号
struct in_addr sin_addr; //IPv4地址
char sin_zero[8];
};
2、IPv6套接字地址结构
struct in6_addr{
unit8_t s6_addr[16]; //128位IPv6地址、网络字节序
};
struct sockaddr_in6{
uint8_t sin6_len;
uint8_t sin6_family; //协议类型,IPv6对应的是AF_INET6
sa_family_t sin6_port; //传输层端口号,网络字节序
uint32_t
br>sin6_flowinfo; //低序20位是流标签,高序12位保留
struct in6_addr sin6_addr; //IPv6地址
uint32_t sin6_scope_id;
};
3、通用套接字地址结构
struct sockaddr{
uint8_t sa_len;
sa_family_t sa_family; //地址族 AF_XXX
char sa_data[14];
};
用途:例如在bind函数里使用了通用套接字地址结构的强制转换 int bind(int, struct sockaddr *, socklen_t);
为什么不直接使用IPv4或者IPv6的地址结构呢,大部分原因是为了使bind这些函数的实现与协议无关。
eg. struct sockaddr_in serv;
bind(sockfd, (struct sockaddr *)srev, sizeof(serv));
4、值-结果参数
socklen_t len;
struct sockaddr_in servaddr,cliaddr;
bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
accept(sockfd, (struct sockaddr *) &cliaddr, &len);
值-结果参数即在函数调用时需要将该结构的大小传递给函数,使内核在写此结构时不至于越界;当函数返回时,该结构大小是一个值,这个值就是内核在这个结构体中存储了多少信息,并返回给进程,因此成为值-结果参数。例如在上述bind和accept函数中,最后一个参数:sizeof(servaddr)不是,而&len是值-结果参数。但是为什么accept要使用值-结果参数呢,我也还不知道,知道的小伙伴希望能分享一下。
5、主机字节序和网络字节序
1)字节序有两种:大端字节序和小端字节序(如图所示)
套接字地址结构
看图就很容易理解了,简而言之就是小端字节序存储规则是:高字节存在高地址,低字节存在低地址。大端字节序则相反。
2)什么是主机字节序?
主机字节序就是某给定系统所用的字节序,通俗地说就是该系统是按大端字节序存储数据还是小端字节序存储数据,不同的系统可能是不一样的。
3)什么又是网络字节序
同理,网络字节序就是网络协议必须指定的字节序,即发送协议栈和接收协议栈必须对多字节字段的传送字节序进行统一,不然岂不是就乱了么。在现有是网络协议中,多采用大端字节序。
4)两种字节序之间的转换
由于不同的主机它的字节序可能不同,但是我们又要求网络字节序相同,那么解决的办法就是在一个主机上,将它的主机字节序和网络字节序进行转换(其实说白了就是一种存储方式的转换而已)。
转换函数有:
uint16_t htons(uint16_t host16bitvalue); //返回主机字节序
uint32_t htonl(uint32_t host32bitvalue); //返回主机字节序
uint16_t ntons(uint16_t net16bitvalue); //返回网络字节序
uint32_t ntonl(uint32_t net32bitvalue); //返回网络字节序
6、几个字节操纵函数
#include
void bzero(void *dest, size_t nbytes); //将目标中指定数目的字节置为0,常用于将套接字地址结构初始化为0
#include
void memset(void *dest, int c, size_t len); memset是指针函数,返回值是指针,所以应该是 void *memset(); 另外void *memset(void *s, int k, size_t n);是将从s指向的位置起n字节赋值为k,当k=0时有清零的作用。

我的更多文章

下载客户端阅读体验更佳

APP专享