您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > Unix网络编程_9-_高级socket编程
Unix网络编程第九讲高级socket编程内容提要高级IO函数NonblockingIO信号驱动IOUnixdomainsocket高级IO函数read/recv/readv/recvmsgwrite/send/writev/sendmsgrecvmsg/sendmsg最为通用,可以替代所有的其它函数read/write最简单,并且不限于socketrecv/send函数#includesys/socket.hssize_trecv(intsockfd,void*buff,size_tnbytes,intflags);ssize_tsend(intsockfd,constvoid*buff,size_tnbytes,intflags);Bothreturn:numberofbytesreadorwrittenifOK,–1onerror常见的flagsMSG_DONTWAIT标志对一个单独的I/O操作设定nonblocking模式,不必针对整个socket该I/O操作结束后,自动关闭nonblocking模式MSG_PEEK标志允许程序检查有多少数据可读不同于recv/recvfrom的是,数据仍然存放在socket缓冲区内MSG_WAITALL标志指示内核只有当指定数目的字节读取完毕,read才能够返回如果系统支持该标志,那么readn函数可以采用下面的宏代替:#definereadn(fd,ptr,n)recv(fd,ptr,n,MSG_WAITALL)即便指定了MSG_WAITALL,read仍然可能返回少于指定数目的数据:asignaliscaughttheconnectionisterminatedanerrorispendingforthesocket.readv/writev函数#includesys/uio.hssize_treadv(intfiledes,conststructiovec*iov,intiovcnt);ssize_twritev(intfiledes,conststructiovec*iov,intiovcnt);Bothreturn:numberofbytesreadorwritten,–1onerrorreadv/writev函数通用,不限于socket类似于read/write,但readv/writev允许一次调用读/写多个缓冲区这些操作习惯被称为scatterread(因为input被分散到多个应用程序缓冲区)和gatherwrite(因为多个缓冲区数据被收集到一个输出操作).readv/writev函数iovisapointertoanarrayofiovecstructuresIOV_MAX定义最大数组长度限制#includesys/uio.hssize_treadv(intfiledes,conststructiovec*iov,intiovcnt);ssize_twritev(intfiledes,conststructiovec*iov,intiovcnt);Bothreturn:numberofbytesreadorwritten,–1onerrorstructiovecstructiovec{void*iov_base;/*addressofbuffer*/size_tiov_len;/*sizeofbuffer*/};NonblockingIOBydefault,socketsareblockingblockingsocket操作输入read,readv,recv,recvfrom,andrecvmsg输出write,writev,send,sendto,andsendmsg接受连接请求accept连接请求connectBlockingI/OModelBlockingreadvs.nonblockingreadBlockingreadTCP,如果没有数据,阻塞;如果哪怕有一个Byte的数据,可以返回,除非设置了MSG_WAITALL标志UDP,如果没有报文到达,阻塞;有一个报文到达,返回Nonblockingread如果有数据,返回;否则,立即返回,指示错误EWOULDBLOCKBlockingwritevs.nonblockingwriteBlockingwriteTCP,写操作相当于将应用程序的数据拷贝到内核的socketsend缓冲区。如果send缓冲满,操作阻塞;否则,返回实际拷贝的数据长度(可能比预期的短)UDP,不会阻塞NonblockingwriteTCP,如果send缓冲区满,立即返回,指示错误EWOULDBLOCKAccept:Blockingvs.nonblockingaccept就是应用程序从内核的连接队列中取出一个ESTABLISHED连接【回忆】Blockingaccept如果有ESTABLISHED连接,返回之;否则,阻塞Nonblockingaccept如果没有,立即返回,指示错误EWOULDBLOCKConnect:Blockingvs.nonblockingconnect的任务是完成三次握手Blockingconnect如果三次握手没有完成,阻塞等待完成否则返回Nonblockingconnect如果三次握手没有完成,立即返回,指示错误EINPROGRESSSocketTimeouts采用alarm采用信号IO多路复用select可以管理多个filedescriptor可以精确到微秒SO_RCVTIMEO和SO_SNDTIMEOsocket选项新的选项,并且仅限于socketalarm例子参见unpv103e/lib/connect_timeo.cNonblockingread/writeSTDINSTDOUTTCPSOCKETEchoclient例子见unpv103e/nonblock/strclinonb.c缓冲区管理Nonblockingconnect其它处理和三次握手并发进行一个connect需要花费一个RTT的时间一个RTT时间可能在几ms(LAN)到几百ms甚至几秒(WAN)之间采用nonblockingconnect,多个连接建立过程可以同时进行.这在Webbrowsers中非常常见.采用select来等待连接建立,select可设置时间限制,减少等待connect超时的时间通常connect的超时从75秒到几分钟.如果不想等那么长时间,那就有必要采用nonblockingNonblockingconnect代码见unpv103e/lib/connect_nonb.cNonblockingconnect-Webclient见unpv103e/nonblock/web.cweb.hhome_page.cstart_connect.cwrite_get_cmd.c信号驱动IOSIGIORTSignalSIGIO信号的发生条件SIGIOwithUDPSocketssocket上有一个数据报文到达Socket上发生一个异步错误SIGIOwithTCPSockets在监听socket上有一个连接请求完成连接拆卸请求启动连接拆卸请求完成半连接关闭shutdownSocket上有数据到达Socket上有数据发送(i.e.,输出缓冲区有空间)有异步错误发生RTsignal-实时信号WhyRTsignal?信号驱动I/O处理多个连接时有些问题,程序无法知道是哪个socket有事件到达.POSIX实时信号(RTsignals)比较SIGIO做了重大改进首先,允许一个信号和一个描述符关联其次,信号在内核排队,实现事件驱动的机制但是,这个队列可能溢出,这时可能还需要SIGIO.UnixDomainsocket一种IPC机制,只能用于本机的进程之间通信.两种类型:Stream、Datagram可以用于进程之间传递文件描述符UnixDomainsocket#includesys/socket.h#includesys/un.hunix_socket=socket(PF_UNIX,type,0);error=socketpair(PF_UNIX,type,0,int*sv);UnixDomainAddress地址:AF_UNIX/AF_LOCALunpv103e/unixdomain/unixbind.cstructsockaddr_un{sa_family_tsun_family;/*AF_LOCAL*/charsun_path[108];/*null-terminatedpathname*/};
本文标题:Unix网络编程_9-_高级socket编程
链接地址:https://www.777doc.com/doc-4013161 .html