WinSock网络编程指南.pdf

上传人:asd****56 文档编号:70322807 上传时间:2023-01-19 格式:PDF 页数:21 大小:270.69KB
返回 下载 相关 举报
WinSock网络编程指南.pdf_第1页
第1页 / 共21页
WinSock网络编程指南.pdf_第2页
第2页 / 共21页
点击查看更多>>
资源描述

《WinSock网络编程指南.pdf》由会员分享,可在线阅读,更多相关《WinSock网络编程指南.pdf(21页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、WinSock 网络编程Windows Sockets 是一套开放的、支持多种协议的 Windows 下的网络编程接口。现在的 Winsock 已经基本上实现了与协议无关,你可以使用 Winsock 来调用多种协议的功能,但较常使用的是 TCP/IP 协议。Winsockets 无疑是我们进行网络编程的利器。Winsocket 编程之 TCP/IP 体系结构一、什么是 TCP/IPTCP/IP指的是 Internet 上使用的两种网络协议:传输控制协议和网际协议;事实上,TCP 协诡计和 IP 协议只是一个称为 TCP/IP 协议族中的两种而已。TCP/IP协议族可以将各种操作系统和网络部件连

2、接起来,它能提供一种在各种系统间移动数据的标准方法。这些协议既可以用于 Internet 上,也可以用于专用网中。TCP/IP协议族中的协议为当今网络用户的各种服务提供数传输功能,这些服务包括:电子邮件的传送文件传输即时消息访问万维网开放式系统互联(OSI)参考模型OSI 参考模型用于对涉网络的各种技术进行标准化,它定义的七层结构代表了数据通信协议的基本结构。OSI 模型中的每一层都指定了特定的功能,它可以看作是各层紧挨着另一屋的一个栈。对于给定的层,它所提供的服务是由这一层的协议定义的。理解了 OSI 模型及其各层有助于理解 TCP/IP 网络中的各部分与应用程序之间是如何进行交互的。OSI

3、 模型栈的七层分别是:第 7 层(应用层),这是 OSI 模型的最高层,本层定义了应用程序与网络及其他系统之间的交互方式第 6 层(表示层),包含了部分操作系统的协议,这一层定义了信息的显示格式,数据加密和解释属于本层功能。第 5 层(会话层),协调端到端的通信,本层维护各种会话状态,提供安全、登录和管理功能。第 4 层(传输层),控制各系统之间的数据流,定义各种消息的数据结构,并进行差错校验。Web 浏览器的加密通常在本层实现。第 3 层(网络层),定义了系统间路由数据的各种协议,点到点通信发生在此层,确保数据到达正确的目的的主机。第 2 层(数据链路层或网络接口层),定义了局部网络环境(即

4、局域网)中从一个节点到另一节点发送和接收消息的规则。第 1 层(物理层媒体层),控制硬件的连接和字节流的编码,这是惟一涉及到网络节点间信息的物理传输的一层。ISO 的 OSI 对服务、接口和协议的概念区别十分明了,但它却没有真正的用户群。TCP/IP 模型对服务、接口和协议的概念区别不象 OSI 模型那样明晰,但很实用。对于 TCP/IP 而言,最重要的是应用层、传输层、网络层和数据链路层;这些层都有特定的协议与这关联,这些协议将在后面的章节中讨论。这些协议可以分为两大类:网络类和应用类(参见图 4-1)。OSI 参考模型Internet 协议族应用层FTP、TelnetSSH、SMTPHTT

5、P、NNTPNFS表示层SMB会话层RPC传输层TCP、UCP网络层IP数据链路层ARP物理层物理层协议图 4-1OSI 和 IP 协议栈TCP/IP 结构事实上并不严格遵循 OSI 模型。但当前关于如何使用分层模型来描述 TCP/IP 又没有一个统一的协定。一般承认 TCP/IP 比 7 层 OSI 模型层次少(3 到 5 层)。这里我们以 4 层 TCP/IP 结构进行讲解。TCP/IP 结构中忽略了 OSI 模型中的某些特征,只综合了部分相邻 OSI 层的特征并分离其它各层。信息由4 层结构中的应用层传送到物理层。当发送数据时,每层将其从上层接收到的信息作为本层数据,并在数据前添加控制信

6、息头,然后一起传送到下一层。每层的接收数据过程与以上发送过程正好相反,其中在数据被传送到上一层之前要将其控制信息头移去。TCP/IP4 层模型以及每层主要功能描述如下:应用层(Application Layer)TCP/IP 组中的应用层综合了 OSI 应用层、表示层以及会话层的功能。因此,在 TCP/IP 结构中,传输层以上的任何过程都称之为应用。在 TCP/IP 中,使用套接字(socket)和端口描述应用程序通信路径。大多数应用层协议与一个或多个端口号相关联。传输层(TransportLayer)TCP/IP 结构中包含两种传输层协议。其一传输控制协议(TCP),确保信息传输过程。其二用

7、户数据报协议(UDP),直接传输数据报,而不需要提供端对端可靠校验。两种协议对应不同的应用具有各自功能。IP 地址用来寻址指定的计算机或者网络设备,而 TCP 的端口号用来确定运行在目的设备上的哪个应用程序应该接受这个封包。端口号是 16 位的。连接的两端都要使用端口号,但没必要相同。网络层(Network Layer)TCP/IP 网络层中的主要协议是网际协议(IP)。所有网络层以下或以上的各层通信在跨越 TCP/IP 协议栈时,都必须通过 IP 完成。此外,网络层还包含部分支持性协议,如 ICMP,实施和管理路由过程。互联网使用 IP地址来唯一标志一台计算机。IP 地址可以通过软件分配给网

8、络接口,将 IP 地址和网络接口的MAC 地址关联在一起。为了使用 IP 寻址,关联的 MAC 地址需要保存起来,这由 ARP(地址解析协议)负责。每个主机都维护了一个记录 IP 和 MAC 地址对的清单。网络访问层(Network Access Layer)在 TCP/IP 结构中,网络访问层由数据链路层和物理层合并而成。TCP/IP 网络访问层并没有重新定义新标准,而是有效利用原有数据链路层和物理层标准。很多 RFC 中描述了 IP 如何使用数据链路协议并作为其接口界面,如以太网、令牌环、FDDI、HSSI 和ATM等。物理层中规定了硬件通信属性,但它不直接作为网络层及以上层的 TCP/I

9、P 协议的接口。这一层也称为介质访问控制层(MAC).例如网卡就属于这一层;以太网接口的各层都有不同的寻址方法,在 MAC 层,寻址是通过 MAC 号进行的。MAC 号是一个位的标志,它被硬性分配到每一个网络接口单元,它是由 IEEE 注册分配的,保证每个以太网结点都有世界唯一的号码。数据传输TCP/IP 协议的基本传输单位是数据包(datagram),TCP 协议负责把数据分成若干个数据包,并给每个数据包加上包头(就像给一封信加上信封),包头上有相应的编号,以保证在数据接收端能将数据还原为原来的格式,IP 协议在每个包头上再加上接收端主机地址,这样数据找到自己要去的地方(就像信封上要写明地址

10、一样),如果传输过程中出现数据丢失、数据失真等情况,TCP 协议会自动要求数据重新传输,并重新组包。总之,IP 协议保证数据的传输,TCP 协议保证数据传输的质量。TCP/IP 协议数据的传输基于 TCP/IP 协议的四层结构:应用层、传输层、网络层、接口层,数据在传输时每通过一层就要在数据上加个包头,其中的数据供接收端同一层协议使用,而在接收端,每经过一层要把用过的包头去掉,这样来保证传输数据的格式完全一致。与其他协议相比,TCP/IP 具有两大优点:它是一种轻量级的、实现成本比较低的协议。基于上述原因,TCP/IP 成为最受欢迎的协议。1983 年,TCP/IP 被集成到 BSD UNIX

11、4.2 发布版本中,然后很快又被集成到 UNIX的商业版本中,并且被纳为 Internet 的标准,沿用至今。今天,TCP/IP 得到了除 Internet 通信以外的广泛应用。例如企业内部网(Internet)通常都使 TCP/IP 来构建。在这些应用中,TCP/IP 显示出了其他网络协议无与伦比的优势。比如 TCP/IP 可以运行在各种各样的硬件和操作系统平台之上;使用 TCP/IP 可以快速方便地构建异构网络,实现 Macs、IBM 兼容机、大型机、SunUNIX 服务器、MIPS 各种类型机器的互联。这些机器可以通过一种通用的协议族进行通信,这也是 TCP/IP自问世以来能够长盛不衰的

12、原因。二、TCP/IP 体系结构与特点1、TCP/IP体系结构TCP/IP 协议实际上就是在物理网上的一组完整的网络协议。其中 TCP 是提供传输层服务,而 IP 则是提供网络层服务。TCP/IP包括以下协议:(结构如图 1.1)(图 1.1)IP:网间协议(Internet Protocol)负责主机间数据的路由和网络上数据的存储。同时为 ICMP,TCP,UDP 提供分组发送服务。用户进程通常不需要涉及这一层。ARP:地址解析协议(Address Resolution Protocol)此协议将网络地址映射到硬件地址。RARP:反向地址解析协议(ReverseAddressResoluti

13、on Protocol)此协议将硬件地址映射到网络地址ICMP:网间报文控制协议(Internet Control Message Protocol)此协议处理信关和主机的差错和传送控制。TCP:传送控制协议(Transmission Control Protocol)这是一种提供给用户进程的可靠的全双工字节流面向连接的协议。它要为用户进程提供虚电路服务,并为数据可靠传输建立检查。(注:大多数网络用户程序使用 TCP)UDP:用户数据报协议(User Datagram Protocol)这是提供给用户进程的无连接协议,用于传送数据而不执行正确性检查。FTP:文件传输协议(File Transf

14、er Protocol)允许用户以文件操作的方式(文件的增、删、改、查、传送等)与另一主机相互通信。SMTP:简单邮件传送协议(Simple Mail TransferProtocol)SMTP 协议为系统之间传送电子邮件。TELNET:终端协议(Telnet Terminal Procotol)允许用户以虚终端方式访问远程主机HTTP:超文本传输协议(Hypertext Transfer Procotol)TFTP:简单文件传输协议(Trivial File Transfer Protocol)2、TCP/IP特点TCP/IP 协议的核心部分是传输层协议(TCP、UDP),网络层协议(IP)

15、和物理接口层,这三层通常是在操作系统内核中实现。因此用户一般不涉及。编程时,编程界面有两种形式:一、是由内核心直接提供的系统调用;二、使用以库函数方式提供的各种函数。前者为核内实现,后者为核外实现。用户服务要通过核外的应用程序才能实现,所以要使用套接字(socket)来实现。图 1.2 是 TCP/IP协议核心与应用程序关系图。(图 1.2)三、专用术语1、套接字套接字是网络的基本构件。它是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连听进程。套接字存在通信区域(通信区域又称地址簇)中。套接字只与同一区域中的套接字交换数据(跨区域时,需要执行某和转换进程才能实现)。W

16、INDOWS 中的套接字只支持一个域网际域。套接字具有类型。WINDOWS SOCKET 1.1 版本支持两种套接字:流套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM)2、WINDOWS SOCKETS 实现一个 WINDOWS SOCKETS 实现是指实现了 WINDOWS SOCKETS 规范所描述的全部功能的一套软件。一般通过 DLL 文件来实现(WS2_32.DLL)3、阻塞处理例程阻塞处理例程(blocking hook,阻塞钩子)是 WINDOWS SOCKETS 实现为了支持阻塞套接字函数调用而提供的一种机制。4、多址广播(multicast,多点传送或组播

17、)是一种一对多的传输方式,传输发起者通过一次传输就将信息传送到一组接收者,与单点传送(unicast)和广播(Broadcast)相对应。练习题:Q1:请你分别划划 OSI 的七层网络结构图,和 TCP/IP 的五层结构图?OSITCP/IP第七层:Application第六层:Presentation第五层:Session第五层:Application第四层:Transport第四层:Transport第三层:Network第三层:Internet第二层:Data Link第二层:Data Link第一层:Physical第一层:PhysicalQ2:请你详细的解释一下 IP 协议的定义,在

