Winsocket入门教程二:非阻塞式服务器和客户端程序.docx

上传人:lao****ou 文档编号:653629 上传时间:2024-03-19 格式:DOCX 页数:14 大小:48.92KB
下载 相关 举报
Winsocket入门教程二:非阻塞式服务器和客户端程序.docx_第1页
第1页 / 共14页
Winsocket入门教程二:非阻塞式服务器和客户端程序.docx_第2页
第2页 / 共14页
Winsocket入门教程二:非阻塞式服务器和客户端程序.docx_第3页
第3页 / 共14页
Winsocket入门教程二:非阻塞式服务器和客户端程序.docx_第4页
第4页 / 共14页
Winsocket入门教程二:非阻塞式服务器和客户端程序.docx_第5页
第5页 / 共14页
亲,该文档总共14页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《Winsocket入门教程二:非阻塞式服务器和客户端程序.docx》由会员分享,可在线阅读,更多相关《Winsocket入门教程二:非阻塞式服务器和客户端程序.docx(14页珍藏版)》请在第一文库网上搜索。

1、Wi1ISOCket入门教程二:非阻塞式服务器和客户端程序那什么是非堵塞呢?非堵塞是相关于堵塞而言,堵塞指的是在进行一个操作的时候,如服务器接收客户端的连接(accept),服务器或者者客户端读写数据(read、write),假如该操作没有执行完成(成功或者者失败都算是执行完成),则程序会一直堵塞在操作执行的地方,直到该操作返回一个明确的结果。而非堵塞式程序则不一样,非堵塞式程序会在产生堵塞操作的地方堵塞一定的时间(该时间能够由程序员自己设置)。假如操作没有完成,在到达所设置的时间之后,不管该操作成功与否,都结束该操作而执行程序下面的操作。为了执行非堵塞操作,我们在创建了一个套接口后,需要将套

2、接口设置为非堵塞的套接口。为了将套接口设置成为非堵塞套接口,我们需要调用ioct1socket函数将套接口设置为非堵塞的套接口。ioct1socket函数的定义如下:该函数的作用是操纵套接口的I/O模式。参数s表示要设置的套接口;参数cmd表示要对该套接口设置的命令,为了要将套接口设置成为非堵塞的,我们应该填写FIONBIO;argp表示填写命令的值,如我们要将套接口设置成非堵塞的,我们需要将值设置成为1,假如我们要将套接口设置成为非堵塞状态的话,我们将值设置成为0就是了。为了进行非堵塞的操作,我们需要在进行操作之前调用se1ect函数,se1ect函数的定义如下:该函数设定一个或者多个套接口

3、的状态,并进行必要的等待,以便执行异步I/O(非堵塞)操作。参数nfds被忽略,该参数的作用仅仅是为了与伯克利套接口相兼容;参数readfds表示要检测的可读套接口的集合(该参数可选,可为设置为NU11);参数readfds表示要检测的可写套接口的集合(该参数可选,可为设置为NU11);参数exceptfds表示要检测的套接口的错误(该参数可选,可为设置为NU11);参数timeout表示执行该函数时需要等待的时间,假如为NU11则表示堵塞操作,为。则表示立即返回。下面让我们来看看参数类型fd_set,fd_set表示套接字的集合。在使用se1ect函数时,我们需要将相应的套接字加入到相应的集

