您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 第20章 基本套接字编程
第20章基本套接字编程套接字编程简述套接字数据结构基本套接字函数套接字选项TCP套接字编程UDP套接字编程小结20.1套接字编程简述套接字是位于应用层与TCP/IP协议族通信的中间软件抽象层,它逻辑上位于传输层与应用层之间,实际上由一组网络编程API组成。套接字的英文名称是Socket,也称为插口或者套接字。Socket数据传输是一种特殊的I/O。20.1.1半相关与全相关在网络通信模型中,一个连接一旦建立,则必然包括以下要素:协议、本地地址、本地端口号、远端地址和远端端口号。这样的一组要素,称为五元组或全相关。其中,协议、本地地址和本地端口号,这三个要素惟一地标识了网络连接的本地进程,而协议、远端地址和远端端口号则惟一地标识了网络连接的对端进程。这三项要素又称为三元组。由于三元组指定了一个完整的网络连接的半部分,所以称为半相关。20.1.2地址族与协议族Linux套接字支持多种协议族。协议族也称为域,不同的协议族定义了不同的通信环境。常见的协议族及作用的环境如下:PF_UNIX/PF_LOCAL/PF_FILE:用于主机内进程间通信PF_INET:Ipv4网络通信协议,用于远程主机间通信PF_INET6:用于Ipv6网络通信PF_IPX:用于NovellIPX网络通信PF_X25:用于ITU-TX.25/ISO-8208网络通信20.1.3面向连接与面向无连接在套接字编程模型中,存在面向连接的服务和面向无连接的服务。面向连接的服务类似于电话系统,无连接服务则类似于电报系统。主动拔号对方摘机,连接建立通话挂机主叫方被叫方向收报方发送发报方收报方向发报方应答20.1.4套接字类型在创建套接字时,除需要指定协议族外,还需要指定套接字的类型。Linux系统支持多种套接字类型,主要包括:流式套接字(SOCK_STREAM)数据报套接字(SOCK_DGRAM)原始套接字(SOCK_RAW)20.1.5字节序字节序是指占内存大于一个字节的类型的数据在内存中的存储顺序,按照不同的顺序可以划分为小端字节序、大端字节序两种,统称为主机字节序。......0x000x01内存地址高端内存地址低端0x00000x40000x4001小端字节序(LittleEndian)大端字节序(BigEndian)0x010x0016位的int型数据1(0x0001)在内存中的镜像20.1.6套接字连接方式在面向连接的套接字编程模式下,可以根据应用的需要构建不同的连接方式。主要包括:短连接方式:指在每进行一次通信报文收发交易时都需要先建立连接,然后进行数据收发,收发完毕后立即断开连接。长连接方式:指客户机与服务器建立好通讯连接,然后进行报文发送和接收。报文发送与接收完毕后,连接并不断开而继续存在,以便进行下一次的数据收发。20.1.7数据传输方式连接建立完成后,在数据发送与接收过程中也存在不同的方式,主要包括同步和异步两种方式。对于同步方式来说,报文发送和接收是同步进行的,即报文发送后,发送方等待接收方处理完成并返回应答报文。同步方式需要考虑超时问题,报文发出后发送方需要设定超时时间,超时后发送方不再继续等待,而直接返回。对于异步方式来说,发送方只负责发送数据,不需要等待接收任何返回数据;而接收方只负责接收数据。通常情况下,异步方式在客户端和服务器端各有两个进程专门负责数据收发。这两个进程相互独立,互不影响。20.2套接字数据结构在套接字编程接口函数中,定义了若干数据结构。这些数据结构大多为结构类型,基本上所有的套接字函数都会用到这些结构的内容。20.2.1套接字地址结构structsockaddr_in{__SOCKADDR_COMMON(sin_);in_port_tsin_port;structin_addrsin_addr;/*Padtosizeof'structsockaddr'.unsignedcharsin_zero[sizeof(structsockaddr)-__SOCKADDR_COMMON_SIZE-sizeof(in_port_t)-sizeof(structin_addr)];};20.2.2通用套接字地址结构Linux系统支持多种不同的地址族,每种地址族的结构内容是各不相同的,例如,internet地址族的地址结构是sockaddr_in,而UNIX地址族的地址结构是sockaddr_un等。在向套接字的编程接口函数传递地址结构指针时,需要将各不相同的地址结构转换为一个通用的数据结构,这就是通用套接字地址结构。structsockaddr{__SOCKADDR_COMMON(sa_);charsa_data[14];};20.2.3主机名称数据结构主机名称数据结构hostent定义了主机名与IP地址的对应关系。在套接字编程模型中,与地址绑定相关的操作都需要使用该结构。structhostent{char*h_name;char**h_aliases;inth_addrtype;inth_length;char**h_addr_list;#defineh_addrh_addr_list[0]};20.2.4服务名称数据结构Linux系统提供了对/etc/services文件进行操作的一系列函数,包括getservbyname、getservbyport等。这些函数都需要使用服务名称数据结构structservent。structservent{char*s_name;char**s_aliases;ints_port;char*s_proto;};20.2.5通用数据收发结构调用通用数据收发函数sendmsg和recvmsg时,需要用到一个类型为structmsghdr的结构,这里称其为通用数据收发结构。structmsghdr{void*msg_name;socklen_tmsg_namelen;structiovec*msg_iov;size_tmsg_iovlen;void*msg_control;size_tmsg_controllen;intmsg_flags;};20.3基本套接字函数字节操作函数字节序操作函数地址转换函数套接字函数20.3.1字节操作函数Linux系统提供了两组函数:一组是以字母b开头的bzero、bcopy,bcmp等函数;另外一组是以mem开头的内存操作函数,函数原型分别为:voidbzero(void*__s,size_t__n);voidbcopy(__constvoid*__src,void*__dest,size_t__n);intbcmp(__constvoid*__s1,__constvoid*__s2,size_t__n);void*memset(void*__s,int__c,size_t__n);void*memcpy(void*__restrict__dest,__constvoid*__restrict__src,size_t__n);intmemcmp(__constvoid*__s1,__constvoid*__s2,size_t__n);20.3.2字节序操作函数Linux系统提供了一系列字节序转换函数:uint16_thtons(uint16_t__hostshort);uint32_thtonl(uint32_t__hostlong);uint16_tntohs(uint16_t__netshort);uint32_tntohl(uint32_t__netlong);20.3.3地址转换函数从点分十进制形式转换为套接字内部数据类型的函数有:in_addr_tinet_aton(__constchar*__cp,structin_addr*__inp);intinet_pton(int__af,__constchar*__restrict__cp,void*__restrict__buf);in_addr_tinet_addr(__constchar*__cp);从套接字内部数据类型转化为点分十进制形式的函数有:char*inet_ntoa(structin_addr__in);__constchar*inet_ntop(int__af,__constvoid*__restrict__cp,char*__restrict__buf,socklen_t__len);20.3.4套接字函数socket函数bind函数connect函数listen函数accept函数send函数和recv函数sendto函数和recvfrom函数sendmsg函数和recvmsg函数close函数和shutdown函数getsockname函数和getpeername函数20.3.4套接字函数socket函数用来创建套接字,其原型为:intsocket(int__domain,nt__type,int__protocol);常用的套接字类型有:SOCK_STREAMSOCK_DGRAMSOCK_RAW20.3.4套接字函数bind函数的作用是为套接字绑定IP地址和端口,其原型如下所示。intbind(int__fd,__CONST_SOCKADDR_ARG__addr,socklen_t__len)20.3.4套接字函数connect函数用于建立与TCP服务器的连接。该函数一般用于客户端编程中。通过调用connect,实际上在TCP协议中发起了三次握手的过程。其原型如下:intconnect(int__fd,__CONST_SOCKADDR_ARG__addr,socklen_t__len);20.3.4套接字函数listen函数用于在指定套接字启动监听,该函数只在服务器端编程中调用,其原型如下所示。intlisten(int__fd,int__n);20.3.4套接字函数在服务器调用listen后,客户端调用connect连接至服务器。从listen函数的说明中可以看到,服务器在TCP层为这些客户端连接维持了一个队列。accept函数就是由从这个队列中取出一个已完成的连接。其原型如下:intaccept(int__fd,__SOCKADDR_ARG__addr,socklen_t*__restrict__addr_len);20.3.4套接字函数send和recv函数用于在流式套接字中发送和接收数据,函数原型如下:ssize_tsend(int__fd,__constvoid*__buf,size_t__n,int__flags);ssize_trecv(int__fd,void*__buf,size_t__n,int__flags);20.3.4套接字函数sendto和recvfrom用于数据报套接字的数据收发,函数原型如下:ssize_tsendto(int__fd,__constvoid*__buf,size_t__n,int__flags,__CONST_SOCKADDR_ARG__addr,socklen_t__addr_len);ssize_trecvfrom(int__fd,void*__restrict__buf,size_t__n,int__flags,__SOCKADDR_ARG__addr,socklen_t*__restrict__addr_len);20.3.4套接字函数sendmsg和recvmsg函数是通用的数据收发函数,不仅可以用于在流式套接字中收发数据(代替send和recv),还可以用于在数据报套接字中发送和接收数据(代替sendto和recvfrom),函数原型如下:ssize_tsendmsg(int__fd,__conststructmsghdr*__message,int__flags);ssize_trecvmsg(int__fd,structmsghdr*__message,int__flags);20.3.4套接字函数close和shutdown函数都用于关闭
本文标题:第20章 基本套接字编程
链接地址:https://www.777doc.com/doc-3271576 .html