18、哪个层上面,主要有什么作用?TCP 与 UDP 呢?Internet Protocol 协议是为跨越局域网和广域网环境的大规模互联网络而设计的世界标准的协议组。IP 协议工作在第三层,主要用于实现连接到互联网上的结点之间的通信。Q3:请问交换机和路由器分别的实现原理是什么?分别在哪个层次上面实现的?交换机工作在第二层,通过 MAC 地址进行数据帧的交换。路由器工作在第三层,通过最优路径来传输数据包。Winsocket 编程之套接字原理一、客户机/服务器模式在 TCP/IP 网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model)。该模式的建立基于以下两

19、点:1、非对等作用;2、通信完全是异步的。客户机/服务器模式在操作过程中采取的是主动请示方式:首先服务器方要先启动,并根据请示提供相应服务:(过程如下)1、打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求。2、等待客户请求到达该端口。3、接收到重复服务请求,处理该请求并发送应答信号。4、返回第二步,等待另一客户请求5、关闭服务器。客户方:1、打开一通信通道,并连接到服务器所在主机的特定端口。2、向服务器发送服务请求报文,等待并接收应答;继续提出请求3、请求结束后关闭通信通道并终止。二、基本套接字为了更好说明套接字编程原理,给出几个基本的套接字,在以后的篇幅中会给出更详细的使用

