《的扩展特性》PPT课件.ppt_第1页
《的扩展特性》PPT课件.ppt_第2页
《的扩展特性》PPT课件.ppt_第3页
《的扩展特性》PPT课件.ppt_第4页
《的扩展特性》PPT课件.ppt_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第六章 Windows Sockets 2的扩展特性,Windows Sockets2概述,Windows sockets2是从Windows sockets1.1发展而来的,它主要是为了适应近年来网络技术的迅猛发展,特别是多媒体网络技术的迅速发展的需要,通过制定Windows Sockets2规范来提供一个与协议无关的、具有紧急网络传输能力的网络传输接口。 windows sockets2实际上是windows sockets1.1接口的一个超集,它在保持和windows sockets1.1完全向后兼容能力的同时,并扩展了windows sockets接口。,Winsock2同时使用多个传输协议,与windows sockets1.1应用程序的向后兼容性,源码的兼容性 #include #pragma comment (lib,”ws2_32”) 二进制的兼容性,重叠I/O,Windows Sockets 2引入了重叠I/O的概念并且要求所有的传输协议提供者都支持这一功能。重叠I/O仅能在由WSASocket()函数打开的插口上使用(使用WSA_FLAG_OVERLAPPED标记)。这种方式的使用将采用Win32建立的模型。 对于接收,应用程序使用WSARecv()函数或WSARecvFrom()函数来提供存放接收数据的缓冲区。如果数据在网络接收以前,应用程序已经提供了一个或多个数据缓冲区,那么接收的数据就可以立即被存放进用户缓冲区。这样可以省去使用recv()函数和recvfrom()函数时需要进行的拷贝工作。,如果在应用程序提供数据缓冲区时已经有数据到来,那么接收的数据将被立即拷贝进用户缓冲区。 如果数据到来时,应用程序没有提供接收缓冲区,那么网络将回到我们熟悉的同步操作方式传送来的数据将被存放进内部缓冲区,直到应用程序发出了接收调用并且提供了接收缓冲区,这时接收的数据就被拷贝进接收缓冲区。 这种做法会有一个例外:就是当应用程序使用setsockopt()函数把接收缓冲区长度置为了0。 在这种情况下,对于可靠传输协议,只有在应用程序提供了接收数据缓冲区后,数据才会被接收; 而对于不可靠传输协议,数据将会丢失。 对于发送的一方,应用程序使用WSASend()函数或WSASendTo()函数提供一个指向已填充了数据的缓冲区的指针。应用程序不应在网络使用完该缓冲区的数据以前以任何方式破坏该缓冲区的数据。,重叠发送和接收调用会立即返回。 如果返回值是0,那么表明了I/O操作已经完成,对应的完成指示也已经可以得到。 如果返回值是SOCKET_ERROR,并且错误代码是WSA_IO_PENDING,那么表明重叠操作已经被成功地初始化,今后发送缓冲区被用完或者接收缓冲区被填满时,将会有完成指示。 任何其他的错误代码表明了初始化没有成功,今后也不会有什么完成指示。 发送操作和接收操作都可以被重叠使用。 接收函数可以被多次调用,发出接收缓冲区,准备接收到来的数据。 发送函数也可以被多次调用,组成一个发送缓冲区队列。 要注意的是,应用程序可以通过按顺序提供发送缓冲区来确保一系列重叠发送操作的顺序,但是对应的完成指示有可能是按照另外的顺序排列的。同样的,在接收数据的一方,缓冲区是按照被提供的顺序填充的,但是完成指示也可能按照另外的顺序排列。,重叠I/O涉及的一些函数,WSACreateEvent:创建一个新的事件对象。 WSAEVENT WSACreateEvent (void); 返回值:如果函数成功,则返回值即是事件对象的句柄。如果函数失败,返回WSA_INVALID_EVENT。应用程序可通过调用WSAGetLastError()函数获取进一步的错误信息。 WSASetEvent:将指定的事件对象状态设置为有信号(signaled)。 BOOL WSASetEvent( WSAEVENT hEvent ); WSAResetEvent :将指定的事件对象状态清除为未置信号(nonsignaled)。 BOOL WSAResetEvent( WSAEVENT hEvent ); WSAOVERLAPPED结构体:它提供了重叠I/O操作的初始化和它后续完成过程之间的通信媒体。 typedef struct _WSAOVERLAPPED DWORD Internal; DWORD InternalHigh; DWORD Offset; DWORD OffsetHigh; WSAEVENT hEvent; WSAOVERLAPPED, *LPWSAOVERLAPPED;,WSAGetOverlappedResult:此函数返回指定插口上一个重叠操作的结果。 BOOL WSAGetOverlappedResult( SOCKET s, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags ); 参数: s:标识插口。这就是调用重叠操作(WSARecv()、 WSARecvFrom()、WSASend()、WSASendTo() 或 WSAIoctl())时指定的那个插口。 lpOverlapped:指向调用重叠操作时指定的WSAOVERLAPPED结构。 lpcbTransfer:指向一个32位变量,该变量用于存放一个发送或接收操作实际传送的字节数。 fWait:指定函数是否等待挂起的重叠操作结束。若为真TRUE则函数在操作完成后才返回。若为假FALSE且函数挂起,则函数返回FALSE,WSAGetLastError()函数返回 WSA_IO_INCOMPLETE。 lpdwFlags:指向一个32位变量,该变量存放完成状态的附加标志位。如果重叠操作为 WSARecv()或WSARecvFrom(),则本参数包含lpFlags参数所需的结果。,返回值: 如果函数成功,则返回值为真TRUE。它意味着重叠操作已经完成,lpcbTransfer所指向的值已经被刷新。应用程序可调用WSAGetLastError()来获取重叠操作的错误信息。 如果函数失败,则返回值为假FALSE。它意味着要么重叠操作未完成,要么由于一个或多个参数的错误导致无法决定完成状态。失败时,lpcbTransfer指向的值不会被刷新。应用程序可用WSAGetLastError()来获取失败的原因。,WSAWaitForMultipleEvents函数:只要指定事件对象中的一个或全部处于有信号状态,或者超时间隔到,则返回。 DWORD WSAWaitForMultipleEvents( DWORD cEvents, const WSAEVENT FAR *lphEvents, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable ); 参数: cEvents:指出lphEvents所指数组中事件对象句柄的数目。事件对象句柄的最大值为WSA_MAXIMUM_WAIT_EVENTS。 lphEvents:指向一个事件对象句柄数组的指针。 fWaitAll:指定等待类型。若为真TRUE,则当lphEvents数组中的所有事件对象同时有信号时,函数返回。若为假FALSE,则当任意一个事件对象有信号时函数即返回。在后一种情况下,返回值指出是哪一个事件对象造成函数返回。 dwTimeout:指定超时时间间隔(以毫秒计)。当超时间隔到,函数即返回,不论fWaitAll参数所指定的条件是否满足。如果dwTimeout为零,则函数测试指定的时间对象的状态,并立即返回。如果dwTimeout是WSA_INFINITE,则函数的超时间隔永远不会到。 fAlertable:指定当系统将一个输入/输出完成例程放入队列以供执行时,函数是否返回。若为真TRUE,则函数返回且执行完成例程。若为假FALSE,函数不返回,不执行完成例程。,返回值:如果函数成功,返回值指出造成函数返回的事件对象;如果函数失败,返回值为WSA_WAIT_FAILED;可调用WSAGetLastError()来获取进一步的错误信息。,重叠服务器实例(采用事件对象机制),1) 创建一个插口,开始在指定的端口上监听连接请求。 2) 接收一个进入的连接请求。 3) 为接收的插口新建一个WSAOVERLAPPED结构,并为该结构分配一个事件对象句柄。也将事件对象句柄分配给一个事件数组,以便稍后由WSAWaitForMultipleEvents函数使用。 4) 在插口上投递一个异步WSARecv请求,指定参数为WSAOVERLAPPED结构。注意函数通常会以失败告终,返回SOCKET_ERROR错误状态WSA_IO_PENDING(I/O操作尚未完成)。 5) 使用步骤3 )的事件数组,调用WSAWaitForMultipleEvents函数,并等待与重叠调用关联在一起的事件进入“已传信”状态(换言之,等待那个事件的“触发”)。 6) WSAWaitForMultipleEvents函数完成后,针对事件数组,调用WSAResetEvent(重设事件)函数,从而重设事件对象,并对完成的重叠请求进行处理。 7) 使用WSAGetOverLappedResult函数,判断重叠调用的返回状态是什么。 8) 在插口上投递另一个重叠WSARecv请求。 9) 重复步骤5 ) 8 )。,程序实例,完成例程,原理:“完成例程”是应用程序用来管理完成的重叠I/O请求的另一种方法。完成例程其实就是一个函数。最开始的时候,我们将其传递给一个重叠I/O 请求,在一个重叠I/O请求完成时由系统调用。它们的基本设计宗旨是通过调用者的线程,为一个已完成的I/O请求提供服务。除此以外,应用程序可通过完成例程,继续进行重叠I/O处理。 一个完成例程必须拥有下述函数原型: void CALLBACK CompletionROUTINE( IN DWORD dwError, /表明了一个重叠操作的完成状态是什么 IN DWORD cbTransferred, /在重叠操作期间,实际传输的字节量是多大 IN LPWSAOVERLAPPED lpOverlapped, /传递到最初的I/O 调用内的一个 / WSAOVERLAPPED 结构 IN DWORD dwFlags );,程序实例,重叠完成指示机制总结,int WSASend( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); int WSARecv( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );,事件对象模型(WSAEventSelect),WSAEventSelect函数:此函数指定一个与参数中提供的FD_XXX网络事件集合相关的事件对象。 int WSAEventSelect( SOCKET s, /插口的描述符 WSAEVENT hEventObject, /标识与网络事件相关的事件对象 long lNetworkEvents ); /指定应用程序感兴趣的FD_XXX /网络事件组合 说明:如同使用select函数一样,WSAEventSelect()函数常用来决定何时执行数据传送操作(如send或recv)能够获得预期的立即成功。,参数lNetworkEvents由下表所列值的“或”构成: 值 含义 FD_READ 期望在读准备好时接到通知 FD_WRITE 期望在写准备好时接到通知 FD_OOB 期望在带外数据到来时接到通知 FD_ACCEPT 期望在连接到来时接到通知 FD_CONNECT 期望在连接建立完成或多点通信”加入”(join)时接 到通知 FD_CLOSE 期望在插口关闭时接到通知,WSAEventSelect函数自动设置插口处于非阻塞模式,要将插口设置回阻塞模式,要使用ioctlsocket或WSAIoctl函数。 rc=WSAEventSelect(s,hEventObject1,FD_READ); rc=WSAEventSelect(s,hEventObject2,FD_WRITE); 为了取消一个插口上选择的网络事件及关联的事件对象,可以使用lNetworkEvents参数为0来调用WSAEventSelect函数,此时参数hEventObject忽略。 rc=WSAEventSelect(s,hEventObject,0);,为不同的网络事件指定不同的事件对象是不可能的,下面的代码第二 个调用将取消第一个调用的作用。,WSAEnumNetworkEvents函数:此函数检测所指定插口上网络事件的发生,清除内部网络事件纪录,如果参数hEventObject指定,则重置该事件对象。 int WSAEnumNetworkEvents( SOCKET s, /标识插口的描述符 WSAEVENT hEventObject, /标识需要复位的相关事件对象 LPWSANETWORKEVENTS lpNetworkEvents /一个WSANETWORKEVENTS结构的数组,它记录了发生的网 /络事件和相应的错误代码 ); 调用该函数后,插口的网络事件的内部纪录被拷贝到参数lpNetworkEvents指示的结构,随后网络事件的内部纪录被清除。如果参数hEventObject非空,则指定的事件对象也被重置。,其中结构WSANETWORKEVENTS定义如下: typedef struct _WSANETWORKEVENTS long lNetworkEvents; /指示什么样的FD_XXX网络事件已经发生 int iErrorCodeFD_MAX_EVENTS; /本数组包含相关的错误码,这些错误码按 /lNetworkEvents的事件位的位置索引排列 WSANETWORKEVENTS, *LPWSANETWORKEVENTS; 可以使用FD_READ_BIT,FD_WRITE_BIT等标识符做索引来定位数组iErrorCode中相应网络事件的错误码。 返回值:如果操作成功则返回0,否则,返回值SOCKET_ERROR。,程序实例,服务质量(QOS),Winodws Sockets 2中引入了服务质量(Quality of Service)机制,它的概念大致描述如下: 流规格描述了网络上单向数据流的特性的集合。 应用程序可以在调用WSAConnect函数发出连接请求时,或者在使用WSAIoctl函数的SIO_SET_QOS命令时,将一对流规格和一个插口连接起来(一个流规格对应一个方向)。 流规格以参数方式声明了应用程序所要求的服务的级别,并且为应用程序适应不同的网络条件提供了一套反馈机制如果应用程序要求的服务级别不能达到,应用程序是否愿意松动它的要求。,插口组,Windows Sockets 2引入了一个所谓插口组的概念。它允许应用程序通知底层的服务提供者一组特定的插口是相关的,它们享有一些特定的性质。组的特性包括了组内单个插口之间的相关特性和整个组的服务规范的特性。 WSASocket()函数和WSAAccept()函数可以用来在创建一个新的插口的同时显式的创建或者加入插口组。getsockopt()函数可以用来得到插口所属插口组的标志。,共享插口,为了在进程间共享插口,Windows Sockets 2引入了WSADuplicateSocket()函数。共享插口是通过对底层的插口创建附加的插口描述字实现的。 int WSADuplicateSocket( SOCKET s, DWORD dwProcessId, /指定使用共享插口的目标进程的ID LPWSAPROTOCOL_INFO lpProtocolInfo /服务提供者将协议信息结构的内容拷贝到此缓冲区 ); WSADuplicateSocket函数用来允许插口在多个进程间共享。源进程调用WSADuplicateSocket函数获得一个特定的WSAPROTOCOL_INFO结构,它使用进程间通信机制将此结构的内容传递给目的进程,目的进程使用这些信息调用WSASocket函数获得此复制插口的描述符。注意的是:一个特定的WSAPROTOCOL_INFO结构只能被目的进程使用一次。,一个建立并使用共享插口的典型流程,扩展的字节顺序转换例程,Windows Sockets 2并不假设对于所有协议,网络字节顺序都是相同的。所以Windows Sockets 2提供了一套把16位或者32位数字转换到网络字节顺序或者从网络字节顺序转换回来的例程。这些函数将插口句柄作为一个输入参数,这个插口有一个结构PROTOCOL_INFO和它相关联。在结构PROTOCOL_INFO的域NetworkByteOrder指明了需要的网络字节顺序是什么(目前或者是big_endian,或者是little_endian)。,分散/聚集方式I/O,WSASend(),WSASendTo(),WSARecv()和WSARecvFrom()函数都以应用程序缓冲区数组作为输入参数,因此它们可以进行分散/聚集方式(向量方式)的I/O操作。如果应用程序需要传送的信息除了信息体外还包含了一个或多个固定长度的头时,这种操作是很有用的。这些头在发送之前不需要由应用程序连接到一个连续的缓冲区中。同样的,在接收时,这些头会自动的分离到各自的缓冲区中。 如果接收时应用程序提供了多个缓冲区,当有数据到来时,操作就结束了,不论提供的缓冲区是否都被使用了。,WinSock 2中扩展的API函数,WSAAccept() accept()函数的扩展版本,它支持条件接收和插口分组。 SOCKET WSAAccept( SOCKET s, struct sockaddr FAR *addr, LPINT addrlen, LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData ); WSACloseEvent() 关闭一个打开的事件对象句柄。 WSAConnect() connect()函数的扩展版本,它支持连接数据交换和QOS规范。 int WSAConnect( SOCKET s, const struct sockaddr FAR *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS ); WSACreateEvent() 创建一个事件对象。 WSADuplicateSocket() 为一个共享插口创建一个新的插口描述字。,WinSock 2中扩展的API函数(续),WSAEnumNetworkEvents() 检查是否有网络事件发生。 int WSAEnumNetworkEvents( SOCKET s, WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents ); WSAEnumProtocols() 得到每个可以使用的协议的信息。 Int WSAEnumProtocols( LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer, ILPDWORD lpdwBufferLength ); WSAEventSelect() 把网络事件组合和一个事件对象连接。 int WSAEventSelect( SOCKET s, WSAEVENT hEventObject, long lNetworkEvents ); WSAGetOverlappedResult() 得到重叠操作的完成状态。 BOOL WSAGetOverlappedResult( SOCKET s, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags );,WSAGetQOSByName() 此函数根据一个命名模板初始化一个QOS结构。 BOOL WSAGetQOSByName( SOCKET s, LPWSABUF lpQOSName, LPQOS lpQOS ); WSAHtonl() htonl()函数的扩展版本。 int WSAHtonl( SOCKET s, u_long hostlong, u_long FAR *lpnetlong ); WSAHtons() htons()函数的扩展版本。 int WSAHtons( SOCKET s, u_short hostshort, u_short FAR *lpnetshort ); WSAIoctl() ioctlsocket()函数的允许重叠操作的版本。 int WSAIoctl( SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );,WinSock 2中扩展的API函数(续),WSAJoinLeaf() 在多点对话中加入一个叶节点。 SOCKET WSAJoinLeaf( SOCKET s, const struct sockaddr FAR *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, DWORD dwFlags ); WSANtohl() ntohl()函数的扩展版本。 int WSANtohl( SOCKET s, u_long netlong, u_long FAR *lphostlong ); WSANtohs() ntohs()函数的扩展版本。 int WSANtohs( SOCKET s, u_short netshort, u_short FAR *lphostshort );,WinSock 2中扩展的API函数(续),WSARecv() recv()函数的扩展版本。它支持重叠插口操作。 int WSARecv( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); WSARecvDisconnect() 终止插口的接收操作。如果插口是基于连接的,得到拆除数据。 int WSARecvDisconnect( SOCKET s, LPWSABUF lpInboundDisconnectData ); WSARecvFrom() recvfrom()函数的扩展版本。它支持重叠插口操作。 int WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct sockaddr FAR *lpFrom, LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );,WinSock 2中扩展的API函数(续),WSAResetEvent() 重新初始化一个数据对象。 BO

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论