第二章 套接口编程简介
(1)IPv4套接口地址结构:
struct sockaddr_in
{
sin_family;
sin_port;//网络字节序,16位
sin_addr;//网络字节序的一个in_addr结构体
}
struct in_addr
{
s_addr;//一个32位的无符号整数,以网络字节序存储
}
(2)通用套接口地址结构
struct sockaddr;对于应用程序员来说只要知道这个结构是用在套接口函数中作为类型转换的即可。
几乎所有的IPv4套接口函数都是利用这个结构去进行参数传递。
(3)IPv6套接口地址结构
struct sockaddr_in6
{
sin6_family;
sin6_port;//网络字节序
sin6_addr;//网络字节序
}
struct in6_addr
{
s6_addr[16];//网络字节序,是一个8位的无符号整数,用来表示128的IPv6地址
}
(4)新的通用套接口地址结构
struct sockaddr_stoage;类似于sockaddr的作用
(5)网络字节序和主机字节序的转换函数:
字母含义:h=host,n=network,s=short(可以理解为16位的端口号),l=long(可以理解为32位的IPv4地址)
htons,htonl------>主机字节序向网络字节序转换
ntohs,ntohl------>网络字节序向主机字节序转换
(6)点分十进制和二进制之间的转换函数(IPv4适用)
int inet_aton(const char *,struct in_addr *);ascii向二进制网络字节序转换,可以直接填充seraddr.sin_addr.返回1----串有效,0---串出错
in_addr_t inet_addr(const char *);可以赋值给seraddr.sin_addr.s_addr;改函数出错则返回INADDR_NONE.
char * inet_ntoa(struct in_addr);返回一个指向点分十进制的字符串.向其传递seraddr.sin_addr;结构存储于一个静态地址之中,位不可重入函数,线程不安全函数
推荐使用inet_aton()和inet_ntoa()函数。
(7)IP地址字符串和网络字节序之间的转换函数(IPv4和IPv6均适用,在新程序中推荐使用)
字母含义说明:p=presentation,n=numeric.
int inet_pton(int family,const char *,void *);用于ascii向网络字节序转换,void *可以填充,seraddr.sin_addr.s_addr(v4),或者seraddr6.sin6_addr.s6_addr(v6);
返回值说明: 1----->成功,0----->输入不是有效的串,-1---->出错`
const char * inet_ntop(int family,const void * ,char * ,size_t len);把const void *指向的变量转换成ascii形式存储与char *之中,由自己分配内存,
一般分配为系统定义的两个宏:INET_ADDRSTRLEN 16;INET6_ADDRSTRLEN 46;分别对应IPv4和IPv6的情况
(8)注意事项:
当利用系统调用read()和 write()函数的时候要注意处理错误和内核缓冲区满的情况,
一般要将read()放到一个循环当中去处理
size_t n;
while((n=read())>0)
{
//do something here.
}