20、说明。1、创建套接字socket()功能:使用前创建一个新的套接字格式:SOCKET PASCAL FAR socket(int af,int type,int procotol);参数:af:通信发生的区域type:要建立的套接字类型procotol:使用的特定协议2、指定本地地址bind()功能:将套接字地址与所创建的套接字号联系起来。格式:intPASCALFARbind(SOCKET s,const struct sockaddr FAR*name,int namelen);参数:s:是由 socket()调用返回的并且未作连接的套接字描述符(套接字号)。其它:没有错误,bind()返

21、回 0,否则 SOCKET_ERROR地址结构说明:struct sockaddr_inshortsin_family;/AF_INETu_shortsin_port;/16 位端口号,网络字节顺序structin_addrsin_addr;/32 位 IP 地址,网络字节顺序charsin_zero8;/保留,空字节,要设为 0sockaddr_inSA1,SA2;SA1.sin_family=AF_INET;SA1.sin_addr.S_un.S_un_b.s_b1=127;SA1.sin_addr.S_un.S_un_b.s_b2=0;SA1.sin_addr.S_un.S_un_b.s

22、_b3=0;SA1.sin_addr.S_un.S_un_b.s_b4=1;SA1.sin_addr.S_un.S_addr=inet_addr(“127.0.0.1”);Little-endianox9812ox12,ox 98big-endian0 x98 0 x12描述位 IP 地址的 in_addr 结构定义:structin_addrunionstruct u_chars_b1,s_b2,s_b3,s_b4;S_un_b;struct u_shorts_w1,s_w2;S_un_w;u_longS_addr;S_un;3、建立套接字连接connect()和 accept()功能:共同

