陈家琪:《计算机网络》WinSock网络编程第1页共23页WinSock网络编程1.概述80's初,ARPA(美国国防部高级研究计划局)®加利福尼亚大学Berkeley分校提供资金,®开发在UNIX下实现TCP/IP协议。®为TCP/IP开发了一个API––Socket接口(套接口)––俗称Bekeley套接口模型。90's初,Microsoft等公司®基于Bekeley套接口模型®制定了WindowsSockets规范(简称WinSock)®已是TCP/IP网络的标准。1993.1,v1.11995.5,v2.0,增加了QOS(网络服务质量控制)2.WinSock模型提供TCP/IP传输层的接口:传输层应用程序网络协议栈(TCP/IP)网络驱动协议网络接口卡低层高层WindowsSocketsAPI(动态链接库)网络层物理层数据链路层应用层表示层会话层①TCP(传输控制协议)提供虚电路和面向连接的数据流传输服务。实现无差错无重复的顺序数据传输。80年代初,美国国防部高级研究计划局(ARPA)给加利福尼亚大学Berkeley分校提供了资金,让他们在UNIX操作系统下实现TCP/IP协议。在这个项目中,研究人员为TCP/IP网络通信开发了一个API(应用程序接口)。这个API称为Socket接口(套接字)。今天,SOCKET接口是TCP/IP网络最为通用的API,也是在INTERNET上进行应用开发最为通用的API。90年代初,由Microsoft联合了其他几家公司共同制定了一套WINDOWS下的网络编程接口,即WindowsSockets规范。它是BerkeleySockets的重要扩充,主要是增加了一些异步函数,并增加了符合Windows消息驱动特性的网络事件异步选择机制。WINDOWSSOCKETS规范是一套开放的、支持多种协议的Windows下的网络编程接口。从1991年的1.0版到1995年的2.0.8版,经过不断完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成为Windows网络编程的事实上的标准。陈家琪:《计算机网络》WinSock网络编程第2页共23页·2·②UDP(用户数据报协议)提供无连接的数据报传输服务。数据通过相互独立的报文进行传输,是无序的,并且不保证可靠、无差错。3.WinSockDLL•WinSock与操作系统的关系应用程序1网络编程接口––如WinSockAPI网络通信协议––如TCP/IP协议操作系统––如Windows应用程序2动态链接库物理通信介质•动态链接库:16位版:WINSOCK.DLL32位版:WSOCK32.DLL①DLL装载WinSock服务由动态连接库WinSockDLL提供,它完成WinSock的初始化任务,协商WinSock的版本支持,并分配必要的资源。在使用WinSockAPI之前,必须调用:·intWSAStartup(WORDv,(LPWSADATA)&WD)其中:v–––指示应用程序对WinSock版本的要求,低字节为主版本号,高字节为副版本号。例:v1.1®v=Ox0101,v2.0®v=Ox0002,WD––返回WinSock的实现信息。WD是一个WSADATA结构:structWSADATA{WORDwVersion;WORDwHighVersion;charszDescription[WSADESCRIPTION_LEN+1];charszSystemStatus[WSASYSSTATUS_LEN+1];陈家琪:《计算机网络》WinSock网络编程第3页共23页·3·unsignedshortiMaxSockets;unsignedshortiMaxUdpDg;charFAR*lpVendorInfo;};结构成员说明wVersion:DLL支持的WinSock规范的版本;wHighVersion:DLL可支持的WinSock规范的最高版本;szDescription:DLL的说明及厂商描述;szSystemStatus:DLL将相关的状态和配置信息;iMaxSockets:一个进程可以打开的最大套接口数目;iMaxUdpDg:应用程序发送或接收的最大UDP数据报的大小;如果应用程序没有给出限制,iMaxUdpDg为0(隐含为8192字节)。最小值为512。lpVendorInfo:指向厂商规定数据结构的远指针。调用成功,返回0。②DLL卸载当不需WinSockDLL的服务,释放DLL所使用的资源。应用程序必须调用:·intWSACleanup()调用成功,返回0。对应于每一次WSAStartup()调用必须有一个WSACleanup()调用。4.套接口SocketSocket实际上是一个通信端口;一个Socket是通讯的一端。网络通信将通过各自的Socket相联系。在应用开发中就像使用文件句柄一样,应用程序向操作系统申请,由操作系统分配本地唯一的Socket端口号。然后,可以对Socket句柄进行读,写操作。·创建Socket:SOCKETsocket(intaf,//套接口所用地址族inttype,//套接口类型陈家琪:《计算机网络》WinSock网络编程第4页共23页·4·intprotocol//套接口所用协议)参数说明AF_INETTCP/IP地址①afAF_UNIX......UNIX地址SOCK_STREAM数据流套接口,对应TCP协议SOCK_DGRAM数据报套接口,对应UDP协议②type............IPPROC_TCP使用TCP/IP的TCP协议IPPROC_UDP使用TCP/IP的UDP协议............③protocol0①和②基本确定了一种协议,若调用者不想指定,设置为0。返回值:若无错误发生,socket()返回引用套接口的描述字(套接口号)。否则的话,返回SOCKET_ERROR错误,即-1。应用程序可通过WSAGetLastError()获取相应错误代码。5.主机地址标识网络环境中的唯一通信端点标识。包含:协议、IP地址、端口。(俗称三元组)关于端口:在TCP/IP中,TCP与UDP使用彼此独立的端口;端口大小:16bit(共216个)端口分为:①系统全局端口:1~1023;例,HTTP为TCP/80,FTP为TCP/21、UDP/69,SMTP为TCP/25②系统自动分配端口:1024~5000;③自由端口:5000~65535;6.主机地址标识的数据结构structsockaddr{u_shortsa_family;//协议族charsa_data[14];//主机地址标识(端口号、IP地址)};陈家琪:《计算机网络》WinSock网络编程第5页共23页·5·structsockaddr_in{shortsin_family;//协议族u_shortsin_port;//16bit端口号,网络字节顺序structin_addrsin_addr;//32bit的IP地址,网络字节顺序charsin_zero[8];//未用};其中:structin_addr{u_longs_addr;//32bit的IP地址,网络字节顺序};网络字节顺序:16bit/32bit整数存放格式––高字节在前,低字节在后。•设置主机地址//------------------------------------------------voidSetSockAddr(structsockaddr_in*A,WORDPort,char*IP){A-sin_family=AF_INET;//TCP/IP协议A-sin_port=htons(Port);//端口号。A-sin_addr.s_addr=inet_addr(IP);//IP地址。}//------------------------------------------------函数作用htons()把16bit的数字从主机字节顺序转换到网络字节顺序inet_addr()把一个IP地址格式A.B.C.D转换成32bit的网络字节顺序注:IntelCPU的主机字节顺序:16bit/32bit整数存放格式––低字节在前,高字节在后。7.Socket号与主机地址捆绑将IP地址和端口号与所创建的Socket号联系起来。·intbind(SOCKETs,//待捆绑Socketstructsockaddrfar*name,//赋予Socket的主机地址标识intlen//name的长度);调用成功,返回0。陈家琪:《计算机网络》WinSock网络编程第6页共23页·6·8.WinSock操作模式①同步模式或阻塞模式(blockingmode)采用DOS技术编程,某些WinSock函数(同步函数)直到完成操作后才返回。例,当执行数据接收函数revc()时,一直等待对方发送数据,直到接收到数据后才返回。②异步模式或非阻塞模式(non-blockingmode)采用Windows技术编程,利用消息(事件驱动)的特点,使同步函数变为异步函数(不产生阻塞)。关键:异步选择函数WSAAsyncSelect()的使用。WSAAsyncSelect()可设置一个或多个网络事件消息,如,已收到数据、数据发送完毕、客户机请求连接、服务器已完成连接等网络事件。当设置的网络事件发生时,Windows应用程序的窗口函数将收到一个消息。通过这个消息就可以进行相应的处理。intWSAAsyncSelect(SOCKETs,//需要事件驱动的套接口HWNDhWnd,//接收消息的窗口句柄unsignedintwMsg,//网络事件发生时的消息字longlEvent//用于指明感兴趣的网络事件集合);lEvent参数由下表中列出的值组成:值意义FD_READ已接收到数据FD_WRITE数据发送完毕FD_OOB已接收到边带数据FD_ACCEPT客户机请求连接,用于服务器端FD_CONNECT服务器已完成连接,用于客户机端FD_CLOSE连接关闭(对方的套接口关闭)例:WSAAsyncSelect(S,hW,WM_USER+1,FD_ACCEPT|FD_READ|FD_CLOSE);程序结束时,应注销异步选择:WSAAsyncSelect(S,hW,0,0);陈家琪:《计算机网络》WinSock网络编程第7页共23页·7·9.无连接协议的同步模式编程无连接服务器一般都是面向事务处理的。一个请求一个应答就完成了客户程序与服务程序之间的相互作用。①工作过程:服务器服务请求服务应答无连接套接口应用程序时序图S=socket(...)bind(S,...)sendto(S,...)recv(S,...)阻塞,等待客户请求处理服务请求closesocket(S)继续服务?YN客户机S=socket(...)bind(S,...)sendto(S,...)recv(S,...)阻塞,等待服务数据处理数据closesocket(S)继续?YN服务器首先启动,通过调用socket()建立一个套接口,然后bind()将该套接口和本地地址(IP地址和端口)联系在一起,服务器调用recv()等待接收数据。客户机通过调用socket()建立一个套接口,然后bind()将该套接口和本地地址(IP地址和端口)联系在一起,客户机调用sendto()向服务器发送数据;服务器的recv()接收到客户机的数据后,调用sendto()向客户机发送应答数据;客户机的recv()便接收到了服务器的应答数据;最后,待数据传送结束后,双方调用closesocket()关闭套接口。陈家琪:《计算机网络》WinSock网络编程第8页共23页·8·②编程示例://UDP(TCP/IP)fortheconsoleapplication.////VC6.0addWSOCK32.LIBinProject-Settings...-Link#includestdafx.h#includew