网络编程实用教程_第3章 Windows环境的网络编程

上传人:人*** 文档编号:569746886 上传时间:2024-07-30 格式:PPT 页数:62 大小:1.36MB
返回 下载 相关 举报
网络编程实用教程_第3章 Windows环境的网络编程_第1页
第1页 / 共62页
网络编程实用教程_第3章 Windows环境的网络编程_第2页
第2页 / 共62页
网络编程实用教程_第3章 Windows环境的网络编程_第3页
第3页 / 共62页
网络编程实用教程_第3章 Windows环境的网络编程_第4页
第4页 / 共62页
网络编程实用教程_第3章 Windows环境的网络编程_第5页
第5页 / 共62页
点击查看更多>>
资源描述

《网络编程实用教程_第3章 Windows环境的网络编程》由会员分享,可在线阅读,更多相关《网络编程实用教程_第3章 Windows环境的网络编程(62页珍藏版)》请在金锄头文库上搜索。

1、吉林大学软件学院吉林大学软件学院第第3章章 Windows环境的网络编程环境的网络编程lWindows Sockets 规范lWinSock 规范与Berkeley套接口的区别lWinsock 1.1 的库函数吉林大学软件学院吉林大学软件学院3.1WindowsSockets规范规范3.1.1概述概述lMicrosoft公司以公司以BerkeleySockets规范为范例,定义规范为范例,定义了了WindowsSocktes规范,简称规范,简称Winsock规范规范。l这是这是Windows操作系统环境下的套接字网络应用程序操作系统环境下的套接字网络应用程序编程接口(编程接口(API)。)。l

2、包含:包含:lBerkeley Socket 风格的库函数;l针对Windows操作系统的扩展库函数。l可以充分利用可以充分利用Windows的消息驱动机制编程。的消息驱动机制编程。lWinsock规范定义了应用程序开发者能够使用,并且规范定义了应用程序开发者能够使用,并且网络软件供应商能够实现的一套库函数和相关语义,网络软件供应商能够实现的一套库函数和相关语义,让各个软件供应商共同遵守,做到让各个软件供应商共同遵守,做到Winsock兼容。兼容。吉林大学软件学院吉林大学软件学院图3.1网网络应用用进程利用程利用Windock进行通信行通信吉林大学软件学院吉林大学软件学院3.1.2Window

3、sSockets规范规范lWindowsSockets规范范是是一一套套开开放放的的、支支持持多多种种协议的的Windows下的网下的网络编程接口。程接口。l从从1991年年到到1995年年,从从1.0版版发展展到到2.0.8版版,已已成成为Windows网网络编程的事程的事实上的上的标准。准。1WindowsSockets1.1版本版本l在在Winsock.h包含文件中,定包含文件中,定义了了WinSock1.1版本版本库库函数的函数的函数的函数的语语法法法法、相关的符号常量相关的符号常量相关的符号常量相关的符号常量和和数据数据数据数据结结构构构构。l库函数的函数的实现在在Winsock.d

4、ll动态链接接库文件中。文件中。(1)WinSock1.1全面全面继承了承了BerkeleySockets规范。范。l见表表3.1吉林大学软件学院吉林大学软件学院(1)WinSock1.1全面全面继承了承了BerkeleySockets规范。范。lWinsock1.1继承了Berkeley Sockets规范的主要特征,一部分库函数与之在形式上保持一致,包括库函数的名称、参数格式、结构定义。l见表 3.1。l其中,带*号的表明该例程在某些情况下可能会发生阻塞。主要函数SOCKET()创建一个套接字,并返回套接字的标识符BIND()把套接字绑定到特定的网络地址上LISTEN()启动指定的套接字,

5、监听到来的连接请求ACCEPT()*接收一个连接请求,并新建一个套接字,原来的套接字返回监听状态CONNECT()*请求讲本地套接字连接到一个指定的远方套接字上SEND()*向一个已经与对方建立连接的套接字发送数据SENDTO()*向一个未与对方建立连接的套接字发送数据,并指定对方网络地址RECV()*从一个已经与对方建立连接的套接字接收数据RECVFROM()*从一个未与对方建立连接的套接字接收数据,并返回对方网络地址SHUTDOWN()有选择的关闭套接字的全双工连接CLOSESOCEKT()*关闭套接字,释放相应的资源表表3.1WinSock1.1继承承BerkeleySockets的函数

6、的函数辅助函数辅助函数HTONL()把32位无符号数从主机字节序转换为网络字节序HTONS()把16位无符号数从主机字节序转换为网络字节序NTOHL()把32位无符号数从网络字节序转换为主机字节序NTOHS()把16位无符号数从网络字节序转换为主机字节序INET_ADDR()把标准的点分十进制的IP转换成长整形地址数据INET_NTOA()把长整形的IP地址数据转换成点分十进制的字符串GETPEERNAME()获得套接字连接上对方的网络地址GETSOCKENAME() 获得指定套接字的网络地址控制函数控制函数GETSOCKOPT()获得指定套接字的属性选项SETSOCKOPT()设置与指定套接