23、完成连接工作格式:intPASCALFARconnect(SOCKET s,const struct sockaddr FAR*name,int namelen);SOCKET PASCAL FAR accept(SOCKET s,structsockaddr FAR*name,intFAR*addrlen);参数:同上4、监听连接listen()功能:用于面向连接服务器,表明它愿意接收连接。格式:intPASCALFARlisten(SOCKET s,intbacklog);5、数据传输send()与 recv()功能:数据的发送与接收格式:intPASCALFARsend(SOCKET s

24、,const char FAR*buf,int len,int flags);intPASCALFARrecv(SOCKET s,const charFAR*buf,int len,int flags);参数:buf:指向存有传输数据的缓冲区的指针。6、多路复用select()功能:用来检测一个或多个套接字状态。格式:intPASCALFARselect(int nfds,fd_set FAR*readfds,fd_set FAR*writefds,fd_setFAR*exceptfds,const struct timeval FAR*timeout);参数:readfds:指向要做读检测的

25、指针writefds:指向要做写检测的指针exceptfds:指向要检测是否出错的指针timeout:最大等待时间7、关闭套接字closesocket()功能:关闭套接字 s格式:BOOL PASCAL FAR closesocket(SOCKET s);三、典型过程图2.1 面向连接的套接字的系统调用时序图2.2 无连接协议的套接字调用时序图2.3 面向连接的应用程序流程图Windows Socket1.1 程序设计一、简介Windows Sockets 是从 Berkeley Sockets 扩展而来的,其在继承 Berkeley Sockets 的基础上,又进行了新的扩充。这些扩充主要是

