资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,基本套接字编程,主要内容,套接字基础,套接字地址结构,套接字基本函数,套接字基础,网络编程接口有两个发展方向:,Socket,,,TLI,套接字是一种网络,API,,,程序员可以用之开发网络程序。,进程,1,进程,2,网络编程接口(,socket),网络通信协议服务接口,(TCP/IP),底层通信协议和网络介质,套接字类型,套接字支持多种通信协议:,Unix,:,Unix,系统内部协议,INET,:,IP,版本,4,INET6,:,IP,版本,6,Linux,支持多种套接字类型,即应用程序希望的通信服务类型,SOCKET_STREAM,:,双向可靠数据流,对应,TCP,SOCKET_DGRAM,:,双向不可靠数据报,对应,UDP,SOCKET_RAW,:,是低于传输层的低级协议或物理网络提供的套接字类型,可以访问内部网络接口。例如接收和发送,ICMP,报,套接字地址结构(,IPv4),大多数套接字函数需要一个指向套接字地址结构的参数,每个协议族都定义它自己的套接字地址结构,一般以”,sockaddr_”,开头,并以协议簇为后缀。(,netinet/in.h,),typedef,uint32_t,in_addr_t,;,typedef,uint16_t in_port_t;,typedef,unsigned short,sa_family_t,;,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_zero8;,;,这些结构在不同的系统上都有所不同,struct,sockaddr_in,server,bzero(&server,sizeof(server,),server.sin_family,=AF_INET;,server.sin_port,=,htons(PORT,);,server.sin_addr.s_addr,=,htonl(INADDR_ANY,),.,IPv6,地址为,128,位。(,netinet/in.h,),套接字地址结构(,IPv6),typedef,uint16_t in_port_t;,typedef,unsigned short,sa_family_t,;,struct in6_addr,uint8_ts6_addr16;,;,struct sockaddr_in6,uint8_t sin6_len;,sa_family_t,sin6_family;,in_port_t sin6_port;,uint32_t sin6_flowinfo;,struct in6_addr sin6_addr;,;,sin6_flowinfo,成员分成三个字段:,低,24,位是流量标号;,下,4,位是优先级;,再下,4,位保留,IPv4,与,IPv6,地址结构比较,长度,AF_INET6,16,位端口号,32,位流标签,128,位,IPv6,地址,sockaddr_in6,长度,AF_INET,16,位端口号,32,位,IP,地址,未用,sockaddr_in,固定长度(,16,字节),固定长度(,24,字节),通用套接字地址结构,由于套接字函数需接收来自不同协议的地址结构,,ANSI,的办法是使用通用的指针类型,即(,void*,),.,套接字函数方法是定义一个通用的套接字地址结构。,struct sockaddr,uint8_t,sa_len,;,sa_family_t,sa_family,;,char sa_data14;,;,这就要求调用套接字函数时,需将指向特定于协议的地址结构的指针类型转换成指向通用的地址结构的指针,,如:,struct,sockaddr_in,serv,bind(sockfd,(struct sockaddr*)&,serv,sizeof(serv,);,字节排序函数,为保证”大端“和”小端“字节序的机器之间能相互通信,需在发送多字节整数时,将主机字节序转换成网络字节序,或反之。,高序字节,低序字节,MSB,(最高有效位),16,位值,LSB,高序字节,低序字节,内存地址增大方向,内存地址增大方向,小端字节序,大端字节序,网络字节序,字节排序函数(,cont.,),#include,uint16_t htons(uint16_t,hostshort,),uint32_t htonl(uint32_t,hostlong,),均返回:网络字节序值,uint16_t ntohs(uint16_t,netshort,),uint32_t ntohl(uint32_t,netlong,),均返回:主机字节序值,h:,主机,n:,网络,s:,短整数,l:,长整数,字节操纵函数,#include,void,bzero(void,*,dest,size_t,nbytes,);,void,bcopy(const,void*,src,void*,dest,size_t,nbytes,);,int,bcmp(const,void*,src,void*,dest,size_t,nbytes,);/*,返回,0,则相同,非,0,不相同*,/,上述三个函数源自,BSD,void*,memset(void,*,dest,int,c,size_t,len,);,void*,memcpy(void,*,dest,const void*,src,size_t,nbytes,);,int,memcmp(const,void*ptr1,const void*ptr2,size_t,nbytes,),上述三个函数属于,ANSI C,地址转换函数,#include,将点分十进制数串转换成,32,位网络字节序二进制值。,int,inet_aton(const,char*cp,struct,in_addr,*,inp,);,返回:,1-,串有效,,0-,串有错,in_addr_t,inet_addr(const,char*cp);,返回:若成功,返回,32,位二进制的网络字节序地址,若有错,则返回一个 常值,INADDR_NONE,(,32,位均为,1,),.,过时函数,inet_aton,函数将,cp,所指的字符串,(,点分十进制数串,如,192.168.0.1),转换成,32,位的网络字节序二进制,并通过指针,inp,来存储。这个函数需要对字符串所指的地址进行有效性验证。但如果,cp,为空,函数仍然成功,但不存储任何结果。,inet_addr,进行相同的转换,但不进行有效性验证,也就是说,所有,2,32,种可能的二进制值,对,inet_addr,函数都是有效的。,地址转换函数(续),char*,inet_ntoa(struct,in_addr,inaddr,);,返回:指向点分十进制数串的指针,函数,inet_ntoa,将,32,位的网络字节序二进制,IPv4,地址转换成相应的点分十进制数串。但由于返回值所指向的串留在静态内存中,这意味着函数是不可重入的。,需要注意的是这个函数是以结构为参数的,而不是指针。,上述三个地址转换函数都只能处理,IPv4,协议,而不能处理,IPv6,地址。,地址转换函数,(,cont.,),#include,int,inet_pton(int,family,const char*,strptr,void*,addrptr,);,返回:,1-,成功,,0,输入无效,,-1:,出错,const char*,inet_ntop(int,family,const void*,addrptr,char*,strptr,size_t,len,);,返回:指向结果的指针成功,,NULL,出错,字母,P,和,N,分别代表,presentation,(地址的表达格式)和,numeric,(数值格式)。,family,参数可以是,AF_INET,也可以是,AF_INET6,。,长度参数,len,是目标的大小,如果太小无法容纳表达格式结果,则返回一个空指针。另外,目标指针调用前必须先由调用者分配空间。,
展开阅读全文