第三章 套接字编程简介
一、套接字地址结构
以socket_in命名,定义在<netinet/in.h>头文件中。
struct in_addr{
in_addr_t s_addr;}
struct sockaddr_in{
uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port; (这三个为必须定义)
struct in_addr sin_addr;
char sin_zero[8];
}
由于当以参数来传递套接字函数时,套接字地址结构以引用形式(传递该结构的指针)来传递。涉及到所有协议族的匹配问题(例如IPV4和IPV6),所以调用时要对指针类型进行强制转换。例如:
bind(socked,(structsockaddr *)&serv,sizeof(serv));
用void *这个指针类型就变得很简单,无需显式进行类型强制转换。
至于sockaddr_storage通用地址结构,比较类似。
二、值---结果参数
传递套接字结构有两种传递方向:
(1) 从进程到内核:bind、connect、sendto;
(2) 从内核到进程:accept、recvfrom、getsockname、getpeername;
在函数调用时,结构大小是一个值,他告诉内核结构的大小;在函数返回时,结构大小是一个结果,告诉进程该结构中存储了多少信息。这种参数称为值---结果函数。
三、字节排序函数
1、小端字节序和大端字节序
不同的操作系统的字节存储模式不同,分为小端字节序和大端字节序。
小端字节序:高序字节内存地址大;
大端字节序:高序字节内存地址小;(Linux为小端字节序)
字节序转换4个函数。
2、字节操纵函数
void bzero(void *dest , size_t nbytes); (将n字节置0)
void bcopy(const void*src, void *dest , size_t nbytes);(将n字节复制到目标字符串)
void bcmp(const void *ptr1 , const void *ptr2 , size_tnbytes);
(比较两字符串前n字节,相同返回0,不同返回非0)
memset、memcpy、memcmp类似。
3、地址转换函数
int inet_ston(const char *strptr , structin_addr *addrptr);
(将strptr所指字符串转换为32位网络字节序二进制值,用addrptr来存储);
in_addr_t inet_addr(const char *strptr );(已弃用)
与inet_ston相同,返回32位网络字节序二进制值(不能处理255.255.255.255)
int inet_pton(int family , const char *strptr ,void *addrptr);
表达形式----->数字形式
const char *inet_ntop(int family , const void*addrptr, char *strptr ,size_t len);(strptr不能为空)
数字形式----->表达形式
readn、written、readline函数:
read和write存在缓冲区溢出的问题,改进为readn、written、readline函数,避免让调用者处理不足的字节计数值。