26、提供了一些异步函数,并增加了符合 WINDOWS 消息驱动特性的网络事件异步选择机制。Windows Sockets 由两部分组成:开发组件和运行组件。开发组件:Windows Sockets 实现文档、应用程序接口(API)引入库和一些头文件。运行组件:Windows Sockets 应用程序接口的动态链接库(WINSOCK.DLL)。二、主要扩充说明1、异步选择机制:Windows Sockets 的异步选择函数提供了消息机制的网络事件选择,当使用它登记网络事件发生时,应用程序相应窗口函数将收到一个消息,消息中指示了发生的网络事件,以及与事件相关的一些信息。Windows Sockets

27、提供了一个异步选择函数 WSAAsyncSelect(),用它来注册应用程序感兴趣的网络事件,当这些事件发生时,应用程序相应的窗口函数将收到一个消息。函数结构如下:intPASCALFARWSAAsyncSelect(SOCKET s,HWND hWnd,unsignedintwMsg,long lEvent);参数说明:hWnd:窗口句柄wMsg:需要发送的消息lEvent:事件(以下为事件的内容)值:含义:FD_READ期望在套接字上收到数据(即读准备好)时接到通知FD_WRITE期望在套接字上可发送数据(即写准备好)时接到通知FD_OOB期望在套接字上有带外数据到达时接到通知FD_ACC

28、EPT 期望在套接字上有外来连接时接到通知FD_CONNECT期望在套接字连接建立完成时接到通知FD_CLOSE期望在套接字关闭时接到通知(OOB data is a logically independent transmission channel associated with each pair of connected stream sockets.)例如:我们要在套接字读准备好或写准备好时接到通知,语句如下:rc=WSAAsyncSelect(s,hWnd,wMsg,FD_READ|FD_WRITE);如果我们需要注销对套接字网络事件的消息发送,只要将 lEvent 设置为 02、

29、异步请求函数在 Berkeley Sockets 中请求服务是阻塞的,WINDOWS SICKETS 除了支持这一类函数外,还增加了相应的异步请求函数(WSAAsyncGetXByY();)。3、阻塞处理方法Windows Sockets 为了实现当一个应用程序的套接字调用处于阻塞时,能够放弃 CPU 让其它应用程序运行,它在调用处于阻塞时便进入一个叫“HOOK”的例程,此例程负责接收和分配 WINDOWS 消息,使得其它应用程序仍然能够接收到自己的消息并取得控制权。WINDOWS 是非抢先的多任务环境,即若一个程序不主动放弃其控制权,别的程序就不能执行。因此在设计 Windows Socke

30、ts 程序时,尽管系统支持阻塞操作,但还是反对程序员使用该操作。但由于 SUN 公司下的Berkeley Sockets 的套接字默认操作是阻塞的,WINDOWS 作为移植的 SOCKETS 也不可避免对这个操作支持。在 WindowsSockets 实现中,对于不能立即完成的阻塞操作做如下处理:DLL 初始化循环操作。在循环中,它发送任何 WINDOWS 消息,并检查这个 Windows Sockets 调用是否完成,在必要时,它可以放弃 CPU 让其它应用程序执行(当然使用超线程的 CPU 就不会有这个麻烦了_)。我们可以调用 WSACancelBlockingCall()函数取消此阻塞操