4、合中。假如集合中的套接字有信号,se1eCt函数的返回值即为集合中有信号的套接字数量。我们用下面的几个宏来操作fd_set集合。我们能够使用FD_SET(sz*set)将套接字s加入到集合set中;我们能够使用FD_C1R(sr*se。将套接字S移除出集合set;我们能够使用FD_ZERO(*set)将集合Set清空;最后,我们能够使用FD_ISSET(s,*set)来推断套接字S是否在集合中有信号。接下来再让我们来看看se1ect函数的三个集合参数readfds、writefds与eceptfdSoreadfds表示可读套接字的集合,可读套接字在三种情况下有信号出现:一、假如集合中有套接字处

5、于监听状态,同时该套接字上有来自客户端的连接请求;二、假如集合中的套接字收到了Send操作发送过来的数据;三、假如集合中的套接字被关闭、重置或者者中断。writefds表示可写套接字的集合,可写套接字在两种情况下有信号出现:一、集合中的套接字通过connect操作后,连接成功;二、能够用send操作向集合中的套接字写数据。eceptfds表示错误套接字的集合,错误套接字在两种情况下有信号出现:一、集合中的套接字通过COnr1eet操作后,连接失败;二、有带外数据到来。在我们熟悉了创建服务器与客户端程序的基础知识后,我们再来看看示例程序,以加深我们对知识的懂得。程序的运行结果如下所示:下面是服务

6、器程序的代码:1. #inc1ude2. #inc1ude3. #inc1ude4. #inc1ude5. #pragmacomment(1ib,ws2-32.1ib)6. #defineASSERTassert7. usingstd:cin;8. usingstd:cout;9. usingstd:end1;10. usingstd:1ist;11. typedef1istSocket1ist;12. typedef1ist:iteratorSocket1istIterator;13. staticconstintc_iPort=10001;14. boo1GraceC1ose(SOCKET

7、*ps);15. intmain()16. 17. intiRet=SOCKET_ERROR;18. 初始化WinSOCket,所有WinSOCket程序务必先使用WSAStartUP进行初始化19. WSADATAdata;20. ZeroMemory(&data,Sizeof(WSADATA);21. iRet=WSAStartup(MAKEWORD(2z0)f&data);22. ASSERT(SOCKET_ERROR!=iRet);23. /建立服务端程序的监听套接字24. SOCKETSk1isten=INVA1ID_SOCKET;25. Sk1isten=socket(AFJNET

8、zSoCK.STREAM,O);26. ASSERT(INVA1ID_SOCKET!=Sk1isten);27. /初始化监听套接字地址信息28. sockaddr_inadrServ;/表示网络地址29. ZeroMemory(&adrServzsizeof(sockaddr-in);30. adrServ.sin-fami1y=AF_INET;/初始化地址格式,只能为AFJNET31. adrServ.sin_port=htons(c_iPort);/初始化端口,由于网络字节顺序与主机字节顺序相反,因此务必使用htons将主机字节顺序转换成网络字节顺序32. adrServ.sin_add

9、r.s_addr=INADDR_ANY;初始化IP,由因此服务器程序,因此能够将INADDR_ANY赋给该字段,表示任意的IP33. /绑定监听套接字到本地34. iRet=bind(sk1istenz(sockaddr*)&adrServzsizeof(sockaddJin);35. ASSERT(SOCKET_ERROR!=iRet);36. /使用监听套接字进行监听37. iRet=1isten(sk1istenzFD_SETSIZE);/SOMAXCONN表示能够连接到该程序的最大连接数38. ASSERT(SOCKET_ERROR!=iRet);39. coutServerbegan

10、1istening.0)sockaddr-inadrC1t;inti1en=sizeof(sockaddr-in);ZeroMemory(&adrC1t,i1en);SOCKETs=accept(sk1istenz(sockaddr*)&adrC1tz&i1en);ASSERT(INVA1ID_SOCKET!=s);s1.push_back(s);coutnServeracceptedaconnection.Thesocketis,s0)78.79.for(Socket1istIteratoriter=s1.begin();iter!=si.end0;+iter)80.81./假如有数据可读,

11、则遍历套接字列表中的所有套接字82./检测出有数据可读的套接字83.iRet=FD_ISSET(*iterz&fsRead);84.if(iRet0)85.86./读取套接字上的数据87.constintc_iBuf1en=512;88.charszBufcJBuf1en+1=,0,;89.intiRead=SOCKET_ERROR;90.iRead=recv(*iterzszBufzc_iBuf1enz0);91.if(0=iRead)/读取出现错误或者者对方关闭连接92.93.iRead=0?coutConnectionshutdownatsocketu*iterend1:94.coutC

12、onnectionrecverroratsocket,*iterend1;95.iRet=GraceC1ose(&(*iter);/假如出错则关闭套接字96.ASSERT(iRet);97.)98.e1se99.100.szBufiRead=,0,;101.coutServerreevedmessagefromsocketn*itern:nszBufend1;102./创建可写集合103.FD_SETfsWrite;104.FD_ZERO(&fsWrite);105.FD_SET(*iterz&fsWrite);106./假如有数据可写,则向客户端发送数据107.iRet=se1ect(1,NU11,&fsWritezNU11,&tv);108.if(0iRet)109.110.intiWrite=SOCKET_ERROR;111. iWrite=send(*iterzszBuf,iRead,O);112. if(SOCKET_ERROR=iWrite)113. 114. coutSendmessageerroratsocket,*iter

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 应用文档 > 工作总结

copyright@ 2008-2022 001doc.com网站版权所有   

经营许可证编号:宁ICP备2022001085号

本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有,必要时第一文库网拥有上传用户文档的转载和下载权。第一文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知第一文库网,我们立即给予删除!



客服