ImageVerifierCode 换一换
格式:DOCX , 页数:66 ,大小:221.61KB ,
资源ID:20199237      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/20199237.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(10网络编程Word格式.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

10网络编程Word格式.docx

1、数据报套接字(Datagram Sockets)这种套接字所提供的通信方式并不可靠,即不能保证所传送的数据包一定合法,也不能保证数据包接收顺序与发送顺序完全一致,甚至数据包是否能够安全传送到目的端都不能保证。由于系统提供的数据报套接字功能有限,因此我们必须在编程时充分考虑各种可能出现的异常情况,例如,如何控制数据包发送和接收顺序,如何保证数据包不被重复发送,另外如何数据包没有发送应该如何处理,这些工作就需要我们自已完成了。更重要的是,在编写复杂的网络应用程序时,还必须考虑数据报的可靠性,因为如果只依赖于系统提供的支持,数据报套接字的可靠性是极差的,如果一个大型的网络通信应用程序经常出现崩溃,那

2、么带来的损失将是不可估量的。数据报套接字的主要用途是以广播方式发送数据,如记录型数据等。流式套接字(Stream Sockets)流式套接字的含义是数据发送后,需要按顺序而且不重复地由目的端接收。这是一种可靠的数据传输方式,对于单个的数据报,以及完整的数据包,流式套接字都可以提供这种面向连接的数据传输。流式套接字的使用要广泛得多,特别是对于大量的数据发送,或要求数据接收顺序时,都需要使用流式套接字。在使用套接字进行网络编程时,有一个非常重要的概念即套接字的端口。在Internet 上每一个站点都有相应的数字化地址,我们称之为 IP 地址。形式一般为 NUM1.NUM2.NUM3.NUM4 即用

3、小数点分隔的 4个数字,如 198.53.145.3。如果通过网络,有一个请求发到198.53.145.3对应的主机上,此请求将附带一个端口号信息,端口号是一个整数值,它标识了所请求的应用程序。必须注意,有一些端口是系统为标准应用预留的,如端口80 主要用于 Web 服务器监听客户应用程序如 Netscape Navigator 浏览器发出的 Web 文档请求。有一些应用程序在设计信息发送时并不是基于连接的,但这种发送方式是没有保障的,即我们不能确定数据确实发送出去了,也不能确定数据接收方的身份。不过对于一些广播性质的信息发送,这种方式是比较适合的。如典型的时间服务,时间服务器将当前时间发送给

4、其所在范围内的每一台机器,至于对方是否接收,或对方接收到时间信息后作何响应,时间服务器都不关心。我们在应用程序中所使用的套接字一般是基于连接的,即两个应用程序各自生成一个套接字,这样在两个对应的套接字之间就建立了一个连接,两个应用程序就是连接的两端。如果已经建立了连接,意味着两端的应用程序可以在此通路上发送和接收信息了。需要注意的是,在两个端点间建立连接会带来一定的时间延迟,一般来讲,延迟影响并不大,但对于实时性要求比较高的信息传送而言,就不太适合了,因此也可以考虑无连接的通信方式。102 MFC Winsock 类类 起初,在 Visual C+中用套接字编程就意味着需要调用套接字动态连接库

5、 DLL 中的相关 API接口函数,即所有的功能的以函数为单位实现的。提出面向对象概念之后,为了方便程序的编写和维护,需要自己建立套接字类,利用套接字类来封装有关套接字的特点和方法。不过从 Visual C+2.1 版本以后,系统就已经提供了两个新的类来专门管理套接字,即 CAsyncSocket 及其子类 CSocket。在此之后使用套接字就有了更为抽象的接口,而且类似于套接字对象的初始化和撤销等工作是我们比较容易忽略的,使用套接字对象就可以帮助我们自动完成。我们知道,Windows 应用程序是异步实现的,在同一时间内可以同时完成多项任务,在老版本的 Windows 操作系统环境下,如果一个

6、应用程序陷入了循环,或者由于某种原因处于挂起状态,那么其后果可能造成整个系统都陷入循环或挂起状态。显然我们需要尽量克服这种现象发生,但是对于一个套接字发出的请求,通常是要求通过TCP/IP 连接从而获得在 Internet 上另一个站点的信息,信息的接收过程往往需要很长的时间完成,此时我们认为用来发送或接收信息的套接字函数就被阻塞了。对于这个问题,可以有 3种解决方法:创建线程 创建一个线程,并将可能出现阻塞的套接字函数在此线程中完成,如果函数确实阻塞了,那么只会导致它所在的线程处于等待状态,而不会影响到整个应用程序。这种方法是在线程思想得到发展之后出现的,最近才得到广泛使用。轮询套接字状态

7、在编写程序时,需要发出请求时,我们可以设置一个函数,其功能是一旦请求发送出去,就返回相应的确认信息,同时我们可以设置另一个函数,它的功能是与第一个函数相对应的,即不断地通过轮询套接字,来查看请求是否发送出去。由于我们需要通过轮询的方式查看套接字状态,因此这种方法的效率是相当低的,需要浪费大量的处理时间进行检查,而不是完成具体的工作。发送消息 最后一种方法同样是通过设计函数实现对套接字状态的检查和管理,首先设置一个函数,其功能是请求一旦发送,就返回相应的确认信息,另外在请求结束时向Windows 提交一个窗口消息。目前,这种方法是最常用的,我们完全可以利用 CAsyncSocket 类完成这一工

8、作。例如,要向 Internet 上另一个站点发送一条串信息,这个过程要通过已建立连接的套接字完成,那么我们可以调用套接字的 Send()函数实现,Send()函数本身并不一定能够发送具体数据,如果发现套接字并没有准备好,或者处于等待状态,Send()函数将立刻返回,如果套接字确实已经准备好,就会向套接字发送相关的消息,而套接字就会捕获这条消息,从而获得相就的数据,即前面所要求发送的串信息,这个过程虽然简单,但可以充分体现异步 Winsock 应用程序的原理。虽然 Winsock的原理很好理解,而且利用 AppWizard 我们就可以要求系统为我们实现一个最基本的 Winsock 应用程序。但

9、在实际应用中,使用 Winsock 编写网络应用程序,实现较为复杂的通信功能则是一项比较困难的工作。在具体实现 Winsock 应用程序前,我们先来分析 CAsyncSocket 和 CSocket 类的属性和方法。1021 CAsyncSocket CAsyncSocket 类的工作实际上就是封装了对异步 Winsock 调用的处理,其定义如下:class CAsyncSocket:public CObject DECLARE_DYNAMIC(CAsyncSocket);private:CAsyncSocket(const CAsyncSocket&rSrc);/no implementat

10、ion void operator=(const CAsyncSocket&/no implementation/Construction public:CAsyncSocket();BOOL Create(UINT nSocketPort=0,int nSocketType=SOCK_STREAM,long lEvent=FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE,LPCTSTR lpszSocketAddress=NULL);/Attributes public:SOCKET m_hSocket;operator SOCKET

11、()const;BOOL Attach(SOCKET hSocket,long lEvent=FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE);SOCKET Detach();BOOL GetPeerName(CString&rPeerAddress,UINT&rPeerPort);BOOL GetPeerName(SOCKADDR*lpSockAddr,int*lpSockAddrLen);BOOL GetSockName(CString&rSocketAddress,UINT&rSocketPort);BOOL GetSockNa

12、me(SOCKADDR*lpSockAddr,int*lpSockAddrLen);BOOL SetSockOpt(int nOptionName,const void*lpOptionValue,int nOptionLen,int nLevel=SOL_SOCKET);BOOL GetSockOpt(int nOptionName,void*lpOptionValue,int*lpOptionLen,int nLevel=SOL_SOCKET);static CAsyncSocket*PASCAL FromHandle(SOCKET hSocket);static int PASCAL G

13、etLastError();/Operations public:virtual BOOL Accept(CAsyncSocket&rConnectedSocket,SOCKADDR*lpSockAddr=NULL,int*lpSockAddrLen=NULL);BOOL Bind(UINT nSocketPort,LPCTSTR lpszSocketAddress=NULL);BOOL Bind(const SOCKADDR*lpSockAddr,int nSockAddrLen);virtual void Close();BOOL Connect(LPCTSTR lpszHostAddre

14、ss,UINT nHostPort);BOOL Connect(const SOCKADDR*lpSockAddr,int nSockAddrLen);BOOL IOCtl(long lCommand,DWORD*lpArgument);BOOL Listen(int nConnectionBacklog=5);virtual int Receive(void*lpBuf,int nBufLen,int nFlags=0);int ReceiveFrom(void*lpBuf,int nBufLen,CString&rSocketPort,int nFlags=0);int ReceiveFr

15、om(void*lpBuf,int nBufLen,SOCKADDR*lpSockAddr,int*lpSockAddrLen,int nFlags=0);enum receives=0,sends=1,both=2;BOOL ShutDown(int nHow=sends);virtual int Send(const void*lpBuf,int nBufLen,int nFlags=0);int SendTo(const void*lpBuf,int nBufLen,UINT nHostPort,LPCTSTR lpszHostAddress=NULL,int nFlags=0);int

16、 SendTo(const void*lpBuf,int nBufLen,const SOCKADDR*lpSockAddr,int nSockAddrLen,int nFlags=0);BOOL AsyncSelect(long lEvent=FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE);/Overridable callbacks protected:virtual void OnReceive(int nErrorCode);virtual void OnSend(int nErrorCode);virtual void O

17、nOutOfBandData(int nErrorCode);virtual void OnAccept(int nErrorCode);virtual void OnConnect(int nErrorCode);virtual void OnClose(int nErrorCode);/Implementation public:virtual CAsyncSocket();static CAsyncSocket*PASCAL LookupHandle(SOCKET hSocket,BOOL bDead=FALSE);static void PASCAL AttachHandle(SOCK

18、ET hSocket,CAsyncSocket*pSocket,BOOL bDead=FALSE);static void PASCAL DetachHandle(SOCKET hSocket,BOOL bDead=FALSE);static void PASCAL KillSocket(SOCKET hSocket,CAsyncSocket*pSocket);static void PASCAL DoCallBack(WPARAM wParam,LPARAM lParam);BOOL Socket(int nSocketType=SOCK_STREAM,long lEvent=FD_READ

19、|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE,int nProtocolType=0,int nAddressFormat=PF_INET);#ifdef _DEBUG virtual void AssertValid()const;virtual void Dump(CDumpContext&dc)const;#endif protected:friend class CSocketWnd;virtual BOOL ConnectHelper(const SOCKADDR*lpSockAddr,int nSockAddrLen);virtual

20、 int ReceiveFromHelper(void*lpBuf,int nBufLen,SOCKADDR*lpSockAddr,int*lpSockAddrLen,int nFlags);virtual int SendToHelper(const void*lpBuf,int nBufLen,const SOCKADDR*lpSockAddr,int nSockAddrLen,int nFlags);CAsyncSocket 类有一组非常有用的成员函数:Accept 函数在一个监听套接字端处理连接请求,即处理一个可能建立的连接,一旦建立连接,就写入相应的套接字地址信息。这里参数 rCon

21、nectedSocket 为监听套接字,lpSockAddr 即为套接字地址,其初始值为空,一旦连接建立,则将套接字实际地址通过 lpSockAddr 返回,另外 lpSockAddrLen 为套接字地址的长度。AsyncSelect 函数的作用是在套接字准备好之后,发出请求要求发送消息,消息的类型如表 10.1所示:表 10.1 消息类型 类型 值 FD_READ 0 x01 FD_WRITE 0 x02 FD_OOB 0 x04 FD_ACCEPT 0 x08 FD_CONNECT 0 x10 FD_CLOSE 0 x20 BOOL Attach(SOCKET hSocket,long l

22、Event=FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE);Attach函数的作用是将一个套接字句柄连接到一个 CAsyncSocket 对象实例上,即建立二者的关联,这样就可以实现与另一台计算机的连接了。这里 hSocket 即为套接字句柄,其相关的消息类型与 AsyncSelect 相同。Bind 函数可以建立一个地址与套接字的关联,一般我们称之为绑定。可以有两种调用形式,其一是提供套接字端口和地址,而且地址是以串作为参数类型的。这种方法比较常用。另一种是提供 SOCKADDR 结构类型的地址参数。Close函数就是关闭套接字。

23、Connect 函数可以建立套接字与远程地址和端口的连接,这个函数在 WinSock 应用程序中必须出现。调用方式也有两种:其一是提供套接字端口和地址,而且地址是以串作为参数类型的。在调用 CAsyncSocket 构造函数之后,需要由 Create 函数实现具体的初始化工作。Detach函数的作用是将上一次建立关联的套接字句柄断开,并返回此套接字句柄。FromHandle函数参数将指定一个套接字句柄,其作用是返回与此套接字关联的CAsyncSocket 对象指针 static int PASCAL GetLastError();GetLastError函数将返回套接字错误代码,在实际应用中需

24、要在操作失败后调用此函数以查找错误原因。指定套接字,调用 GetPeerName 函数就可以找到与之对应的远程套接字的 IP 地址和端口号。远程套接字的 IP 地址和端口号可以分别由参数 rPeerAddress 和 rPeerPort 返回,也可以由指向 SOCKADDR 结构的参数 lpSockAddr返回。GetSockName与 GetPeerName 函数的作用类似,但更为简单一些,即指定套接字,则返回其 IP 地址和端口号。IP 地址和端口号可以分别由参数 rPeerAddress 和rPeerPort返回,也可以由指向 SOCKADDR 结构的参数 lpSockAddr返回。Ge

25、tSockOpt 函数和 SetSockOpt 函数的作用是对套接字状态的存取,对于SetSockOpt 而言。当前设置的套接字状态由参数 lpOptionValue确定。而对于GetSockOpt 函数,可以由参数 lpOptionValue得到套接字状态。IOCtl 的作用是设置套接字的模式,一般来说,主要有两种模式,即阻塞和非阻塞。Listen 函数的作用为监听,即构造一个套接字以查看是否需要建立连接。OnAccept 是一个需重载的回调函数,当一个套接字可能需要与另一端建立连接时,可以调用此函数处理相应的消息。OnClose是一个需重载的回调函数,当一个套接字关闭时,可以调用此函数处理相应的消息。OnConnect 是一个需重载的回调函数,当一个套接字成功建立连接,或者连接失败时,可以调用此函数处理相应的消息。OnOutOfBandData是一个需重载的回调函数,如果一些非常急需的数据已经准备好,就会发出相应的消息,这一类消息的处理需要由 OnOutOfBandData 完成。OnReceive是一个需重载的回调函数,当一个套接字

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1