31、作。在 WindowsSockets 中,有一个默认的阻塞处理例程 BlockingHook()简单地获取并发送 WINDOWS 消息。如果要对复杂程序进行处理,Windows Sockets 中还有 WSASetBlockingHook()提供用户安装自己的阻塞处理例程能力;与该函数相对应的则是 SWAUnhookBlockingHook(),它用于删除先前安装的任何阻塞处理例程,并重新安装默认的处理例程。请注意,设计自己的阻塞处理例程时,除了函数 WSACancelBlockingHook()之外,它不能使用其它的 Windows SocketsAPI 函数。在处理例程中调用 WSACan

32、celBlockingHook()函数将取消处于阻塞的操作,它将结束阻塞循环。4、出错处理Windows Sockets 为了和以后多线程环境(WINDOWS/UNIX)兼容,它提供了两个出错处理函数来获取和设置当前线程的最近错误号。(WSAGetLastEror()和 WSASetLastError())5、启动与终止使用函数 WSAStartup()和 WSACleanup()启动和终止套接字。三、Windows Sockets 网络程序设计核心我们终于可以开始真正的 Windows Sockets 网络程序设计了。不过我们还是先看一看每个 Windows Sockets网络程序都要涉及的

33、内容。让我们一步步慢慢走。1、启动与终止在所有 WindowsSockets 函数中,只有启动函数 WSAStartup()和终止函数 WSACleanup()是必须使用的。启动函数必须是第一个使用的函数,而且它允许指定 Windows SocketsAPI 的版本,并获得 SOCKETS 的特定的一些技术细节。本结构如下:intPASCALFARWSAStartup(WORD wVersionRequested,LPWSADATAlpWSAData);其中 wVersionRequested 保证 SOCKETS 可正常运行的 DLL 版本,如果不支持,则返回错误信息。我们看一下下面这段代码

34、,看一下如何进行 WSAStartup()的调用WORD wVersionRequested;/定义版本信息变量WSADATAwsaData;/定义数据信息变量interr;/定义错误号变量wVersionRequested=MAKEWORD(1,1);/给版本信息赋值err=WSAStartup(wVersionRequested,&wsaData);/给错误信息赋值if(err!=0)return;/告诉用户找不到合适的版本/确认 Windows Sockets DLL 支持 1.1 版本/DLL 版本可以高于 1.1/系统返回的版本号始终是最低要求的 1.1,即应用程序与 DLL 中可支

35、持的最低版本号if(LOBYTE(wsaData.wVersion)!=1|HIBYTE(wsaData.wVersion)!=1)WSACleanup();/告诉用户找不到合适的版本return;/WindowsSockets DLL 被进程接受,可以进入下一步操作关闭函数使用时,任何打开并已连接的 SOCK_STREAM 套接字被复位,但那些已由 closesocket()函数关闭的但仍有未发送数据的套接字不受影响,未发送的数据仍将被发送。程序运行时可能会多次调用 WSAStartup()函数,但必须保证每次调用时的 wVersionRequested 的值是相同的。2、异步请求服务Win

36、dows Sockets 除 支 持Berkeley Sockets 中 同 步 请 求,还 增 加 了 了 一 类 异 步 请 求 服 务 函 数WSAAsyncGerXByY()。该函数是阻塞请求函数的异步版本。应用程序调用它时,由 WindowsSockets DLL 初始化这一操作并返回调用者,此函数返回一个异步句柄,用来标识这个操作。当结果存储在调用者提供的缓冲区,并且发送一个消息到应用程序相应窗口。常用结构如下:HANDLE taskHnd;char hostname=rs6000;taskHnd=WSAAsyncBetHostByName(hWnd,wMsg,hostname,b

37、uf,buflen);需要注意的是,由于 Windows 的内存对像可以设置为可移动和可丢弃,因此在操作内存对象是,必须保证WIindows Sockets DLL 对象是可用的。3、异步数据传输使用 send()或 sendto()函数来发送数据,使用 recv()或 recvfrom()来接收数据。Windows Sockets 不鼓励用户使用阻塞方式传输数据,因为那样可能会阻塞整个 Windows 环境。下面我们看一个异步数据传输实例:假设套接字 s 在连接建立后,已经使用了函数 WSAAsyncSelect()在其上注册了网络事件 FD_READ 和FD_WRITE,并且 wMsg 值

