Unix网络编程_9-_高级socket编程

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Unix网络编程第九讲高级socket编程内容提要高级IO函数NonblockingIO信号驱动IOUnixdomainsocket高级IO函数read/recv/readv/recvmsgwrite/send/writev/sendmsgrecvmsg/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仍然可能返回少于指定数目的数据:asignaliscaughttheconnectionisterminatedanerrorispendingforthesocket.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*/};NonblockingIOBydefault,socketsareblockingblockingsocket操作输入read,readv,recv,recvfrom,andrecvmsg输出write,writev,send,sendto,andsendmsg接受连接请求accept连接请求connectBlockingI/OModelBlockingreadvs.nonblockingreadBlockingreadTCP,如果没有数据,阻塞;如果哪怕有一个Byte的数据,可以返回,除非设置了MSG_WAITALL标志UDP,如果没有报文到达,阻塞;有一个报文到达,返回Nonblockingread如果有数据,返回;否则,立即返回,指示错误EWOULDBLOCKBlockingwritevs.nonblockingwriteBlockingwriteTCP,写操作相当于将应用程序的数据拷贝到内核的socketsend缓冲区。如果send缓冲满,操作阻塞;否则,返回实际拷贝的数据长度(可能比预期的短)UDP,不会阻塞NonblockingwriteTCP,如果send缓冲区满,立即返回,指示错误EWOULDBLOCKAccept:Blockingvs.nonblockingaccept就是应用程序从内核的连接队列中取出一个ESTABLISHED连接【回忆】Blockingaccept如果有ESTABLISHED连接,返回之;否则,阻塞Nonblockingaccept如果没有,立即返回,指示错误EWOULDBLOCKConnect:Blockingvs.nonblockingconnect的任务是完成三次握手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.cweb.hhome_page.cstart_connect.cwrite_get_cmd.c信号驱动IOSIGIORTSignalSIGIO信号的发生条件SIGIOwithUDPSocketssocket上有一个数据报文到达Socket上发生一个异步错误SIGIOwithTCPSockets在监听socket上有一个连接请求完成连接拆卸请求启动连接拆卸请求完成半连接关闭shutdownSocket上有数据到达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_LOCALunpv103e/unixdomain/unixbind.cstructsockaddr_un{sa_family_tsun_family;/*AF_LOCAL*/charsun_path[108];/*null-terminatedpathname*/};

1 / 32
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功