7、字相关的属性选项IOCTLSOCKET()为套接字提供控制SELECT()*执行同步I/O多路复用表表3.1WinSock1.1继承承BerkeleySockets的函数的函数(cont.)(2)数据库函数数据库函数l表表3.2列出了列出了Winsock规范定义的数据库查询函数。规范定义的数据库查询函数。l其其中中6个个采采用用getXbyY()getXbyY()的的形形式式,大大多多要要借借助助网网络络上上的的数据库来获得信息,而不采用本地数据库来实现。数据库来获得信息,而不采用本地数据库来实现。函数名函数名说明说明gethostname()用来返回本地计算机的标准主机名gethostbyn

8、ame()*返回对英语给定主机名的主机信息gethostbyaddr()*根据一个IP地址取回相应的主机信息getservbyname()*返回对应于给定服务名和协议名的相关服务信息getservbyport()*返回对应于给定端口号和协议名的相关服务信息getportbyname()*返回对应于给定协议名的相关服务信息getportbynumber()*返回对应于给定协议号的相关服务信息表表3.2数据数据库查询函数函数吉林大学软件学院吉林大学软件学院lgetXbyY()形形式式的的数数据据库库例例程程都都返返回回一一个个指指针针,指指向向某某种种类类型型的的结结构构区区域域,用用来来存存放放

9、函函数数返返回回的的数数据信息。据信息。l这些结构区域是由winsock实现(即Winsock.dll)分配的,由系统管理,所以指针指向的结构数据是易失的,只在该线程的下一个Winsock API调用前有效。l一个线程中只有一个该结构的副本,因此应用程序在发出下一个Winsock API调用前,应把所需的信息复制下来。l应用程序不应试图修改或释放这个结构。吉林大学软件学院吉林大学软件学院(3)WinSock1.1扩充了扩充了BerkeleySockets规范规范l针针对对微微软软Windows的的特特点点,WinSock1.1定定义义了了一一批批新新的的库库函函数数,提提供供了了对对消消消消息

10、息息息驱驱驱驱动动动动机机机机制制制制的的支支持持,有效地利用有效地利用WindowsWindowsWindowsWindows多任务多线程多任务多线程多任务多线程多任务多线程的机制。的机制。l扩充主要是提供了一些异步函数,增加了符合Windows消息驱动特性的网络事件异步选择机制,有利于开发符合Windows编程模式的软件,使得开发高性能网络通信程序成为可能。l这些扩充函数的名字都以WSA开头,后面跟async表示是专为实现异步机制而设置的。l编程时必须使用WSAStartup()和WSACleanup(),其它函数随意使用。11表表3.3Winsock1.1的常用的常用扩展函数展函数Win

11、sock的注册与注销函数的注册与注销函数WSAStartup()初始化低层Windows Socks DLLWSACleanup()从低层的Windows Sockets DLL撤销注册异步执行的数据库查询函数异步执行的数据库查询函数WSAAsynGetHostBYName()GetHostBYName()的异步版本WSAAsynGetHostBYAddr()GetHostBYAddr()的异步版本WSAAsynGetServByName()GetServByName()的异步版本WSAAsynGetServByPort()GetServByPort()的异步版本WSAAsynGetProto

