1.7.4 释放套接字资源
因为无连接协议没有连接,所以也不会有对连接的正式关闭和从容关闭。在接收端或发送端完成收发数据时,它只需要在套孩了句柄上调用 closesockel 函数,使可释放为套接字分配的所有相关资源。
1.8 其他API函数
本小节介绍其他几个 Winsock API 函数,它们在网络应用程序中非常有用
1.8.1 getpeername
该函数用于获得通信方的套接字地址信息,该信息是关于已建立连接的那个套接字的。它的定义如下:
int getpeername ( SOCKET S, struct sockaddr FAR* name, int FAR* namelen)
第1个参数是准备连接的套接字,后两个参数则是指向下层协议类型的SOCKADDR 结构及其长度的指针。对数据报套接字来说,这个函数返回的是传递到连接调用的那个地址:但不会返回传递到sendto或WSASendTo 调用的那个地址。
1.8.2 getsockname
该函数是对应 getpeername 的雨数。它返回的是给定接字的本地接 的地址信息。
它的定义如下
int getsockname( SOCKET S, struct sockaddr FAR*name, int FAR* namelen, )
除了套接字 s 返回的地址信息是本地地址信息外,其参数和 getpeername 的参数都是一样的。在TCP 协议中,这个地址与监听特定端口及 IP 接口的那个服务器套接字是一样的。
1.8.3 WSADuplicateSocket
WSADuplicateSocket 函数用来建立WSAPROTOCOLINFO 结构,该结构可传递到另一个进程这样就可用另个进程打开指向同一个下层套接字的句柄,如此一来,这个进程也能对该资源进行探作。
注意,这,点只在进程之间的操作时才必要,同一个进程中的线程可自由传递套接字描述符该函数的定义如下:
int WSADuplicatesocket( SOCKET S, DWORD dwProcessId, LPWSAPROTOCOL_INFO IpProtocolInfo )
第1个参数是准备复制的套字第 2个参数 dwPrcessld,是打算使所复制的会接字的进程的ID。第3个参数lpProtocolInfo,是–个指向WSAPROTOCOL INFO结构的指针,该结构包含目标进程打开复制句柄时所需的信息。为了使当前的进程能够把 WSAPROTOCOL INFO 结构传递给目标进程,然后月标进程再利用该结构建立·个指向指定套接字的句柄(利用 WSASocket 函数),必须考虑进程间通信。
两个套接字的描述符都可独立使用 I/O;但 Winsock 没有提供访问控制,因此这要由程序员决定是否执行某种同步。因为是复制的套接字描述符,而不是实际的套接字,所以所有描述符中都可见到关联到某个套接字的所有状态信息。比方说,对于描述符上由 setsocketopt 函数设置的任何一个套按字选项,都可通过任何一个或所有描述符利用 getsockopt 函数来查看它们。如果一个进程在一个复制的套接字上调用 closesocket,就会导致该进程中的描述符被释放:但在最后留下的那个描述符上调用closesocket 之前,下层套接宇会保持打开状态。
1.9 Windows CE
前面几个小节中的所有信息中也都可以应用于 Windows CE。惟一例外的是由于 Windows CE是建立在 Winsock 1.1 规范基上的,因此不能用 Winsock 2中特有的函数,比如用于收发数据、建立连接和接受连接的函数的 WSA 变体。Windows CE 平台上可用的 WSA 函数只有 WSAStartupWSACleanup、WSAGetLastError 和 WSAloctl,本章经对前 3 个函数进行了讨论 最后一个留到第7章作全面讲解。
Windows CE 支持 TCP/IP 协议,这意味着可以同时访 TCP 和UDP除了 TCP/IP 之外,它还支持红外线套接字。IrDA 协议只支持面向流的通信。
对这两个协议来说,所有的常用 Winsock 1.1 API函数调用都可用于创建和传输数据。惟一例外的操作是必须解决 Windows CE 2.0 内 UDP 数套字中的销误:即每次调用send sendto都会导致核心内存泄漏。这个错误在 Windows CE 2.1中已得到修复,但出上内核分散在 ROM 中,因此,目前还没有更新的软件可以像复 Widows CE 2.0 中的这一错。惟一的解决办法是不要在 Windows CE 2.0中使用数据报。
由于Windows CE 个支持控制台应用程序,而且只采用 UNICODE,所以本章介绍的示例都以Windows 95、Windows 98、Windows NT 平台为目标平台,举出这些例子的目的是让人家直接了解Winsock 的核心概念,用不着理会那些与 Winsock 无关的代码。除非此时正在编写 Windows CE 服务程序,否则几乎随时都需要一个用户界面,这样,使需要为窗口处理程序和其他用户界面元素编写若F新函数,而这样就违背了本书的初衷。除此以外还必须了解 UNICODE 和UNICODE 的 Winsock函数。至于传递给收发 Winsock 函数的指定字符串尼UNICODE 字符串还是ANSI字符串,则山程序员决定。只要传递的是一个效的缓冲,Winsock 就不会注意其内容(当然,可能需要对缓冲类型进行转换以抑制编详警告)。需要记住,如果把一个 UNICODE 字符串转换成 char*,那么准备发送多少字节的长度就应该对参数做出相应的调整。因为其他的 Widows 系统函数都要求 UNICODE 字符中所以在 Windows CE 中,如果打算把收到或发出的数据显示出来,必须考虑到它是不是 UNICODE,这样才能将它显示出米。总而言之,对于创建一个简单的 Winsock 应用程序而言,Windows CE 要复杂得多。
如果想在 Windows CE 上运行这些示例,只需要稍微修改 Winsok 代码即可,首先,头文件必须是WINSOCKH,而不是WINSOCK2.H为 Winsock 1.1 是适用于 Windows CE 的最新 Winsock 版本,所以WSAStartup 应该加它。
另外,Windows CE 不支持控制台应用程序,因而必须用WinMain来代 main。注意,这并不意味着需要把一个窗口合开到应用程序中,只意味着不能用 printf 这一类的控制台文本 I/O函数。
总结
本介绍了如何具体使用 TCP 和 UDP 协议以建立面向连接通信和无连接通信时所需的核心Winsock 函数。
针对面向连接通信,本演示了如何接受个客户机连接,以及怎样建立一个到服务器的客户机连接。
另外还介绍了面向会话的数据收发操作。针对无连接通信,本章也讲到了如何收发数据,由于本章的目的是介绍核心的 Wimsock API,因此并未考虑涉及网络编程性能方面的问题。
第6章将涉及性能方面的问题,并介绍微软 Winsock 的扩展,包括 TransmitFile、TransmitPackets、AcceptEx、GetAcceptExSockaddrs、ConnectEx、DisconnectE 以及 WSARecvMsg 等。
这些函数将有助于编写高性能、可升级的 Winsock 应用程序前面的讨论已经说明了如何用 Ipv4 协议来使用 WinSock,随后3 个章节将讲述 Winsock 结构的设计,并介绍其他可用协议的使用方法。
参考:
Microsoft Windows网络编程 第一章Winsock简介
私信回复:
windows网络编程pdf
可获得【Microsoft Windows网络编程】pdf版