网络编程实用教程第3章课件

上传人:仙*** 文档编号:154550852 上传时间:2022-09-21 格式:PPT 页数:61 大小:1.37MB
收藏 版权申诉 举报 下载
网络编程实用教程第3章课件_第1页
第1页 / 共61页
网络编程实用教程第3章课件_第2页
第2页 / 共61页
网络编程实用教程第3章课件_第3页
第3页 / 共61页
资源描述:

《网络编程实用教程第3章课件》由会员分享,可在线阅读,更多相关《网络编程实用教程第3章课件(61页珍藏版)》请在装配图网上搜索。

1、吉林大学软件学院吉林大学软件学院3.1 Windows Sockets规范规范3.1.1 概述概述lMicrosoft公司以公司以Berkeley Sockets规范为范例,定义规范为范例,定义了了Windows Socktes规范,简称规范,简称Winsock规范规范。l这是这是Windows操作系统环境下的套接字网络应用程序操作系统环境下的套接字网络应用程序编程接口(编程接口(API)。)。l包含:包含:lBerkeley Socket 风格的库函数;l针对Windows操作系统的扩展库函数。l可以充分利用可以充分利用Windows的消息驱动机制编程。的消息驱动机制编程。lWinsock规

2、范定义了应用程序开发者能够使用,并且规范定义了应用程序开发者能够使用,并且网络软件供应商能够实现的一套库函数和相关语义,网络软件供应商能够实现的一套库函数和相关语义,让各个软件供应商共同遵守,做到让各个软件供应商共同遵守,做到Winsock兼容。兼容。吉林大学软件学院吉林大学软件学院图图3.1 网络应用进程利用网络应用进程利用Windock进行通信进行通信 吉林大学软件学院吉林大学软件学院3.1.2 Windows Sockets规范规范lWindows Sockets 规范是一套开放的、支持多种协规范是一套开放的、支持多种协议的议的Windows下的网络编程接口。下的网络编程接口。l从从19

3、91年到年到1995年,从年,从1.0版发展到版发展到2.0.8版,已成版,已成为为Windows网络编程的事实上的标准。网络编程的事实上的标准。1Windows Sockets 1.1版本版本l在在Winsock.h包含文件中,定义了包含文件中,定义了WinSock 1.1版本版本、和和。l库函数的实现在库函数的实现在Winsock.dll动态链接库文件中。动态链接库文件中。(1)WinSock 1.1 全面继承了全面继承了Berkeley Sockets规范。规范。l见表 3.1吉林大学软件学院吉林大学软件学院(1)WinSock 1.1 全面继承了全面继承了Berkeley Socket

4、s规范。规范。lWinsock1.1继承了Berkeley Sockets规范的主要特征,一部分库函数与之在形式上保持一致,包括库函数的名称、参数格式、结构定义。l见表 3.1。l其中,带*号的表明该例程在某些情况下可能会发生阻塞。主要函数SOCKET()创建一个套接字,并返回套接字的标识符BIND()把套接字绑定到特定的网络地址上LISTEN()启动指定的套接字,监听到来的连接请求ACCEPT()*接收一个连接请求,并新建一个套接字,原来的套接字返回监听状态CONNECT()*请求讲本地套接字连接到一个指定的远方套接字上SEND()*向一个已经与对方建立连接的套接字发送数据SENDTO()*

5、向一个未与对方建立连接的套接字发送数据,并指定对方网络地址RECV()*从一个已经与对方建立连接的套接字接收数据RECVFROM()*从一个未与对方建立连接的套接字接收数据,并返回对方网络地址SHUTDOWN()有选择的关闭套接字的全双工连接CLOSESOCEKT()*关闭套接字,释放相应的资源表表3.1 WinSock 1.1继承继承Berkeley Sockets的函数的函数辅助函数HTONL()把32位无符号数从主机字节序转换为网络字节序HTONS()把16位无符号数从主机字节序转换为网络字节序NTOHL()把32位无符号数从网络字节序转换为主机字节序NTOHS()把16位无符号数从网络

6、字节序转换为主机字节序INET_ADDR()把标准的点分十进制的IP转换成长整形地址数据INET_NTOA()把长整形的IP地址数据转换成点分十进制的字符串GETPEERNAME()获得套接字连接上对方的网络地址GETSOCKENAME()获得指定套接字的网络地址控制函数GETSOCKOPT()获得指定套接字的属性选项SETSOCKOPT()设置与指定套接字相关的属性选项IOCTLSOCKET()为套接字提供控制SELECT()*执行同步I/O多路复用表表3.1 WinSock 1.1继承继承Berkeley Sockets的函数的函数(cont.)(2)数据库函数数据库函数l表表3.2列出了