12、byNameGetProtobyName()的异步版本WSAAsynGetProtobyNumber()GetProtobyNumber()的异步版本12表表3.3Winsock1.1的常用的常用扩展函数(展函数(续)异步机制的相关函数异步机制的相关函数WSAAsynSelect()Select()的异步版本WSACancelAsyncRequest()取消一个未完成的WSAAsyncGetXByY()函数的实例WSACancelBlockingCall ()取消未完成的阻塞的API调用WSAIsBlocking()确定线程是否被一个调用阻塞错误处理相关函数错误处理相关函数WSAGetLast

13、Error()得到最近一个Winsock调用出错的详细信息WSASetLastError()设置下一次WSAGetLastError()返回的错误信息吉林大学软件学院吉林大学软件学院(4)WinSock1.1只支持只支持TCP/IP协议栈协议栈lWinsock1.1的实现,即的实现,即Winsock.dll和底层协议栈和底层协议栈的接口是唯一的,且是独占的,只能访问的接口是唯一的,且是独占的,只能访问TCP/IP协议栈。协议栈。l因此,因此,Winsock1.1套接字仅支持单一的通信域,套接字仅支持单一的通信域,即即Internet域。域。吉林大学软件学院吉林大学软件学院2WinSock2.0

14、规范规范lWinSock 2.0在源码和二进制代码方面与WinSock 1.1兼容,此外还增强了许多功能。(1)支持多种协议(2)引入了重叠I/O的概念(3)使用事件对象异步通知(4)服务的质量(QOS)(5)套接口组(6)扩展的字节顺序转换例程(7)分散/聚集方式I/O(8)新增了许多函数。 吉林大学软件学院吉林大学软件学院3.WinSock1.1中的阻塞问题中的阻塞问题l阻塞是在把应用程序从Berkeley套接口环境中移植到Windows环 境 中 的 一 个 主 要 焦 点 , 虽 然 Windows Sockets支持关于套接口的阻塞操作,但是这种应用是被强烈反对的。l阻塞,是指唤起一

15、个函数,该函数直到相关操作完成时才返回。l在Berkeley套接口模型中,一个套接口的操作的缺省行为是阻塞方式的,除非程序员显式地请求该操作为非阻塞方式。l在Windows环境下,强烈推荐程序员尽可能使用非阻塞方式(异步方式)的操作,因为非阻塞方式的操作能够更好地在非占先的Windows环境下工作。吉林大学软件学院吉林大学软件学院l有些Sockets操作在阻塞和非阻塞方式下没什么区别;而有些Sockets操作取决于传输情况,会立即完成或阻塞一段时间。l当操作用于阻塞套接口(打*号标记的)时,这些操作被认为是工作于阻塞方式的。l在Windows Sockets实现中,一个无法立刻完成的阻塞操作是

16、按如下方式处理的:lDLL先初始化操作,然后进入一个循环,在循环中发送收到的任何信息,以便必要时将处理器交给其它线程;l然后检查Windows Sockets功能是否完成,如果完成了,WSACancleBlockingCall()被唤起,阻塞操作以一个适当的返回值结束。吉林大学软件学院吉林大学软件学院l如果一个正在运行某一阻塞操作的进程收到了一个Windows消息,那么应用程序有可能试图发出另一个Windows Sockets调用。l由于难以安全的处理这种情况,Windows Sockets规范不支持这种应用程序的工作方式,此时可以借助两个函数来解决:lWSAIsBlocking () 可以用

17、来确定在该进程上是否有阻塞的Windows Sockets调用;lWSACancleBlockingCall()可以用来取消在线的阻塞调用,如果有的话。l其它任何Windows Sockets函数此时被调用,都会失败并返回错误代码WSAEINPROGRESS。l这一限制适用于所有阻塞和非阻塞操作。吉林大学软件学院吉林大学软件学院3.1.3WinSock规范与规范与Berkeley套接口的区别套接口的区别1套接口数据类型和该类型的错误返回值l在在UNIX中中,包包括括套套接接口口句句柄柄在在内内的的所所有有句句柄柄,都都是是非负的短整数;非负的短整数;l在在WinSock规规范范中中定定义义了了

18、一一个个新新的的数数据据类类型型,称称作作SOCKET,用来代表套接字描述符。,用来代表套接字描述符。typedefu_intSOCKET;lsocket()和和accept()函函数数返返回回时时,返返回回的的就就是是SOCKET类型。类型。lSOCKET可可以以取取从从0到到INVALID_SOCKET-1之之间间的的任任意值。意值。吉林大学软件学院吉林大学软件学院l要要判判断断socket()和和accept()是是否否正正确确执执行行,可可以以将将返返回回值值 和和 INVALID_SOCKET来来 比比 较较 , 该该 常常 量量 已已 在在Winsock.h中定义。中定义。l例如:

19、例如:l在UNIX套接字规范中s=socket();if(s=-1)执行错误处理代码 l在Winsock套接字规范中:s=socket();if(s=INVALID_SOCKET)执行错误处理代码 吉林大学软件学院吉林大学软件学院2select()函数和FD_*宏l在在Winsock中,使用中,使用select()函数时,应用程序应坚持函数时,应用程序应坚持用用FD_XXX宏来设置、初始化、清除和检查宏来设置、初始化、清除和检查fd_set结结构,构,fd_set结构用来代表一组套接口。结构用来代表一组套接口。3错误代码的获得lUNIX套套接接字字规规范范中中,如如果果函函数数执执行行时时发发

20、生生了了错错误误,会把错误代码放到会把错误代码放到errno或或h_errno变量中。变量中。l在在Winsock中中错错误误代代码码可可以以使使用用WSAGetLastError()调用得到。调用得到。4指针l所所有有应应用用程程序序与与WindowsSockets使使用用的的指指针针都都必必须须是是FAR指针。指针。吉林大学软件学院吉林大学软件学院5. 重命名的函数l有有两两个个伯伯克克利利套套接接口口函函数数改改了了名名字字,避避免免与与其其它它API冲突。冲突。lclose()改变为closesocket()lioctl()改变为ioctlsocket() 6. Winsock支持的最

21、大套接口数目l一一个个特特定定的的WindowsSockets提提供供者者所所支支持持的的套套接接口口的的最最大大数数目目是是由由实实现现确确定定的的;任任何何一一个个应应用用程程序序都都不不应应假设某个待定数目的套接口可用。假设某个待定数目的套接口可用。l一一个个WindowsSockets应应用用程程序序可可以以使使用用的的套套接接口口的的最最大大数数目目在在Winsock.h中中缺缺省省值值是是64,在在编编译译时时由由常常量量FD_SETSIZEFD_SETSIZE决定。决定。吉林大学软件学院吉林大学软件学院7. 头文件lBerkeley头文件被包含在头文件被包含在Winsock.h中

22、。中。l一一 个个 Windows Sockets应应 用用 程程 序序 只只 需需 简简 单单 地地 包包 含含Winsock.h就足够了。就足够了。8原始套接口lWindows Sockets规范范并并没没有有规定定Windows SocketsDLL必必须支支持持原原始始套套接接口口(用用SOCK_RAW打打开开的的套套接接口口),但是鼓励提供原始套接口支持。,但是鼓励提供原始套接口支持。9、Winsock规范对于消息驱动机制的支持l体体现在异步在异步选择机制、异步机制、异步请求函数、阻塞求函数、阻塞处理方法、理方法、错误处理、启理、启动和和终止等方面。止等方面。吉林大学软件学院吉林大学

23、软件学院3.2Winsock1.1的库函数的库函数3.2.1Winsock的注册与注销的注册与注销1初始化函数WSAStartup()lWinsock应用用程程序序要要做做的的第第一一件件事事,就就是是必必须首首先先调用用WSAStartup()函数函数对Winsock进行行初初初初始化始化始化始化。l初初始始化化也也称称为注注注注册册册册,注注册册成成功功后后,才才能能调用用其其他他的的WinsockAPI函数。函数。(1)WSAStartup()函数的函数的调用格式用格式intWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData);lwVe

