




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Winsocket入门教程二非阻塞式服务器和客户端程序(TCP) Winsocket入门教程二非阻塞式服务器和客户端程序(TCP)收藏上次为大家介绍了阻塞式多线程服务端程序和阻塞式客户端程序的设计方法,但是在上文的最后也提到过,服务器程序会因为建立连接和关闭连接而频繁的创建和关闭线程会产生大量的内存碎片,从而导致服务端程序不能保证长时间的稳定运行。 因此我在这里为大家介绍另外一种建立服务器和客户端程序的方法,即建立非阻塞式的服务器和客户端程序。 那什么是非阻塞呢?非阻塞是相对于阻塞而言,阻塞指的是在进行一个操作的时候,如服务器接收客户端的连接(aept),服务器或者客户端读写数据(read、write),如果该操作没有执行完成(成功或者失败都算是执行完成),则程序会一直阻塞在操作执行的地方,直到该操作返回一个明确的结果。 而非阻塞式程序则不一样,非阻塞式程序会在产生阻塞操作的地方阻塞一定的时间(该时间可以由程序员自己设置)。 如果操作没有完成,在到达所设置的时间之后,无论该操作成功与否,都结束该操作而执行程序下面的操作。 为了执行非阻塞操作,我们在创建了一个套接口后,需要将套接口设置为非阻塞的套接口。 为了将套接口设置成为非阻塞套接口,我们需要调用ioctlsocket函数将套接口设置为非阻塞的套接口。 ioctlsocket函数的定义如下int ioctlsocket(SOCKET s,long cmd,u_long FAR*argp)该函数的作用是控制套接口的I/O模式。 参数s表示要设置的套接口;参数cmd表示要对该套接口设置的命令,为了要将套接口设置成为非阻塞的,我们应该填写FIONBIO;argp表示填写命令的值,如我们要将套接口设置成非阻塞的,我们需要将值设置成为1,如果我们要将套接口设置成为非阻塞状态的话,我们将值设置成为0就是了。 为了进行非阻塞的操作,我们需要在进行操作之前调用select函数,select函数的定义如下int select(int nfds,fd_set FAR*readfds,fd_set FAR*writefds,fd_set FAR*exceptfds,const structtimeval FAR*timeout);该函数设定一个或多个套接口的状态,并进行必要的等待,以便执行异步I/0(非阻塞)操作。 参数nfds被忽略,该参数的作用仅仅是为了与伯克利套接口相兼容;参数readfds表示要检测的可读套接口的集合(该参数可选,可为设置为NULL);参数readfds表示要检测的可写套接口的集合(该参数可选,可为设置为NULL);参数exceptfds表示要检测的套接口的错误(该参数可选,可为设置为NULL);参数timeout表示执行该函数时需要等待的时间,如果为NULL则表示阻塞操作,为0则表示立即返回。 下面让我们来看看参数类型fd_set,fd_set表示套接字的集合。 在使用select函数时,我们需要将相应的套接字加入到相应的集合中。 如果集合中的套接字有信号,select函数的返回值即为集合中有信号的套接字数量。 我们用下面的几个宏来操作fd_set集合。 我们可以使用FD_SET(s,*set)将套接字s加入到集合set中;我们可以使用FD_CLR(s,*set)将套接字s移除出集合set;我们可以使用FD_ZERO(*set)将集合set清空;最后,我们可以使用FD_ISSET(s,*set)来判断套接字s是否在集合中有信号。 接下来再让我们来看看select函数的三个集合参数readfds、writefds以及exceptfds。 readfds表示可读套接字的集合,可读套接字在三种情况下有信号出现 一、如果集合中有套接字处于监听状态,并且该套接字上有客户端的连接请求; 二、如果集合中的套接字收到了send操作发送过来的数据; 三、如果集合中的套接字被关闭、重置或者中断。 writefds表示可写套接字的集合,可写套接字在两种情况下有信号出现 一、集合中的套接字经过connect操作后,连接成功; 二、可以用send操作向集合中的套接字写数据。 exceptfds表示错误套接字的集合,错误套接字在两种情况下有信号出现 一、集合中的套接字经过connect操作后,连接失败; 二、有带外数据到来。 在我们了解了创建服务器和客户端程序的基础知识后,我们再来看看示例程序,以加深我们对知识的理解。 程序的运行结果如下所示下面是服务器程序的代码view plaincopyto clipboardprint?1.#include2.#include3.#include4.#include5.#pragma ment(lib,ws2_32.lib)6.#define ASSERTassert7.using std:cin;8.using std:cout;9.using std:endl;10.using std:list;11.typedef listSocketList;12.typedef list:iterator SocketListIterator;13.static const int c_iPort=10001;14.bool GraceClose(SOCKET*ps);15.int main()16.17.int iRet=SOCKET_ERROR;18./初始化Winsocket,所有Winsocket程序必须先使用WSAStartup进行初始化19.WSADATA data;20.ZeroMemory(&data,sizeof(WSADATA);21.iRet=WSAStartup(MAKEWORD(2,0),&data);22.ASSERT(SOCKET_ERROR!=iRet);23./建立服务端程序的监听套接字24.SOCKET skListen=INVALID_SOCKET;25.skListen=socket(AF_INET,SOCK_STREAM,0);26.ASSERT(INVALID_SOCKET!=skListen);27./初始化监听套接字地址信息28.sockaddr_in adrServ;/表示网络地址29.ZeroMemory(&adrServ,sizeof(sockaddr_in);30.adrServ.sin_family=AF_INET;/初始化地址格式,只能为AF_INET31.adrServ.sin_port=htons(c_iPort);/初始化端口,由于网络字节顺序和主机字节顺序相反,所以必须使用htons将主机字节顺序转换成网络字节顺序32.adrServ.sin_addr.s_addr=INADDR_ANY;/初始化IP,由于是服务器程序,所以可以将INADDR_ANY赋给该字段,表示任意的IP33./绑定监听套接字到本地34.iRet=bind(skListen,(sockaddr*)&adrServ,sizeof(sockaddr_in);35.ASSERT(SOCKET_ERROR!=iRet);36./使用监听套接字进行监听37.iRet=listen(skListen,FD_SETSIZE);/SOMAXCONN表示可以连接到该程序的最大连接数38.ASSERT(SOCKET_ERROR!=iRet);39.coutServer beganlistening.0)59.60.sockaddr_in adrClt;61.int iLen=sizeof(sockaddr_in);62.ZeroMemory(&adrClt,iLen);63.SOCKET s=aept(skListen,(sockaddr*)&adrClt,&iLen);64.ASSERT(INVALID_SOCKET!=s);65.sl.push_back(s);66.coutServer aepteda connection.The socketis0)85.86./读取套接字上的数据87.const int c_iBufLen=512;88.char szBufc_iBufLen+1=0;89.int iRead=SOCKET_ERROR;90.iRead=recv(*iter,szBuf,c_iBufLen,0);91.if(0=iRead)/读取出现错误或者对方关闭连接92.93.iRead=0?coutConnection shutdownat socket*iter0)4.5.sockaddr_in adrClt;6.int iLen=sizeof(sockaddr_in);7.ZeroMemory(&adrClt,iLen);8.SOCKET s=aept(skListen,(sockaddr*)&adrClt,&iLen);9.ASSERT(INVALID_SOCKET!=s);10.sl.push_back(s);11.coutServer aepteda connection.The socketis0)sockaddr_in adrClt;int iLen=sizeof(sockaddr_ZeroMemory(&adrClt,iLen);SOCKET s=aept(skListen,ASSERT(INVALID_SOCKET!=s)sl.push_back(s);cout=iRead)/读取出现错误或者对方关闭连接2.3.iRead=0?coutConnection shutdownatsocket*iter=iRead)/读取出现错误或者对方关闭连接iReiReASSview plaincopyto clipboardprint?1.sl.remove(INVALID_SOCKET);/删除无效的套接字,套接字在关闭后被设置为无效sl.remove(INVALID_SOCKET);/删除无效的套接字,套接接下来再让我们来看看客户端程序的代码。 view plaincopyto clipboardprint?1.#include2.#include3.#include4.#pragma ment(lib,ws2_32.lib)5.#define ASSERTassert6.using std:cin;7.using std:cout;8.using std:endl;9.static constchar c_szIP=;10.static constintc_iPort=10001;11.bool GraceClose(SOCKET*ps);12.int main()13.14.int iRet=SOCKET_ERROR;15./初始化Winsocket,所有Winsocket程序必须先使用WSAStartup进行初始化16.WSADATA data;17.ZeroMemory(&data,sizeof(WSADATA);18.iRet=WSAStartup(MAKEWORD(2,0),&data);19.ASSERT(SOCKET_ERROR!=iRet);20./建立连接套接字21.SOCKET skClient=INVALID_SOCKET;22.skClient=socket(AF_INET,SOCK_STREAM,0);23.ASSERT(INVALID_SOCKET!=skClient);24./初始化连接套接字地址信息25.sockaddr_in adrServ;/表示网络地址26.ZeroMemory(&adrServ,sizeof(sockaddr_in);27.adrServ.sin_family=AF_INET;/初始化地址格式,只能为AF_INET28.adrServ.sin_port=htons(c_iPort);/初始化端口,由于网络字节顺序和主机字节顺序相反,所以必须使用htons将主机字节顺序转换成网络字节顺序29.adrServ.sin_addr.s_addr=i_addr(c_szIP);/初始化IP,由于网络字节顺序和主机字节顺序相反,所以必须使用i_addr将主机字节顺序转换成网络字节顺序30./将套接口从阻塞状态设置到非阻塞状态31.unsigned longulEnable=1;32.iRet=ioctlsocket(skClient,FIONBIO,&ulEnable);33.ASSERT(SOCKET_ERROR!=iRet);34.fd_set fsWrite;35.TIMEVAL tv;36.tv.tv_sec=1;37.tv.tv_usec=0;38.coutClient beganto connectto theserver.szBuf;69.if(0=strcmp(exit,szBuf)70.71.break;72.73.FD_ZERO(&fsWrite);74.FD_SET(skClient,&fsWrite);75./如果集合fsWrite中的套接字有信号,则可以用send操作写数据76.iRet=select(1,NULL,&fsWrite,NULL,&tv);77.if(00);128.if(SOCKET_ERROR=iRet)129.130.r
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 离婚精神赔偿金计算与支付方式合同范本及纠纷处理
- 2025年新合同法规定
- 2025年新能源绿色金融政策与绿色能源产业政策支持研究报告
- 2025年大一病理学试卷及答案
- 2025年建筑施工安全管理信息化对施工现场安全管理的影响评估报告
- 2025年成人高考政治专升本试卷及答案
- 2025年新能源行业供应链风险管理数字化解决方案报告
- 2025年物理初中综合试卷及答案
- 2025年土地置换住宅合同
- 2025年智能助手市场人工智能语音交互系统开发可行性报告
- 六年级上册语文期末复习句子专项训练及答案
- 2019人教版高中英语选择性必修一UNIT 1 People of Achievement 单词表
- 电力变压器基础知识课件
- JJG 373-1997四球摩擦试验机
- GB/T 37785-2019烟气脱硫石膏
- GB/T 29343-2012木薯淀粉
- GB/T 16714-2007连续式粮食干燥机
- 班组长能力提升培训讲义课件
- 少先队大队委申请表
- 柴油机负荷特性曲线比较课件
- 技术核定单样表
评论
0/150
提交评论