7、列出了Winsock规范定义的数据库查询函数。规范定义的数据库查询函数。l其中其中6个采用个采用的形式,大多要借助网络上的数的形式,大多要借助网络上的数据库来获得信息,而不采用本地数据库来实现。据库来获得信息,而不采用本地数据库来实现。函数名说明gethostname()用来返回本地计算机的标准主机名gethostbyname()*返回对英语给定主机名的主机信息gethostbyaddr()*根据一个IP地址取回相应的主机信息getservbyname()*返回对应于给定服务名和协议名的相关服务信息getservbyport()*返回对应于给定端口号和协议名的相关服务信息getportbyna

8、me()*返回对应于给定协议名的相关服务信息getportbynumber()*返回对应于给定协议号的相关服务信息表表3.2 数据库查询函数数据库查询函数吉林大学软件学院吉林大学软件学院lgetXbyY()形式的数据库例程都返回一个指针,指形式的数据库例程都返回一个指针,指向某种类型的结构区域,用来存放函数返回的数向某种类型的结构区域,用来存放函数返回的数据信息。据信息。l这些结构区域是由winsock实现(即Winsock.dll)分配的,由系统管理,所以指针指向的结构数据是易失的,只在该线程的下一个Winsock API调用前有效。l一个线程中只有一个该结构的副本,因此应用程序在发出下一个

9、Winsock API调用前,应把所需的信息复制下来。l应用程序不应试图修改或释放这个结构。吉林大学软件学院吉林大学软件学院(3)WinSock 1.1 扩充了扩充了Berkeley Sockets规范规范l针对微软针对微软 Windows的特点,的特点,WinSock 1.1定义了一定义了一批新的库函数,提供了对批新的库函数,提供了对的支持,的支持,有效地利用有效地利用的机制。的机制。l扩充主要是提供了一些异步函数,增加了符合Windows消息驱动特性的网络事件异步选择机制,有利于开发符合Windows编程模式的软件,使得开发高性能网络通信程序成为可能。l这些扩充函数的名字都以WSA开头,后

10、面跟async表示是专为实现异步机制而设置的。l编程时必须使用WSAStartup()和WSACleanup(),其它函数随意使用。10表表3.3 Winsock 1.1的常用扩展函数的常用扩展函数Winsock的注册与注销函数WSAStartup()初始化低层Windows Socks DLLWSACleanup()从低层的Windows Sockets DLL撤销注册异步执行的数据库查询函数WSAAsynGetHostBYName()GetHostBYName()的异步版本WSAAsynGetHostBYAddr()GetHostBYAddr()的异步版本WSAAsynGetServByN

11、ame()GetServByName()的异步版本WSAAsynGetServByPort()GetServByPort()的异步版本WSAAsynGetProtobyNameGetProtobyName()的异步版本WSAAsynGetProtobyNumber()GetProtobyNumber()的异步版本11表表3.3 Winsock 1.1的常用扩展函数(续)的常用扩展函数(续)异步机制的相关函数WSAAsynSelect()Select()的异步版本WSACancelAsyncRequest()取消一个未完成的WSAAsyncGetXByY()函数的实例WSACancelBlock

12、ingCall()取消未完成的阻塞的API调用WSAIsBlocking()确定线程是否被一个调用阻塞错误处理相关函数WSAGetLastError()得到最近一个Winsock调用出错的详细信息WSASetLastError()设置下一次WSAGetLastError()返回的错误信息吉林大学软件学院吉林大学软件学院(4)WinSock 1.1只支持只支持TCP/IP协议栈协议栈 lWinsock 1.1的实现,即的实现,即Winsock.dll和底层协议栈和底层协议栈的接口是唯一的,且是独占的,只能访问的接口是唯一的,且是独占的,只能访问TCP/IP协议栈。协议栈。l因此,因此,Winso

13、ck 1.1套接字仅支持单一的通信域,套接字仅支持单一的通信域,即即Internet域。域。吉林大学软件学院吉林大学软件学院2WinSock 2.0规范规范lWinSock 2.0在源码和二进制代码方面与WinSock 1.1兼容,此外还增强了许多功能。(1)支持多种协议(2)引入了重叠I/O的概念(3)使用事件对象异步通知(4)服务的质量(QOS)(5)套接口组(6)扩展的字节顺序转换例程(7)分散/聚集方式I/O(8)新增了许多函数。吉林大学软件学院吉林大学软件学院3.WinSock 1.1中的阻塞问题中的阻塞问题l阻塞是在把应用程序从Berkeley套接口环境中移植到Windows环境中