24、rsionRequested:应用程序要使用的winsock最高版本号;llpWSAData:指向WSADATA结构,返回Winsock API实现细节。图3.2在一台在一台计算机中,使用同一算机中,使用同一Winsock实现的多个网的多个网络应用程序用程序(2)WSAStartup()函数的初始化函数的初始化过程程吉林大学软件学院吉林大学软件学院25(3)WSADATA结构的定构的定义#defineWSADESCRIPTION_LEN256#defineWSASYS_STATUS_LEN128typedefstructWSADataWORDwVersion;WORDwHighVersion;

25、charszDescriptionWSADESCRIPTION_LEN+1;charszSystemStatusWSASYS_STATUS_LEN+1;unsignedshortiMaxSockets;unsignedshortiMaxUdpDg;char*lpVendorInfo;WSADATA;吉林大学软件学院吉林大学软件学院26(4)初始化函数可能返回的初始化函数可能返回的错误代代码WSASYSNOTREADY:网网络通信依通信依赖的网的网络子系子系统没有准没有准备好。好。WSAVERNOTSUPPORTED:找不到所需的找不到所需的WinsockAPI相相应的的动态连接接库。WSAEI

26、NVAL:DLL不支持不支持应用程序所需的用程序所需的Winsock版本。版本。WSAEINPROGRESS:正在正在执行一个阻塞的行一个阻塞的Winsock1.1操作。操作。WSAEPROCLIM:已已经达到达到Winsock支持的任支持的任务数上限。数上限。WSAEFAULT:参数参数lpWSAData不是合法指不是合法指针。27(5)初始化初始化Winsock的示例的示例#include/对于于Winsock2.0,应包括包括Winsock2.h文件文件aa()WORDwVersionRequested;/应用程序所需的用程序所需的Winsock版本号版本号WSADATAwsaData;