38、为 WM_SOCK,那么我们可以在 Windows 消息循环中增加如下的分支语句:caseWM_SOCK:switch(lParam)case FD_READ:len=recv(wParam,lpBuffer,length,0);break;case FD_WRITE:while(send(wParam,lpBuffer,len,0)!=SOCKET_ERROR)break;break;4、出错处理Windows 提供了一个函数来获取最近的错误码 WSAGetLastError(),推荐的编写方式如下:len=send(s,lpBuffer,len,0);if(len=SOCKET_ERROR

39、)&(WSAGetLastError()=WSAWOULDBLOCK).基于 Visual C+的 WinsockAPI 研究为了方便网络编程,90 年代初,由 Microsoft 联合了其他几家公司共同制定了一套 WINDOWS 下的网络编程接口,即 Windows Sockets 规范,它不是一种网络协议,而是一套开放的、支持多种协议的 Windows下的网络编程接口。现在的 Winsock 已经基本上实现了与协议无关,你可以使用 Winsock 来调用多种协议的功能,但较常使用的是TCP/IP 协议。Socket 实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有 Sock

40、et 接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个 Socket 接口来实现。微软为 VC 定义了 Winsock 类如 CAsyncSocket 类和派生于 CAsyncSocket 的 CSocket 类,它们简单易用,读者朋友当然可以使用这些类来实现自己的网络程序,但是为了更好的了解 WinsockAPI 编程技术,我们这里探讨怎样使用底层的 API 函数实现简单的 Winsock 网络应用程式设计,分别说明如何在 Server 端和 Client 端操作Socket,实现基于 TCP/IP 的数据传送,最后给出相关的源代码。在 VC 中进行 WINSOCK 的 API

41、编程开发的时候,需要在项目中使用下面三个文件,否则会出现编译错误。1WINSOCK.H:这是 WINSOCK API 的头文件,需要包含在项目中。2WSOCK32.LIB:WINSOCK API 连接库文件。在使用中,一定要把它作为项目的非缺省的连接库包含到项目文件中去。3WINSOCK.DLL:WINSOCK 的动态连接库,位于 WINDOWS 的安装目录下。一、服务器端操作 socket(套接字)1)在初始化阶段调用 WSAStartup()此函数在应用程序中初始化 WindowsSockets DLL,只有此函数调用成功后,应用程序才可以再调用其他Windows Sockets DLL

42、中的 API 函数。在程式中 调用该函数的形式如下:WSAStartup(WORD)(18|1),(LPWSADATA)&WSAData),其中(18|1)表示我们用的是 WinSocket1.1 版本,WSAdata 用来存储系统传回的关于 WinSocket 的资料。2)建立 Socket初始化 WinSock 的动态连接库后,需要在服务器端建立一个监听的 Socket,为此可以调用 Socket()函数用来建立这个监听的 Socket,并定义此 Socket 所使用的通信协议。此函数调用成功返回 Socket 对象,失败则返回INVALID_SOCKET(调用 WSAGetLastErr

43、or()可得知原因,所有 WinSocket 的函数都可以使用这个函数来获取失败的原因)。SOCKET PASCAL FAR socket(intaf,inttype,intprotocol)参数:af:目前只提供 PF_INET(AF_INET);type:Socket 的类型(SOCK_STREAM、SOCK_DGRAM);protocol:通讯协定(如果使用者不指定则设为 0);如果要建立的是遵从 TCP/IP协议的 socket,第二个参数 type应为 SOCK_STREAM,如为 UDP(数据报)的 socket,应为 SOCK_DGRAM。3)绑定端口接下来要为服务器端定义的这个