14、的一个主要焦点,虽然Windows Sockets支持关于套接口的阻塞操作,但是这种应用是被强烈反对的。l阻塞,是指唤起一个函数,该函数直到相关操作完成时才返回。l在Berkeley套接口模型中,一个套接口的操作的缺省行为是阻塞方式的,除非程序员显式地请求该操作为非阻塞方式。l在Windows环境下,强烈推荐程序员尽可能使用非阻塞方式(异步方式)的操作,因为非阻塞方式的操作能够更好地在非占先的Windows环境下工作。吉林大学软件学院吉林大学软件学院l有些Sockets操作在阻塞和非阻塞方式下没什么区别;而有些Sockets操作取决于传输情况,会立即完成或阻塞一段时间。l当操作用于阻塞套接口(

15、打*号标记的)时,这些操作被认为是工作于阻塞方式的。l在Windows Sockets实现中,一个无法立刻完成的阻塞操作是按如下方式处理的:lDLL先初始化操作,然后进入一个循环,在循环中发送收到的任何信息,以便必要时将处理器交给其它线程;l然后检查Windows Sockets功能是否完成,如果完成了,WSACancleBlockingCall()被唤起,阻塞操作以一个适当的返回值结束。吉林大学软件学院吉林大学软件学院l如果一个正在运行某一阻塞操作的进程收到了一个Windows消息,那么应用程序有可能试图发出另一个Windows Sockets调用。l由于难以安全的处理这种情况,Window

16、s Sockets规范不支持这种应用程序的工作方式,此时可以借助两个函数来解决:lWSAIsBlocking()可以用来确定在该进程上是否有阻塞的Windows Sockets调用;lWSACancleBlockingCall()可以用来取消在线的阻塞调用,如果有的话。l其它任何Windows Sockets函数此时被调用,都会失败并返回错误代码WSAEINPROGRESS。l这一限制适用于所有阻塞和非阻塞操作。吉林大学软件学院吉林大学软件学院3.1.3 WinSock规范与规范与Berkeley套接口的区别套接口的区别1套接口数据类型和该类型的错误返回值l在在UNIX中,包括套接口句柄在内的

17、所有句柄,都是中,包括套接口句柄在内的所有句柄,都是非负的短整数;非负的短整数;l在在WinSock规范中定义了一个新的数据类型,称作规范中定义了一个新的数据类型,称作SOCKET,用来代表套接字描述符。,用来代表套接字描述符。typedef u_int SOCKET;lsocket()和和accept()函数返回时,返回的就是函数返回时,返回的就是SOCKET类型。类型。lSOCKET可以取从可以取从0到到INVALID_SOCKET-1之间的任之间的任意值。意值。吉林大学软件学院吉林大学软件学院l要判断要判断socket()和和accept()是否正确执行,可以将返回是否正确执行,可以将返

18、回值和值和INVALID_SOCKET来比较,该常量已在来比较,该常量已在Winsock.h中定义。中定义。l例如:例如: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结构用来代表一组

19、套接口。结构用来代表一组套接口。3错误代码的获得lUNIX套接字规范中,如果函数执行时发生了错误,套接字规范中,如果函数执行时发生了错误,会把错误代码放到会把错误代码放到errno或或h_errno变量中。变量中。l在在Winsock中错误代码可以使用中错误代码可以使用WSAGetLastError()调用得到。调用得到。4指针l所有应用程序与所有应用程序与Windows Sockets使用的指针都必须是使用的指针都必须是FAR指针。指针。吉林大学软件学院吉林大学软件学院5.重命名的函数l有两个伯克利套接口函数改了名字,避免与其它有两个伯克利套接口函数改了名字,避免与其它API冲突。冲突。lc

20、lose()改变为closesocket()lioctl()改变为ioctlsocket()6.Winsock支持的最大套接口数目l一个特定的一个特定的Windows Sockets提供者所支持的套接口提供者所支持的套接口的最大数目是由实现确定的;任何一个应用程序都不的最大数目是由实现确定的;任何一个应用程序都不应假设某个待定数目的套接口可用。应假设某个待定数目的套接口可用。l一个一个Windows Sockets应用程序可以使用的套接口的应用程序可以使用的套接口的最大数目在最大数目在Winsock.h中缺省值是中缺省值是64,在编译时由常,在编译时由常量量决定。决定。吉林大学软件学院吉林大学

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