27、/用来返回用来返回Winsock实现的的细节信息信息Interr;/出出错代代码。wVersionRequested=MAKEWORD(1,1);/生成版本号生成版本号1.1err=WSAStartup(wVersionRequested,&wsaData);/调用初始化函数用初始化函数if(err!=0)return;/通知用通知用户找不到合适的找不到合适的DLL文件文件/确确认返回的版本号是客返回的版本号是客户要求的要求的1.1if(LOBYTE(wsaData.wVersion)!=1|HYBYTE(wsaData.wVersion)!=1)WSACleanup();return;/*至

28、此,可以确至此,可以确认初始化成功,初始化成功,Winsock.DLL可用。可用。吉林大学软件学院吉林大学软件学院2注销函数WSACleanup()l程序使用完Winsock.DLL提供的服务后,应用程序必须调用WSACleanup()函数,来解除与Winsock.DLL库的绑定,释放Winsock实现分配给应用程序的系统资源,中止对Windows Sockets DLL的使用。(1)WSACleanup()函数的调用格式函数的调用格式intWSACleanup(void);l返 回 值 : 如 果 操 作 成 功 返 回 0, 否 则 返 回SOCKET_ERROR.28(2)WSAClea

29、nup()函数的功能函数的功能l对应于于一一个个任任务进行行的的每每一一次次WSAStartup()调用用,必必须有有一个一个WSACleanup()调用。用。l只只有有最最后后的的WSACleanup()做做实际的的清清除除工工作作;前前面面的的调用用仅仅将将WindowsSocketsDLL中的内置引用中的内置引用计数数递减。减。l一个一个简单的的应用程序用程序为确保确保WSACleanup()调用了足用了足够的的次数,可以在一个循次数,可以在一个循环中不断中不断调用用WSACleanup()直至返直至返WSANOTINITIALISED。(3)WSACleanup()函数可能返回的函数可

30、能返回的错误代代码lWSANOTINITIALISED:在调用本API之前应成功调用WSAStartup()。lWSAENETDOWN:检测到网络子系统失效。lWSAEINPROGRESS:一个阻塞的WinSock调用正在进行中,或者服务提供者仍在处理一个回调函数。29吉林大学软件学院吉林大学软件学院3.2.2Winsock的错误处理函数的错误处理函数lWinsock函函数数执执行行时时都都有有一一个个返返回回值值,只只能能说说明明函函数数的执行成功与否,不能从返回值了解出错原因。的执行成功与否,不能从返回值了解出错原因。1WSAGetLastError()函数函数intWSAGetLastE

31、rror(void);l返返回回本本线线程程进进行行的的上上一一次次Winsock函函数数调调用用时时,产产生生的错误代码。的错误代码。l在在Winsock.h中定义了所有的错误代码,基数是中定义了所有的错误代码,基数是100002WSASetLastError()函数函数voidWSASetLastError(intiError);l本本函函数数允允许许应应用用程程序序为为当当前前线线程程设设置置错错误误代代码码,并并可可由后来的由后来的WSAGetLastError()调用返回。调用返回。吉林大学软件学院吉林大学软件学院3.2.3主要的主要的Winsock函数函数1创建套接口创建套接口SO

32、CKET()SOCKETsocket(intaf,inttype,intprotocol);l返返回回值值:创创建建成成功功,返返回回套套接接字字描描述述符符,否否则则返返回回SOCK_ERROR。l举例:举例:SOCKET sockfd=SOCKET( AF_INET, SOCK_STREAM, 0); /* 创建一个流式套接字。SOCKET sockfd=SOCKET( AF_INET, SOCK_DGRAM, 0); /* 创建一个数据报套接字。 吉林大学软件学院吉林大学软件学院2将套接口将套接口绑定到指定的网定到指定的网络地址地址BIND()intbind(SOCKETs,consts

33、tructsockaddr*name,intnamelen);l有有许多多函函数数都都需需要要套套接接字字的的地地址址信信息息,像像UNIX套套接接字字一一样,Winsock也也定定义了了三三种种关关于于地地址址的的结构构,经常使用。常使用。通通用用的的Winsock地地址址结构构,针对各各种种通通信信域域的的套套接接字字,存存储它它们的地址信息。的地址信息。struct sockaddr u_short sa_family; /* 地址家族char sa_data14; /* 协议地址 32专门针对Internet通信域的通信域的Winsock地址地址结构构struct sockaddr_i

34、n short sin_family; /*指定地址家族,一定是AF_INET.u_short sin_port; /*指定将要分配给套接字的传输层端口号,struct in_addr sin_addr; /*指定套接字的主机的IP 地址char sin_zero8; /* 全置为0,是一个填充数。 专用于存用于存储IP地址的地址的结构构Struct in_addr Union Struct u_char s_b1,s_b2,s_b3,s_b4; S_un_b;Struct u_short s_w1,s_w2; S_un_w;U_long S_addr;33吉林大学软件学院吉林大学软件学院l在

35、在使使用用Internet域域的的套套接接字字时,这三三个个数数据据结构构的的一一般般用法是:用法是:l首先,定义一个Sockaddr_in的结构实例变量,并将它清零;l然后,为这个结构的各成员变量赋值;l第三步,在调用BIND()绑定函数时,将指向这个结构的指针强制转换为 sockaddr*类型。 34l举例:例:SOCKETserSock;/ 定义了一个SOCKET 类型的变量。sockaddr_inmy_addr;/ 定义一个Sockaddr_in型的结构实例变量。interr;/出出错码。intslen=sizeof(sockaddr);/ sockaddr 结构的长度。serSock

36、 = SOCKET(AF_INET, SOCK_DGRAM,0 ); / 创建数据报套接字。memset(my_addr,0);/ 将Sockaddr_in的结构实例变量清零。my_addr.sin_family=AF_INET;/ 指定通信域是Internet。my_addr.sin_port=htons(21); / 指定端口,将端口号转换为网络字节顺序。 35/* 指定IP地址,将IP地址转换为网络字节顺序。my_addr.sin_addr.s_addr=htonl(INADDR-ANY);/* 将套接字绑定到指定的网络地址,对&my_addr进行了强制类型转换。if(BIND(serS

37、ock,(LPSOCKADDR)&my_addr,slen)=SOCKET_ERROR)/* 调用WSAGetLastError()函数,获取最近一个操作的错误代码。err=WSAGetLastError();/* 以下可以报错,进行错误处理。36吉林大学软件学院吉林大学软件学院3启启动服服务器器监听客听客户端的端的连接接请求求LISTEN()intlisten(SOCKETs,intbacklog);l仅适用于支持连接的SOCK_STREAM类型的套接口。套接口s处于一种“变动”模式,申请进入的连接请求被确认,并排队等待被接受。l这个函数特别适用于同时有多个连接请求的服务器;如果当一个连接请

38、求到来时,队列已满,那么客户将收到一个WSAECONNREFUSED错误。4接收接收连接接请求求 ACCEPT()SOCKETaccept(SOCKETs,structsockaddr*addr,int*addrlen);37吉林大学软件学院吉林大学软件学院5请求求连接接CONNECT()intconnect(SOCKETs,structsockaddr*name,intnamelen);l举例例structsockaddr_indaddr;memset(void*)&daddr,0,sizeof(daddr);daddr.sin_family=AF_INET;daddr.sin_port=h

39、tons(8888);daddr.sin_addr.s_addr=inet_addr(133.197.22.4);connect(ClientSocket,(structsockaddr*)&daddr,sizeof(daddr);38396向一个已向一个已连接的套接口接的套接口发送数据送数据SEND()int send( SOCKET s, char * buf, int len, int flags); 图3.3同步套接字的同步套接字的Send()函数的函数的执行流程行流程407从一个已从一个已连接套接口接收数据接套接口接收数据RECV()intrecv(SOCKETs,char*buf,

40、intlen,intflags);图3-4说明了明了send和和recv的作用,套接字的作用,套接字缓冲区与冲区与应用用进程程缓冲冲区的关系,以及区的关系,以及协议栈所作的所作的传送。送。图3.4Send()和和Recv()都是都是对本地套接字的操作本地套接字的操作吉林大学软件学院吉林大学软件学院8按照指定目的地向数据按照指定目的地向数据报套接字套接字发送数据送数据SENDTO()intsendto(SOCKETs,char*buf,intlen,intflags,structsockaddr*to,inttolen);9接接收收一一个个数数据据报并并保保存存源源地地址址,从从数数据据报套套接

41、接字字接接收收数据数据RECVFORM()intrecvfrom(SOCKETs,char*buf,intlen,intflags,structsockaddr*from,int*fromlen);41吉林大学软件学院吉林大学软件学院10关关闭套接字套接字CLOSESOCKET()intclosesocket(SOCKETs);l关关闭一个套接口,一个套接口,释放套接口描述字放套接口描述字s,以后,以后对s的的访问均均以以WSAENOTSOCK错误返回。返回。l若本次若本次为对套接口的最后一次套接口的最后一次访问,则相相应的名字信息及的名字信息及数据数据队列都将被列都将被释放。放。lclose

42、socket()的的语义受受SO_LINGER与与SO_DONTLINGER选项影响,影响,对比如下:比如下:选项间隔 关闭方式 等待关闭与否 SO_DONTLINGER 不关心 优雅 否 SO_LINGER 零 强制 否 SO_LINGER 非零 优雅 是 42吉林大学软件学院吉林大学软件学院11禁禁止止在在一一个个套套接接口口上上进行行数数据据的的接接收收与与发送送SHUTDOWN()intshutdown(SOCKETs,inthow);l用于任何用于任何类型的套接口禁止接收、禁止型的套接口禁止接收、禁止发送或禁止收送或禁止收发。l如果how参数为0,则该套接口上的后续接收操作将被禁止。

43、l若how为1,则禁止后续发送操作,对于TCP,将发送FIN。 l若how为2,则同时禁止收和发。 l请注意注意shutdown()函数并不关函数并不关闭套接口,且套接口所占有套接口,且套接口所占有的的资源将被一直保持到源将被一直保持到closesocket()调用。用。43吉林大学软件学院吉林大学软件学院3.2.4Winsock的的辅助函数助函数1Winsock中的字中的字节顺序序转换函数函数图3-5两种本机字两种本机字节顺序序吉林大学软件学院吉林大学软件学院lWinsockAPI特特为此此设置了四个函数,置了四个函数,(1)htonl()l将将主主机机的的无无符符号号长整整型型数数本本机机

44、顺序序转换为网网络字字节顺序序(HosttoNetworkLong),用于,用于IP地址。地址。u_longPASCALFARhtonl(u_longhostlong);lhostlong是是主主机机字字节顺序序表表达达的的32位位数数。htonl()返返回回一一个网个网络字字节顺序的序的值。(2)htons()l将将主主机机的的无无符符号号短短整整型型数数转换成成网网络字字节顺序序(HosttoNetworkShort),用于端口号。,用于端口号。u_shortPASCALFARhtons(u_shorthostshort);lhostshort:主机字:主机字节顺序表达的序表达的16位数。

45、位数。htons()返回返回一个网一个网络字字节顺序的序的值。45吉林大学软件学院吉林大学软件学院(3)ntohl()l将将一一个个无无符符号号长整整型型数数从从网网络字字节顺序序转换为主主机机字字节顺序。序。(NetworktoHostLong),用于,用于IP地址。地址。u_longPASCALFARntohl(u_longnetlong);lnetlong是是一一个个以以网网络字字节顺序序表表达达的的32位位数数,ntohl()返回一个以主机字返回一个以主机字节顺序表达的数。序表达的数。(4)ntohs()l将将一一个个无无符符号号短短整整型型数数从从网网络字字节顺序序转换为主主机机字字

46、节顺序。序。(NetworktoHostSort),用于端口号,用于端口号u_shortPASCALFARntohs(u_shortnetshort);lnetshort是一个以网是一个以网络字字节顺序表达的序表达的16位数。位数。ntohs()返回一个以主机字返回一个以主机字节顺序表达的数。序表达的数。46吉林大学软件学院吉林大学软件学院2获取与套接口相取与套接口相连的端地址的端地址GETPEERNAME()intgetpeername(SOCKETs,structsockaddr*name,int*namelen);3获取一个套接口的本地名字取一个套接口的本地名字GETSOCKNAME()

47、intgetsockname(SOCKETs,structsockaddr*name,int*namelen);47吉林大学软件学院吉林大学软件学院4 将将 一一 个个 点点 分分 十十 进 制制 形形 式式 的的 IP地地 址址 转 换 成成 一一 个个 长 整整 型型 数数 INET_ADDR()unsignedlonginet_addr(constchar*cp);5将将网网络地地址址转换成成点点分分十十进制制的的字字符符串串格格式式INET_NTOA()char*inet_ntoa(structin_addrin);48吉林大学软件学院吉林大学软件学院3.2.5Winsock的信息查询

48、函数的信息查询函数lWinsockAPI提供了一提供了一组信息信息查询函数,函数,让我我们能能方便地方便地获取套接口所需要的网取套接口所需要的网络地址信息以及其地址信息以及其它信息,它信息,(1)Gethostname()l用来返回本地用来返回本地计算机的算机的标准主机名。准主机名。intgethostname(char*name,intnamelen);(2)Gethostbyname()l返回返回对应于于给定主机名的主机信息。定主机名的主机信息。structhostent*gethostbyname(constchar*name);吉林大学软件学院吉林大学软件学院(3)Gethostbya

49、ddr()根据一个根据一个IP地址取回相地址取回相应的主机信息。的主机信息。structhostent*gethostbyaddr(constchar*addr,intlen,inttype);(4)Getservbyname()返回返回对应于于给定服定服务名和名和协议名的相关服名的相关服务信息。信息。structservent*getservbyname(constchar*name,constchar*proto);(5)Getservbyport()返回返回对应于于给定端口号和定端口号和协议名的相关服名的相关服务信息。信息。structservent*getservbyport(intp

50、ort,constchar*proto);50吉林大学软件学院吉林大学软件学院(6)Getprotobyname()返回返回对应于于给定定协议名的相关名的相关协议信息。信息。structprotoent*getprotobyname(constchar*name);(7)Getprotobynumber()返回返回对应于于给定定协议号的相关号的相关协议信息。信息。structprotoent*getprotobynumber(intnumber);51l除除Gethostname()外,其它六个函数有以下共同特点:外,其它六个函数有以下共同特点:函数名都采用GetXbyY的形式。 如果函数成功

51、地执行,就返回一个指向某种结构的指针,该结构包含所需要的信息。如果函数执行发生错误,就返回一个空指针。应用程序可以立即调用WSAGetLastError()来得到一个特定的错误代码。函数执行时,可能在本地计算机上查询,也可能通过网络向域名服务器发送请求,来获得所需要的信息,这取决于用户网络的配置方式。为了能让程序在等待响应时能作其他的事情,Winsock API扩充了一组作用相同的异步查询函数,不会引起进程的阻塞。并且可以使用Windows的消息驱动机制。也是六个函数,与GetXbyY各函数对应,在每个函数名 前 面 加 上 了 WSAAsync前 缀 , 名 字 采 用 WSAAsyncGe

52、tXByY()的形式。它们的工作机制在后面详述。52吉林大学软件学院吉林大学软件学院3.2.6WSAAsyncGetXByY类型的型的扩展函数展函数lWSAAsyncGetXByY类型型的的扩展展函函数数是是GetXByY函函数数的的异异步步版版本本,这些些函函数数可可以以很很好好地地利利用用Windows的的消消息息驱动机制。机制。lWinsock的实现启动WSAAsyncGetXByY()操作后立即返回调用方,并传回一个异步任务句柄,应用程序可以用该句柄标识操作;l当操作完成时,如果有结果将会把结果复制到调用方提供的缓冲区buf中,同时向应用程序的窗口发一条消息;l应用程序窗口hWnd接收

53、到消息wMsg,该消息结构的wParam参数包含了初次函数调用时返回的异步任务句柄;Iprarm参数的高16位包含错误代码。531WSAAsyncGetHostByName()函数函数lgethostbyname()的的异异步步版版本本,用用于于获取取对应一一个个主主机机名的主机名称和地址信息。名的主机名称和地址信息。HANDLEWSAAsyncGetHostByName(HWNDhWnd,unsignedintwMsg,constchar*name,char*buf,intbuflen);lhWnd:异步请求完成时,接收消息的窗口句柄;lwMsg:异步请求完成时,将要接收的消息;lname:

54、指向主机名的指针;lbuf:接收hostent数据的数据区指针,需大于hostent结构大小,因为hostent结构引用的数据也都在该区域内。lbuflen:数据区的大小。l若若操操作作成成功功地地初初启启,返返回回一一个个HANDLE类型型的的非非0值,作作为请求需要的异步任求需要的异步任务句柄。句柄。l该HANDLE类型型的的值可可通通过WSACancelAsyncRequest()用用来来取取消消操操作作,也也可可通通过检查wParam消消息息参参数数,以以匹匹配配异异步操作和完成消息步操作和完成消息.542WSAAsyncGetHostByAddr()函数函数l本本函函数数是是geth

55、ostbyaddr()的的异异步步版版本本,用用来来获取取对应于于一个网一个网络地址的主机名和地址信息地址的主机名和地址信息.HANDLEWSAAsyncGetHostByAddr(HWNDhWnd,unsignedintwMsg,constchar*addr,intlen,inttype,char*buf,intbuflen);lhWnd 异步请求完成时,应该接收消息的窗口句柄.lwMsg 异步请求完成时,将要接收的消息. laddr 主机网络地址的指针,以网络字节次序存储. llen 地址长度.对于PF_INET来说必须为4. ltype 地址类型,必须是PF_INET. lbuf 接收h

56、ostent数据的数据区指针.lbuflen 上述数据区的大小.l返回返回值指出异步操作是否成功地初启指出异步操作是否成功地初启.l若若操操作作成成功功地地初初启启,WSAAsyncGetHostByAddr()返返回回一一个个HANDLE类型的非型的非0值,作,作为请求需要的异步任求需要的异步任务句柄句柄.l如如果果异异步步操操作作不不能能初初启启,WSAAsyncGetHostByAddr()返返回回一一个个0值,并且可使用并且可使用WSAGetLastError()来来获取取错误号号.553WSAAsyncGetServByName()函数函数l本本函函数数是是getservbyname

57、()的的异异步步版版本本,用用来来获取取对应于于一一个个服服务名的服名的服务信息信息.HANDLEWSAAsyncGetServByName(HWNDhWnd,unsignedintwMsg,constchar*name,constchar*proto,char*buf,intbuflen);lhWnd 异步请求完成时,应该接收消息的窗口句柄.lwMsg 异步请求完成时,将要接收的消息. lname 指向服务名的指针. lproto 指向协议名称的指针.它可能是NULL,在这种情况下,WSAAsyncGetServByName()将搜索第一个服务入口(满足 s_name或 s_aliases之

58、 一 和 所 给 的 名 字 匹 配 .)否 则 , WSAAsyncGetServByName()将和名和协议同时匹配. lbuf 接收hostent数据的数据区指针.lbuflen 上述数据区的大小.l返回返回值指出异步操作是否成功地初启指出异步操作是否成功地初启.564WSAAsyncGetServByPort()l本本函函数数是是getservbyport()的的异异步步版版本本,用用来来获取取对应于于一一个个端口号的服端口号的服务信息信息.HANDLEWSAAsyncGetServByPort(HWNDhWnd,unsignedintwMsg,intport,constchar*pr

59、oto,char*buf,intbuflen);lhWnd 异步请求完成时,应该接收消息的窗口句柄.lwMsg 异步请求完成时,将要接收的消息. lport 服务的接口.以网络字节序. lproto 指 向 协 议 名 称 的 指 针 .它 可 能 是 NULL,在 这 种 情 况 下 ,WSAAsyncGetServByName()将搜索第一个服务入口(满足s_name或s_aliases之一和所给的名字匹配.)否则, WSAAsyncGetServByName()将和名和协议同时匹配. lbuf 接收hostent数据的数据区指针.lbuflen 上述数据区的大小.l返回返回值指出异步操作

60、是否成功地初启指出异步操作是否成功地初启.575WSAAsyncGetProtoByName()函数函数l本本函函数数是是getprotobyname()的的异异步步版版本本,用用来来获获取取对对应应于于一一个协议名的协议名称和代号个协议名的协议名称和代号.HANDLEWSAAsyncGetProtoByName(HWNDhWnd,unsignedintwMsg,constchar*name,char*buf,intbuflen);lhWnd 异步请求完成时,应该接收消息的窗口句柄.lwMsg 异步请求完成时,将要接收的消息. lname 指向要获得的协议名的指针.lbuf 接收hostent

61、数据的数据区指针.lbuflen 上述数据区的大小.l返回返回值指出异步操作是否成功地初启指出异步操作是否成功地初启.l若若操操作作成成功功地地初初启启,WSAAsyncGetProtoByName()返返回回一一个个HANDLE类型的非型的非0值,作,作为请求需要的异步任求需要的异步任务句柄句柄.l如如果果异异步步操操作作不不能能初初启启,WSAAsyncGetProtoByName()返返回回一个一个0值,并且可使用并且可使用WSAGetLastError()来来获取取错误号号.586WSAAsyncGetProtoByNumber()函数函数l本本函函数数是是getprotobynumb

62、er()的的异异步步版版本本,用用来来获取取对应于一个于一个协议号的号的协议名称和代号名称和代号.HANDLEWSAAsyncGetProtoByNumber(HWNDhWnd,unsignedintwMsg,intnumber,char*buf,intbuflen);lhWnd 异步请求完成时,应该接收消息的窗口句柄.lwMsg 异步请求完成时,将要接收的消息. lnumber 要获得的协议号,以主机字节序. lbuf 接收hostent数据的数据区指针.lbuflen 上述数据区的大小. l返回返回值指出异步操作是否成功地初启指出异步操作是否成功地初启.l若若操操作作成成功功地地初初启启,

63、WSAAsyncGetProtoByNumber()返返回回一一个个HANDLE类型的非型的非0值,作,作为请求需要的异步任求需要的异步任务句柄句柄.l如如果果异异步步操操作作不不能能初初启启,WSAAsyncGetProtoByNumber)返返回一个回一个0值,并且可使用并且可使用WSAGetLastError()来来获取取错误号号.59吉林大学软件学院吉林大学软件学院3.3网络应用程序的运行环境网络应用程序的运行环境1.开开发WindowsSockets网网络应用用程程序序的的软、硬硬件件环境境l采采用用支支持持WindowsSocketsAPI的的Windows98SE以以上的操作系上

64、的操作系统;l采采用用可可视化化和和面面向向对象象技技术的的编程程语言言,如如MicrosoftVisualC+6.0;l采用采用TCP/IP网网络通信通信协议。吉林大学软件学院吉林大学软件学院l网网络中中的的所所采采用用的的计算算机机应满足足Windows运运行行的的配置要求。配置要求。l网网络中中各各节点点上上的的计算算机机需需安安装装网网卡卡,并并安安装装网网卡的卡的驱动程序。程序。l可可以以采采用用以以太太网网交交换机机将将若若干干台台计算算机机组建建成成局局域网。域网。l在在配配置置网网络时,首首先先实现对等等网网,使使各各计算算机机节点点能能在在“网网上上邻居居”中中找找到到自自己

65、己和和其其它它各各计算算机机,并能并能实现文件文件资源相互共享。源相互共享。l其次,网其次,网络配置中,配置中,应添加添加TCP/IP协议,设定相定相应的的IP地址。地址。吉林大学软件学院吉林大学软件学院2.调用用WindowsSockets接口的基本步接口的基本步骤l采采用用不不同同套套接接字字的的应用用程程序序的的调用用套套接接字字函函数数时,应遵循相遵循相应的步的步骤。3.使使用用VisualC+6.0进行行WindowsSockets程程序序开开发的其它技的其它技术要点要点l首先做好初始化处理。l通信双方的程序应采用统一的界面形式。l尽量采用多线程(Multithreaded)编程技术。l应充分利用Windows Sockets的基于消息的网络事件异步选择机制。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号