44、监听的 Socket 指定一个地址及端口(Port),这样客户端才知道待会要连接哪一个地址的哪个端口,为此我们要调用 bind()函数,该函数调用成功返回 0,否则返回 SOCKET_ERROR。intPASCALFARbind(SOCKET s,const struct sockaddr FAR*name,int namelen);参 数:s:Socket 对象名;name:Socket 的地址值,这个地址必须是执行这个程式所在机器的 IP 地址;namelen:name 的长度;如果使用者不在意地址或端口的值,那么可以设定地址为 INADDR_ANY,及 Port 为 0,Windows

45、Sockets 会自动将其设定适当之地址及Port(1024 到 5000之间的值)。此后可以调用getsockname()函数来获知其被设定的值。4)监听当服务器端的 Socket 对象绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。listen()函数使服务器端的 Socket 进入监听状态,并设定可以建立的最大连接数(目前最大值限制为 5,最小值为 1)。该函数调用成功返回 0,否则返回 SOCKET_ERROR。intPASCALFARlisten(SOCKET s,intbacklog);参 数:s:需要建立监听的 Socket;backlog:最大连接个数;服务

46、器端的 Socket 调用完 listen()后,如果此时客户端调用 connect()函数提出连接申请的话,Server 端必须再调用 accept()函数,这样服务器端和客户端才算正式完成通信程序的连接动作。为了知道什么时候客户端提出连接要求,从而服务器端的 Socket 在恰当的时候调用 accept()函数完成连接的建立,我们就要使用WSAAsyncSelect()函数,让系统主动来通知我们有客户端提出连接请求了。该函数调用成功返回 0,否则返回SOCKET_ERROR。intPASCALFARWSAAsyncSelect(SOCKET s,HWND hWnd,unsignedintw

47、Msg,long lEvent);参数:s:Socket 对象;hWnd:接收消息的窗口句柄;wMsg:传给窗口的消息;lEvent:被注册的网络事件,也即是应用程序向窗口发送消息的网络事件,该值为下列值 FD_READ、FD_WRITE、FD_OOB、FD_ACCEPT、FD_CONNECT、FD_CLOSE 的组合,各个值的具体含意为:FD_READ:希望在套接字 S 收到数据时收到消息;FD_WRITE:希望在套接字 S 上可以发送数据时收到消息;FD_ACCEPT:希望在套接字 S 上收到连接请求时收到消息;FD_CONNECT:希望在套接字 S 上连接成功时收到消息;FD_CLOSE

48、:希望在套接字 S 上连接关闭时收到消息;FD_OOB:希望在套接字 S 上收到带外数据时收到消息。具体应用时,wMsg应是在应用程序中定义的消息名称,而消息结构中的 lParam 则为以上各种网络事件名称。所以,可以在窗口处理自定义消息函数中使用以下结构来响应 Socket 的不同事件:caseWM_SOCK:/WM_SOCK 为自定义网络通知消息switch(lParam)caseFD_READ:break;case FD_WRITE、break;5)服务器端接受客户端的连接请求当 Client 提出连接请求时,Server 端 hwnd 视窗会收到 Winsock Stack 送来我们自

49、定义的一个消息,这时,我们可以分析lParam,然后调用相关的函数来处理此事件。为了使服务器端接受客户端的连接请求,就要使用accept()函数,该函数新建一 Socket 与客户端的 Socket 相通,原先监听之 Socket 继续进入监听状态,等待他人的连接要求。该函数调用成功返回一个新产生的 Socket 对象,否则返回 INVALID_SOCKET。SOCKET PASCAL FAR accept(SCOKET s,structsockaddr FAR*addr,int FAR*addrlen);参数:s:Socket 的识别码;addr:存放来连接的客户端的地址;addrlen:a

50、ddr 的长度6)结束 socket 连接结束服务器和客户端的通信连接是很简单的,这一过程可以由服务器或客户机的任一端启动,只要调用closesocket()就可以了,而要关闭 Server 端监听状态的 socket,同样也是利用此函数。另外,与程序启动时调用WSAStartup()憨数相对应,程式结束前,需要调用 WSACleanup()来通知 Winsock Stack 释放 Socket 所占用的资源。这两个函数都是调用成功返回 0,否则返回 SOCKET_ERROR。intPASCALFARclosesocket(SOCKET s);参 数:s:Socket 的识别码;intPASC

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