22、方法、错误处理、启动和终止等方面。、错误处理、启动和终止等方面。吉林大学软件学院吉林大学软件学院3.2 Winsock 1.1的库函数的库函数3.2.1 Winsock的注册与注销的注册与注销 1初始化函数WSAStartup()lWinsock应用程序要做的第一件事,就是必须首先调应用程序要做的第一件事,就是必须首先调用用WSAStartup()函数对函数对Winsock进行进行。l初始化也称为初始化也称为,注册成功后,才能调用其他的,注册成功后,才能调用其他的Winsock API函数。函数。(1)WSAStartup()函数的调用格式函数的调用格式int WSAStartup(WORD

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

24、LEN 128typedef struct WSAData WORD wVersion;WORD wHighVersion;char szDescriptionWSADESCRIPTION_LEN+1;char szSystemStatusWSASYS_STATUS_LEN+1;unsigned short iMaxSockets;unsigned short iMaxUdpDg;char*lpVendorInfo;WSADATA;吉林大学软件学院吉林大学软件学院25(4)初始化函数可能返回的错误代码初始化函数可能返回的错误代码WSASYSNOTREADY:网络通信依赖的网络子系统没有准备好。

25、网络通信依赖的网络子系统没有准备好。WSAVERNOTSUPPORTED:找不到所需的找不到所需的Winsock API相应的动态连接库。相应的动态连接库。WSAEINVAL:DLL不支持应用程序所需的不支持应用程序所需的Winsock版本。版本。WSAEINPROGRESS:正在执行一个阻塞的正在执行一个阻塞的Winsock 1.1操作。操作。WSAEPROCLIM:已经达到已经达到Winsock支持的任务数上限。支持的任务数上限。WSAEFAULT:参数参数lpWSAData不是合法指针。不是合法指针。26(5)初始化初始化Winsock的示例的示例#include /对于对于Winsoc

26、k 2.0,应包括,应包括 Winsock2.h文件文件aa()WORD wVersionRequested;/应用程序所需的应用程序所需的Winsock版本号版本号WSADATA wsaData;/用来返回用来返回Winsock 实现的细节信息实现的细节信息Int err;/出错代码。出错代码。wVersionRequested=MAKEWORD(1,1);/生成版本号生成版本号1.1err=WSAStartup(wVersionRequested,&wsaData);/调用初始化函数调用初始化函数if(err!=0)return;/通知用户找不到合适的通知用户找不到合适的DLL文件文件/确

27、认返回的版本号是客户要求的确认返回的版本号是客户要求的1.1if(LOBYTE(wsaData.wVersion)!=1|HYBYTE(wsaData.wVersion)!=1?)WSACleanup();return;/*至此,可以确认初始化成功,至此,可以确认初始化成功,Winsock.DLL可用。可用。吉林大学软件学院吉林大学软件学院2注销函数WSACleanup()l程序使用完Winsock.DLL提供的服务后,应用程序必须调用WSACleanup()函数,来解除与Winsock.DLL库的绑定,释放Winsock实现分配给应用程序的系统资源,中止对Windows Sockets DL

28、L的使用。(1)WSACleanup()函数的调用格式函数的调用格式int WSACleanup(void);l返 回 值:如 果 操 作 成 功 返 回 0,否 则 返 回SOCKET_ERROR.27(2)WSACleanup()函数的功能函数的功能l对应于一个任务进行的每一次对应于一个任务进行的每一次WSAStartup()调用,必须有调用,必须有一个一个WSACleanup()调用。调用。l只有最后的只有最后的WSACleanup()做实际的清除工作;前面的调做实际的清除工作;前面的调用仅仅将用仅仅将Windows Sockets DLL中的内置引用计数递减。中的内置引用计数递减。l一

29、个简单的应用程序为确保一个简单的应用程序为确保WSACleanup()调用了足够的调用了足够的次数,可以在一个循环中不断调用次数,可以在一个循环中不断调用WSACleanup()直至返直至返WSANOTINITIALISED。(3)WSACleanup()函数可能返回的错误代码函数可能返回的错误代码lWSANOTINITIALISED:在调用本API之前应成功调用WSAStartup()。lWSAENETDOWN:检测到网络子系统失效。lWSAEINPROGRESS:一个阻塞的WinSock调用正在进行中,或者服务提供者仍在处理一个回调函数。28吉林大学软件学院吉林大学软件学院3.2.2 Wi

30、nsock的错误处理函数的错误处理函数lWinsock函数执行时都有一个返回值,只能说明函数函数执行时都有一个返回值,只能说明函数的执行成功与否,不能从返回值了解出错原因。的执行成功与否,不能从返回值了解出错原因。1WSAGetLastError()函数函数int WSAGetLastError(void);l返回本线程进行的上一次返回本线程进行的上一次Winsock函数调用时,产生函数调用时,产生的错误代码。的错误代码。l在在Winsock.h中定义了所有的错误代码,基数是中定义了所有的错误代码,基数是10000 2WSASetLastError()函数函数void WSASetLastEr

31、ror(int iError);l本函数允许应用程序为当前线程设置错误代码,并可本函数允许应用程序为当前线程设置错误代码,并可由后来的由后来的WSAGetLastError()调用返回。调用返回。吉林大学软件学院吉林大学软件学院3.2.3 主要的主要的Winsock函数函数1创建套接口创建套接口SOCKET()SOCKET socket(int af,int type,int protocol);l返回值:创建成功,返回套接字描述符,否则返回返回值:创建成功,返回套接字描述符,否则返回SOCK_ERROR。l举例:举例:SOCKET sockfd=SOCKET(AF_INET,SOCK_STR

32、EAM,0);/*创建一个流式套接字。SOCKET sockfd=SOCKET(AF_INET,SOCK_DGRAM,0);/*创建一个数据报套接字。吉林大学软件学院吉林大学软件学院2将套接口绑定到指定的网络地址将套接口绑定到指定的网络地址BIND()int bind(SOCKET s,const struct sockaddr*name,int namelen);l有许多函数都需要套接字的地址信息,像有许多函数都需要套接字的地址信息,像UNIX 套接套接字一样,字一样,Winsock也定义了三种关于地址的结构,经也定义了三种关于地址的结构,经常使用。常使用。通用的通用的Winsock地址结构

33、,针对各种通信域的套接字地址结构,针对各种通信域的套接字,存储它们的地址信息。,存储它们的地址信息。struct sockaddr u_short sa_family;/*地址家族char sa_data14;/*协议地址 31专门针对专门针对Internet 通信域的通信域的Winsock地址结构地址结构struct sockaddr_in short sin_family;/*指定地址家族,一定是AF_INET.u_short sin_port;/*指定将要分配给套接字的传输层端口号,struct in_addr sin_addr;/*指定套接字的主机的IP 地址char sin_zero

34、8;/*全置为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;32吉林大学软件学院吉林大学软件学院l在使用在使用Internet域的套接字时,这三个数据结构的一域的套接字时,这三个数据结构的一般用法是:般用法是:l首先,定义一个Sockaddr_in的结构实例变量,并将它清零;l然后,为这个结构的各成员变量赋值;l第三步,在调用BIND()绑定函数时,将指向这个结构的

35、指针强制转换为 sockaddr*类型。33l举例:举例:SOCKET serSock;/定义了一个SOCKET 类型的变量。sockaddr_in my_addr;/定义一个Sockaddr_in型的结构实例变量。int err;/出错码。出错码。int slen=sizeof(sockaddr);/sockaddr 结构的长度。serSock=SOCKET(AF_INET,SOCK_DGRAM,0);/创建数据报套接字。memset(my_addr,0);/将Sockaddr_in的结构实例变量清零。my_addr.sin_family=AF_INET;/指定通信域是Internet。my

36、_addr.sin_port=htons(21);/指定端口,将端口号转换为网络字节顺序。34/*指定IP地址,将IP地址转换为网络字节顺序。my_addr.sin_addr.s_addr=htonl(INADDR-ANY);/*将套接字绑定到指定的网络地址,对&my_addr进行了强制类型转换。if (BIND(serSock,(LPSOCKADDR?)&my_addr,slen)=SOCKET_ERROR)/*调用WSAGetLastError()函数,获取最近一个操作的错误代码。err=WSAGetLastError();/*以下可以报错,进行错误处理。35吉林大学软件学院吉林大学软件学

37、院3启动服务器监听客户端的连接请求启动服务器监听客户端的连接请求LISTEN()int listen(SOCKET s,int backlog);l仅适用于支持连接的SOCK_STREAM类型的套接口。套接口s处于一种“变动”模式,申请进入的连接请求被确认,并排队等待被接受。l这个函数特别适用于同时有多个连接请求的服务器;如果当一个连接请求到来时,队列已满,那么客户将收到一个WSAECONNREFUSED错误。4接收连接请求接收连接请求ACCEPT()SOCKET accept(SOCKET s,struct sockaddr*addr,int*addrlen);36吉林大学软件学院吉林大学软

38、件学院5请求连接请求连接CONNECT()int connect(SOCKET s,struct sockaddr*name,int namelen);l举例举例struct sockaddr_in daddr;memset(void*)&daddr,0,sizeof(daddr);daddr.sin_family=AF_INET;daddr.sin_port=htons(8888);daddr.sin_addr.s_addr=inet_addr(133.197.22.4);connect(ClientSocket,(struct sockaddr*)&daddr,sizeof(daddr);

39、37386向一个已连接的套接口发送数据向一个已连接的套接口发送数据SEND()int send(SOCKET s,char*buf,int len,int flags);图图3.3 同步套接字的同步套接字的Send()函数的执行流程函数的执行流程 397从一个已连接套接口接收数据从一个已连接套接口接收数据RECV()int recv(SOCKET s,char*buf,int len,int flags);图图3-4说明了说明了send和和recv的作用,套接字缓冲区与应用进程缓冲的作用,套接字缓冲区与应用进程缓冲区的关系,以及协议栈所作的传送。区的关系,以及协议栈所作的传送。图图3.4 Se

40、nd()和和Recv()都是对本地套接字的操作都是对本地套接字的操作 吉林大学软件学院吉林大学软件学院8按照指定目的地向数据报套接字发送数据按照指定目的地向数据报套接字发送数据SENDTO()int sendto(SOCKET s,char*buf,int len,int flags,struct sockaddr*to,int tolen);9接收一个数据报并保存源地址,从数据报套接字接接收一个数据报并保存源地址,从数据报套接字接收数据收数据RECVFORM()int recvfrom(SOCKET s,char*buf,int len,int flags,struct sockaddr*f

41、rom,int*fromlen);40吉林大学软件学院吉林大学软件学院10关闭套接字关闭套接字CLOSESOCKET()int closesocket(SOCKET s);l关闭一个套接口,释放套接口描述字关闭一个套接口,释放套接口描述字s,以后对,以后对s的访问均的访问均以以WSAENOTSOCK错误返回。错误返回。l若本次为对套接口的最后一次访问,则相应的名字信息及若本次为对套接口的最后一次访问,则相应的名字信息及数据队列都将被释放。数据队列都将被释放。lclosesocket()的语义受的语义受SO_LINGER与与SO_DONTLINGER选项影响,对比如下:选项影响,对比如下:选项间

42、隔 关闭方式 等待关闭与否 SO_DONTLINGER 不关心 优雅 否 SO_LINGER 零 强制 否 SO_LINGER 非零 优雅 是 41吉林大学软件学院吉林大学软件学院11禁止在一个套接口上进行数据的接收与发送禁止在一个套接口上进行数据的接收与发送SHUTDOWN()int shutdown(SOCKET s,int how);l用于任何类型的套接口禁止接收、禁止发送或禁止收发。用于任何类型的套接口禁止接收、禁止发送或禁止收发。l如果how参数为0,则该套接口上的后续接收操作将被禁止。l若how为1,则禁止后续发送操作,对于TCP,将发送FIN。l若how为2,则同时禁止收和发。l

43、请注意请注意shutdown()函数并不关闭套接口,且套接口所占有函数并不关闭套接口,且套接口所占有的资源将被一直保持到的资源将被一直保持到closesocket()调用。调用。42吉林大学软件学院吉林大学软件学院3.2.4 Winsock的辅助函数的辅助函数1Winsock中的字节顺序转换函数中的字节顺序转换函数图图3-5 两种本机字节顺序两种本机字节顺序 吉林大学软件学院吉林大学软件学院lWinsock API特为此设置了四个函数,特为此设置了四个函数,(1)htonl()l将主机的无符号长整型数本机顺序转换为网络字节顺将主机的无符号长整型数本机顺序转换为网络字节顺序序(Host to N

44、etwork Long),用于,用于IP地址。地址。u_long PASCAL FAR htonl(u_long hostlong);lhostlong是主机字节顺序表达的是主机字节顺序表达的32位数。位数。htonl()返回返回一个网络字节顺序的值。一个网络字节顺序的值。(2)htons()l将主机的无符号短整型数转换成网络字节顺序将主机的无符号短整型数转换成网络字节顺序(Host to Network Short),用于端口号。,用于端口号。u_short PASCAL FAR htons(u_short hostshort);lhostshort:主机字节顺序表达的:主机字节顺序表达的1

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

46、数从网络字节顺序转换为主机字将一个无符号短整型数从网络字节顺序转换为主机字节顺序。节顺序。(Network to Host Sort),用于端口号,用于端口号u_short PASCAL FAR ntohs(u_short netshort);lnetshort是一个以网络字节顺序表达的是一个以网络字节顺序表达的16位数。位数。ntohs()返回一个以主机字节顺序表达的数。返回一个以主机字节顺序表达的数。45吉林大学软件学院吉林大学软件学院2获取与套接口相连的端地址获取与套接口相连的端地址GETPEERNAME()int getpeername(SOCKET s,struct sockaddr

47、*name,int*namelen);3获取一个套接口的本地名字获取一个套接口的本地名字GETSOCKNAME()int getsockname(SOCKET s,struct sockaddr*name,int*namelen);46吉林大学软件学院吉林大学软件学院4将一个点分十进制形式的将一个点分十进制形式的IP地址转换成一个长整型地址转换成一个长整型数数INET_ADDR()unsigned long inet_addr(const char*cp);5将网络地址转换成点分十进制的字符串格式将网络地址转换成点分十进制的字符串格式INET_NTOA()char*inet_ntoa(stru

48、ct in_addr in);47吉林大学软件学院吉林大学软件学院3.2.5 Winsock的信息查询函数的信息查询函数lWinsock API提供了一组信息查询函数,让我们能提供了一组信息查询函数,让我们能方便地获取套接口所需要的网络地址信息以及其方便地获取套接口所需要的网络地址信息以及其它信息,它信息,(1)Gethostname()l用来返回本地计算机的标准主机名。用来返回本地计算机的标准主机名。int gethostname(char*name,int namelen);(2)Gethostbyname()l返回对应于给定主机名的主机信息。返回对应于给定主机名的主机信息。struct

49、hostent*gethostbyname(const char*name);吉林大学软件学院吉林大学软件学院(3)Gethostbyaddr()根据一个根据一个IP地址取回相应的主机信息。地址取回相应的主机信息。struct hostent*gethostbyaddr(const char*addr,int len,int type);(4)Getservbyname()返回对应于给定服务名和协议名的相关服务信息。返回对应于给定服务名和协议名的相关服务信息。struct servent*getservbyname(const char*name,const char*proto);(5)Ge

50、tservbyport()返回对应于给定端口号和协议名的相关服务信息。返回对应于给定端口号和协议名的相关服务信息。struct servent*getservbyport(int port,const char*proto);49吉林大学软件学院吉林大学软件学院(6)Getprotobyname()返回对应于给定协议名的相关协议信息。返回对应于给定协议名的相关协议信息。struct protoent*getprotobyname(const char*name);(7)Getprotobynumber()返回对应于给定协议号的相关协议信息。返回对应于给定协议号的相关协议信息。struct pr

51、otoent*getprotobynumber(int number);50l除除Gethostname()外,其它六个函数有以下共同特点:外,其它六个函数有以下共同特点:函数名都采用GetXbyY的形式。如果函数成功地执行,就返回一个指向某种结构的指针,该结构包含所需要的信息。如果函数执行发生错误,就返回一个空指针。应用程序可以立即调用WSAGetLastError()来得到一个特定的错误代码。函数执行时,可能在本地计算机上查询,也可能通过网络向域名服务器发送请求,来获得所需要的信息,这取决于用户网络的配置方式。为了能让程序在等待响应时能作其他的事情,Winsock API扩充了一组作用相同

52、的异步查询函数,不会引起进程的阻塞。并且可以使用Windows的消息驱动机制。也是六个函数,与GetXbyY各函数对应,在每个函数名 前 面 加 上 了 W S A A s y n c 前 缀,名 字 采 用WSAAsyncGetXByY()的形式。它们的工作机制在后面详述。51吉林大学软件学院吉林大学软件学院3.2.6 WSAAsyncGetXByY类型的扩展函数类型的扩展函数lWSAAsyncGetXByY类型的扩展函数是类型的扩展函数是GetXByY函数函数的异步版本,这些函数可以很好地利用的异步版本,这些函数可以很好地利用Windows的消的消息驱动机制。息驱动机制。lWinsock的

53、实现启动WSAAsyncGetXByY()操作后立即返回调用方,并传回一个异步任务句柄,应用程序可以用该句柄标识操作;l当操作完成时,如果有结果将会把结果复制到调用方提供的缓冲区buf中,同时向应用程序的窗口发一条消息;l应用程序窗口hWnd接收到消息wMsg,该消息结构的wParam参数包含了初次函数调用时返回的异步任务句柄;Iprarm参数的高16位包含错误代码。521WSAAsyncGetHostByName()函数函数lgethostbyname()的异步版本,用于获取对应一个主机的异步版本,用于获取对应一个主机名的主机名称和地址信息。名的主机名称和地址信息。HANDLE WSAAsy

54、ncGetHostByName(HWND hWnd,unsigned int wMsg,const char*name,char*buf,int buflen);lhWnd:异步请求完成时,接收消息的窗口句柄;lwMsg:异步请求完成时,将要接收的消息;lname:指向主机名的指针;lbuf:接收hostent数据的数据区指针,需大于hostent结构大小,因为hostent结构引用的数据也都在该区域内。lbuflen:数据区的大小。l若操作成功地初启,返回一个若操作成功地初启,返回一个HANDLE类型的非类型的非0值,作值,作为请求需要的异步任务句柄。为请求需要的异步任务句柄。l该该HAND

55、LE类型的值可通过类型的值可通过WSACancelAsyncRequest()用用来取消操作,也可通过检查来取消操作,也可通过检查wParam消息参数,以匹配异消息参数,以匹配异步操作和完成消息步操作和完成消息.53 2WSAAsyncGetHostByAddr()函数函数l本函数是本函数是gethostbyaddr()的异步版本,用来获取对应于的异步版本,用来获取对应于一个网络地址的主机名和地址信息一个网络地址的主机名和地址信息.HANDLE WSAAsyncGetHostByAddr(HWND hWnd,unsigned int wMsg,const char*addr,int len,i

56、nt type,char*buf,int buflen);lhWnd 异步请求完成时,应该接收消息的窗口句柄.lwMsg 异步请求完成时,将要接收的消息.laddr 主机网络地址的指针,以网络字节次序存储.llen 地址长度.对于PF_INET来说必须为4.ltype 地址类型,必须是PF_INET.lbuf 接收hostent数据的数据区指针.lbuflen 上述数据区的大小.l返回值指出异步操作是否成功地初启返回值指出异步操作是否成功地初启.l若操作成功地初启,若操作成功地初启,WSAAsyncGetHostByAddr()返回一个返回一个HANDLE类型的非类型的非0值,作为请求需要的异

57、步任务句柄值,作为请求需要的异步任务句柄.l如果异步操作不能初启如果异步操作不能初启,WSAAsyncGetHostByAddr()返回一返回一个个0值值,并且可使用并且可使用WSAGetLastError()来获取错误号来获取错误号.543WSAAsyncGetServByName()函数函数l本函数是本函数是getservbyname()的异步版本,用来获取对应于一个的异步版本,用来获取对应于一个服务名的服务信息服务名的服务信息.HANDLE WSAAsyncGetServByName(HWND hWnd,unsigned int wMsg,const char*name,const ch

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

59、.554WSAAsyncGetServByPort()l本函数是本函数是getservbyport()的异步版本,用来获取对应于一个的异步版本,用来获取对应于一个端口号的服务信息端口号的服务信息.HANDLE WSAAsyncGetServByPort(HWND hWnd,unsigned int wMsg,int port,const char*proto,char*buf,int buflen);lhWnd 异步请求完成时,应该接收消息的窗口句柄.lwMsg 异步请求完成时,将要接收的消息.lport 服务的接口.以网络字节序.lproto 指向协议名称的指针.它可能是NULL,在这种情况

60、下,WSAAsyncGetServByName()将搜索第一个服务入口(满足s_name或s_aliases之一和所给的名字匹配.)否则,WSAAsyncGetServByName()将和名和协议同时匹配.lbuf 接收hostent数据的数据区指针.lbuflen 上述数据区的大小.l返回值指出异步操作是否成功地初启返回值指出异步操作是否成功地初启.565WSAAsyncGetProtoByName()函数函数l本函数本函数是是getprotobyname()的异步的异步版本,用来获取对应于一版本,用来获取对应于一个协议名的协议名称和代号个协议名的协议名称和代号.HANDLE WSAAsyn

61、cGetProtoByName(HWND hWnd,unsigned int wMsg,const char*name,char*buf,int buflen);lhWnd 异步请求完成时,应该接收消息的窗口句柄.lwMsg 异步请求完成时,将要接收的消息.lname 指向要获得的协议名的指针.lbuf 接收hostent数据的数据区指针.lbuflen 上述数据区的大小.l返回值指出异步操作是否成功地初启返回值指出异步操作是否成功地初启.l若操作成功地初启,若操作成功地初启,WSAAsyncGetProtoByName()返回一返回一个个HANDLE类型的非类型的非0值,作为请求需要的异步任

62、务句柄值,作为请求需要的异步任务句柄.l如果异步操作不能初启如果异步操作不能初启,WSAAsyncGetProtoByName()返回返回一个一个0值值,并且可使用并且可使用WSAGetLastError()来获取错误号来获取错误号.576WSAAsyncGetProtoByNumber()函数函数l本函数是本函数是getprotobynumber()的异步版本,用来获取对的异步版本,用来获取对应于一个协议号的协议名称和代号应于一个协议号的协议名称和代号.HANDLE WSAAsyncGetProtoByNumber(HWND hWnd,unsigned int wMsg,int number

63、,char*buf,int buflen);lhWnd 异步请求完成时,应该接收消息的窗口句柄.lwMsg 异步请求完成时,将要接收的消息.lnumber 要获得的协议号,以主机字节序.lbuf 接收hostent数据的数据区指针.lbuflen 上述数据区的大小.l返回值指出异步操作是否成功地初启返回值指出异步操作是否成功地初启.l若操作成功地初启,若操作成功地初启,WSAAsyncGetProtoByNumber()返回返回一个一个HANDLE类型的非类型的非0值,作为请求需要的异步任务句柄值,作为请求需要的异步任务句柄.l如果异步操作不能初启如果异步操作不能初启,WSAAsyncGetP

64、rotoByNumber)返返回一个回一个0值值,并且可使用并且可使用WSAGetLastError()来获取错误号来获取错误号.58吉林大学软件学院吉林大学软件学院3.3 网络应用程序的运行环境网络应用程序的运行环境1.开发开发Windows Sockets网络应用程序的软、硬件网络应用程序的软、硬件环境环境l采用支持采用支持Windows Sockets API的的Windows98SE以上的操作系统;以上的操作系统;l采用可视化和面向对象技术的编程语言,如采用可视化和面向对象技术的编程语言,如Microsoft Visual C+6.0;l采用采用TCP/IP网络通信协议。网络通信协议。

65、吉林大学软件学院吉林大学软件学院l网络中的所采用的计算机应满足网络中的所采用的计算机应满足Windows运行的运行的配置要求。配置要求。l网络中各节点上的计算机需安装网卡,并安装网网络中各节点上的计算机需安装网卡,并安装网卡的驱动程序。卡的驱动程序。l可以采用以太网交换机将若干台计算机组建成局可以采用以太网交换机将若干台计算机组建成局域网。域网。l在配置网络时,首先实现对等网,使各计算机节在配置网络时,首先实现对等网,使各计算机节点能在点能在“网上邻居网上邻居”中找到自己和其它各计算机中找到自己和其它各计算机,并能实现文件资源相互共享。,并能实现文件资源相互共享。l其次,网络配置中,应添加其次

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

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


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