您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > Linux&Unix网络编程复习资料
第一章TCP/IP简介1.OSI模型和TCP/IP模型2.TCP连接的建立TCP连接的建立需要经过3次数据传输(三次握手),步骤如下:(1)服务器必须已经准备好接收客户的连接请求,这通过调用socket、bind和listen函数来完成。客户通过调用connect函数进行主动打开,这引起客户端发送一个SYN分节到服务器端。(2)服务器收到客户端发来的SYN分节后,必须发送ACK对其进行确认,同时发送一个自己的SYN分节给客户端,表示接受客户端建立连接的请求。(3)客户端发送ACK确认服务器SYN,建立连接成功。3.TCP连接的终止当数据传输完毕后,TCP需要发送4个分节终止该连接,释放TCP连接的步骤如下:(1)客户端应用进程调用close,调用close的结果就是发送一个FIN分节主动关闭连接。(2)服务器收到FIN后执行被动关闭,发送ACK对客户端的FIN分节进行确认。(3)当服务器将待发的数据发送完后,调用close关闭它的套接字,这导致它的TCP发送一个FIN分节给客户端。(4)接收到服务器的FIN分节后,对其发送一个ACK确认分节,当前的连接被彻底关闭。第二章套接字编程简介1.套接字的类型套接字支持各种通信协议,目前Linux系统常用的协议有以下两种:(1)INET:IP版本4。(2)INET6:IP版本6。套接字类型是指创建套接字的应用程序要使用的通信服务的类型。Linux系统支持多种套接字类型,最常用的有以下几种:(1)SOCK_STREAM:流式套接字,提供面向连接、可靠的数据传输服务,数据按字节流、按顺序收发,保证数据在传输过程中无丢失、无冗余。TCP协议支持该套接字。(2)SOCK_DGRAM:数据报套接字,提供面向无连接的服务,数据收发无序,不能保证数据的准确到达。UDP协议支持该套接字。(3)SOCK_RAW:原始套接字。允许对低于传输层的协议或物理网络直接访问例如可以接收和发送ICMP报。常用于检测新的协议。第三章基本TCP套接字编程1.TCP套接字编程TCP套接字编程中,服务器端实现的步骤如下:(1)使用socket()函数创建套接字。(2)将创建的套接字绑定到指定的地址结构。(3)Listen()函数设置套接字为监听模式,使服务器进入被动打开的状态。(4)接受客户端的连接请求,建立连接。(5)接收、应答客户端的数据请求。(6)终止连接。客户端实现的步骤相对比较简单:(1)使用socket()函数创建套接字。(2)调用connect()函数建立一个与TCP服务器的连接。(3)发送数据请求,接收服务器的数据应答。(4)终止连接。2.socket()函数客户端服务器端都存在,产生TCP套接字,作为TCP通信的传输端点#includesys/socket.hintsocket(intfamily,inttype,intprotocol)返回:非负套接字(sockfd)【0,1】-成功;-1-出错。family:协议族;type:套接字类型;protocol:一般为0,除原始套接字外。Family(确定协议类型)type(指明产生套接字类型)AF_INETIPv4协议SOCK_STREAM字节流套接口AF_INET6IPv6协议SOCK_DGRAM数据报套接口【AF_LOCALunix域协议】SOCK_RAW原始套接口AF_ROUTE路由套接口【AF_KEY密钥套接口】3.bind()绑定函数绑定函数的作用就是为调用socket()函数产生的套接字分配一个本地协议地址,建立地址与套接字的对应关系。#includesys/socket.hintbind(intsockfd,conststructsockaddr*addr,socklen_lenlen)返回:0-成功;-1-出错并置errnoSockfd:套接字函数返回的套接字描述符server:指向特定协议的地址结构的指针addrlen:套接字地址结构的长度该函数指明套接字将使用本地的哪一个协议端口进行数据传送(IP地址和端口号),注意:协议地址addr是通用地址。一般而言,服务器调用此函数,而客户则很少调用它。绑定地址时,可以指定地址和端口号,也可以指定其中之一,甚至一个也不指定。通配地址:INADDR_ANY,其值一般为0,它通知内核选择IP地址。IP地址端口结果通配地址0内核选择IP地址和端口号通配地址非0内核选择IP地址,进程指定端口本地IP0进程指定IP地址,内核选择端口本地IP非0进程指定IP地址和端口号若指定端口号为0,调用函数bind时,内核选择一个临时端口(在实际中,端口号都要指定);但若指定一个通配IP地址,则直到套接字已连接(TCP)或数据报已在套接字上发出(UDP),内核才选择一个本地IP地址。strictsockaddr_inaddr;intport=1234;intopt=SO_REUSEADDR;setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));bzero(&server,sizeof(server));addr.sin_family=AF_INET;addr.sin_addr.s_addr=htonl(INADDR_ANY);addr.sin_port=htons(port);if(bind(fd,(structsockaddr*)&addr,sizeof(addr))==-1){/*错误处理*/}4.listen()监听函数#includesys/socket.hintlisten(intsockfd,intbacklog)返回:0-成功;-1-出错并置errno值;Sockfd:要设置的描述符backlog:规定请求队列中的最大连续数,对队列中等待服务请求的数目进行了限制函数listen仅被服务器调用,它完成两件事情:函数listen将未连接的套接字转化成被动套接字,指示内核应接受指向此套接字的连接请求;函数的第二个参数规定了内核为此套接字排队的最大连接个数;对于给定的监听套接字,内核要维护两个队列未完成连接队列已完成连接队列两个队列之和不超过backlog;在TCP三次握手中监听套接字两个队列的位置如下图所示5.connect()连接函数#includesys/socket.hintconnect(intsockfd,conststructsockaddr*addr,socklen_taddrlen);返回:0-成功;-1-出错;Sockfd:套接字描述符addr:指向服务器套接字地址结构的指针addrlen:套接字地址结构的大小函数connect激发TCP的三路握手过程;仅在成功或出错返回;错误有以下几种情况:(1)如果客户没有收到SYN分节的响应,则返回ETIMEDOUT。(2)如果对客户的SYN的响应是RST,则表明该服务器主机在指定的端口上没有进程在等待与之相连。函数返回错误ECONNREFUSED;(3)如果客户发出的SYN在中间路由器上引发一个目的地不可达ICMP错误,客户上的内核保存此消息,并按第一种情况,连续发送SYN,直到规定时间,返回保存的消息(即ICMP错误)作为EHOSTUNREACH或ENETUNREACH错误返回给进程6.accept()#includesys/socket.hintaccept(intsockfd,structsockaddr*cliaddr,socklen_t*addrlen);返回:[非负描述字(connfd)]1,0-OK;-1-出错;Listenfd:套接字描述符cliaddr:套接字地址结构addrlen:套接字地址结构长度accept函数由TCP服务器调用;从已完成连接队列头返回下一个已完成连接;如果该队列空,则进程进入睡眠状态。函数返回的套接字为已连接套接字,应与监听套接字区分开来【该函数最多返回三个值:一个既可能是新套接字也可能是错误指示的整数,一个客户进程的协议地址(由cliaddr所指),以及该地址的大小(这后两个参数是值-结果参数);也就是说,】服务器可以通过参数cliaddr来得到请求连接并获得成功的客户的地址和端口号;7.close()#includeunistd.hintclose(intsockfd);返回:0-OK;-1-出错;Sockfd:要关闭的描述符close函数缺省功能是将套接字做上“已关闭”标记,并立即返回到进程。这个套接字不能再为该进程所用。正常情况下,close将引发向TCP的四分节终止序列,但在终止前将发送已排队的数据;如果套接字描述符访问计数在调用close后大于0(在多个进程共享同一个套接字的情况下),则不会引发TCP终止序列(即不会发送FIN分节);8.Shutdown()#includesys/socket.hintshutdown(intsockfd,inthowto);返回:0-OK;-1-出错,并置相应的errno的值;Sockfd:要关闭的套接字描述符该函数立即发送FIN分节。shutdown根据参数howto关闭指定方向的数据传输;SHUT_RD:关闭连接的读这一半,不再接收套接字中的数据且现留在接收缓冲区的数据作废;SHUT_WD:关闭连接的写这一半(半关闭),当留在套接字发送缓冲区中的数据都被发送,后跟tcp连接终止序列,不管访问计数是否大于0;此后将不能在执行对套接字的任何写操作;SHUT_RDWR:连接的读、写都关闭,这等效于调用shutdown两次,一次调用是用SHUT_RD,第二次用SHUT_WR。9.Read()函数#includeunistd.hintread(intfd,char*buf,intlen);返回:大于0-读写字节大小;-1-出错;调用函数read时,有如下几种情况:套接字接收缓冲区接收数据,返回接收到的字节数;tcp协议收到FIN数据,返回0;tcp协议收到RST数据,返回-1,同时errno为ECONNRESET;进程阻塞过程中接收到信号,返回-1,同时errno为EINTR。read(connfd,buff,strlen(buff));10.write()函数#includeunistd.hintwrite(intfd,char*buf,intlen);返回:大于0-读写字节大小;-1-出错;Buf:用于发送信息的缓冲区len:缓冲区大小调用函数write,有如下几种情况:套接字发送缓冲区有足够空间,返回发送的字节数;tcp协议接收到RST数据,返回-1,同时errno为ECONNRESET;;进程阻塞过程中接收到信号,返回-1,同时errno为EINTR。write(connfd,buff,strlen(buff));11.send()发送函数#includesys/types.h#includesys/socket.hssize_tsend(intfd,constvoid*msg,size_tlen,intflags);返回:非0-发送成功的数据长度;-1-出错;flags是传输控制标志,其值定义如下:0:常规操作,如同write()函数MSG_OOB,发送带外数据(TCP紧急数据)。MSG_DONTROUTE:忽略底层协议的路由设置,只能将数据发送给与发送机处在同一个网络中的机器上。12.recv()接收函数#includesys/types.h#includesys/socket.hssize_trecv(intfd,void*buf,size_tlen,intflags);返回:大于0表示成功接收的数据长度;0:对方已关闭,-1:出错。flags是传输控制标志,其值定义如下:0:常规操作,如同read()函数;MSG_PEEK:只查看数据而不读出数据,后续读操作仍然能读出所查看的该数据;MSG_OOB:忽略常规数据,而只读带外数据;MSG_WAITALL:re
本文标题:Linux&Unix网络编程复习资料
链接地址:https://www.777doc.com/doc-5691040 .html