收藏 分享(赏)

Windows网络程序设习题课资料.doc

上传人:dzzj200808 文档编号:2262381 上传时间:2018-09-08 格式:DOC 页数:21 大小:377.50KB
下载 相关 举报
Windows网络程序设习题课资料.doc_第1页
第1页 / 共21页
Windows网络程序设习题课资料.doc_第2页
第2页 / 共21页
Windows网络程序设习题课资料.doc_第3页
第3页 / 共21页
Windows网络程序设习题课资料.doc_第4页
第4页 / 共21页
Windows网络程序设习题课资料.doc_第5页
第5页 / 共21页
点击查看更多>>
资源描述

1、网络通信程序设计复习习题(一)(注:这周请同学们复习,下周测验,期末试题是从下列试题中选择)一、基本概念1. Winsock 是什么? Windows 下网络编程的规范 Windows 下得到广泛应用的、开放的、支持多种协议的网络编程接口。 已成为 Windows 网络编程的事实上的标准。 2. Windows socket 规范 Windows Socket 规范本意在于提供给应用程序开发者一套简单的 API,并让各家网络软件供应商共同遵守。3. Socket 原理 Socket 通常称为套接字、套管、插口,是两个程序间通信链路的端点。 Socket 实际上是一个编程接口,为网络应用程序提供

2、各种接口函数。4. Winsock 基本概念1. 多数网络协议都由软件实现,而且几乎所有计算机系统都将网络协议的实现作为操作系统的一部分,操作系统提供给用户的程序接口叫做应用程序编程接口(API ) 。2. 套接字接口(Socket Interface) 就是一种 API5. 套接字及类型1. 套接字(socket)是网络通信的基本构件,是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和与之相连的进程。2. 套接字存在于通信区域中,通信区域也称地址族3. 套接字通常只与同一区域中的套接字交换数据(也可跨区域通信,但要执行某种转换进程之后才能实现) 。4. TCP/IP 的 sock

3、et 提供三种类型的套接字: 流式套接字(SOCK_STREAM) 提供一个面向连接的、可靠的数据传输服务, 内设流量控制,避免数据流超限;数据被看作是字节流,无长度限制。 文件传输协议(FTP)即使用流式套接字。 数据报式套接字(SOCK_DGRAM) 提供一个无连接服务。 数据报以独立包形式被发送,不提供无错保证,数据可能丢失或重复,且接收顺序混乱。 网络文件系统(NFS)使用数据报式套接字。 原始式套接字(SOCK_RAW) 该接口允许对较低层协议,如 IP、ICMP 直接访问。 常用于检验新的协议实现或访问现有服务中配置的新设备。 5. 服务方式 面向连接(虚电路) 面向连接服务是电话

4、系统服务模式的抽象,每一次完整的数据传输都要经过建立连接、使用连接、终止连接的过程。 在数据传输过程中,不携带目的地址,而使用连接号(connect ID) 。 本质上,连接是一个管道,收发数据不但顺序一致,而且内容相同。TCP 协议提供面向连接的虚电路。 无连接 无连接服务是邮政系统服务的抽象,每个分组都携带完整的目的地址,各分组在系统中独立传送。 无连接服务不能保证分组的先后顺序,不进行分组出错的恢复和重传,不保证传输的可靠性。 UDP 协议提供无连接的数据报服务。 6. Winsock 寻址计算机都分配有一个 IP 地址,用一个 32 位数来表示。客户机需要通过 TCP 或 UDP 和服

5、务器通信时,必须指定服务器的 IP 地址和服务端口号。服务器打算监听接入客户机请求时,也必须指定一个 IP 地址和一个端口号。二、Winsock 通信程序设计基础1. 编写 Winsock 通信程序需要那些头文件和动态连接库? winsock2.h ,ws2_32.lib2. TCP 和 UDP 通信使用的 API 函数 socket()、bind()、listen()、accept()、send() 、recv()、sendto()、recvfrom()、closesocket()3. Connect()函数的说明 在客户端使用该函数请求建立连接时,将激活建立连接的三次握手,用来建立到服务器

6、 TCP 的连接。如果调用该函数前没有调用bind()来绑定本地地址,则由系统隐式绑定一个地址到该套接字 该函数用在 UDP 的客户端时,connect()函数并不是真正地发出建立请求连接的请求,调用将从本地操作系统直接返回。这样可以将服务器的地址信息保存下来,在后续 UDP 端口发送数据时,由套接字自动在发送函数中填入服务器地址,而不需要由应用程序在调用发送函数时填入4. 面向连接的 C/S 程序工作流程(TCP) 服务器端工作流程 使用 WSAStartup()加载 Winsock 库 使用 socket()函数创建服务器端通信套接字 使用 bind()函数将创建的套接字与服务器地址绑定

7、使用 listen()函数使服务器套接字做好接收连接请求准备 使用 accept()接收来自客户端由 connect()函数发出的连接请求 根据连接请求建立连接后,使用 send()函数发送数据,或者使用 recv()函数接收数据 使用 closesocket()函数关闭套接字(可以先用 shutdown()函数先关闭读写通道) 最后调用 WSACleanup()函数释放 Winsock 库 客户端程序工作流程 使用 WSAStartup()函数加载 Winsock 库 使用 socket()函数创建客户端套接字 使用 connect()函数发出向服务器建立连接的请求(调用前可以不用 bind

8、()端口号,由系统自动完成) 连接建立后使用 send()函数发送数据,或使用 recv()函数接收数据 使用 closesocet()函数关闭套接字 最后调用 WSACleanup()函数释放 Winsock 库5. 无连接的 C/S 程序工作流程(UDP)6. 无连接的数据报传输服务通信时,客户端与服务器端所使用的函数是类似的,其工作流程如下: 使用 WSAStartup()函数加载 Winsock 库 使用 socket()函数创建套接字,以确定协议类型 调用 bind()函数将创建的套接字与本地地址绑定,确定本地地址和本地端口号 使用 sendto()函数发送数据,或者使用 recvf

9、rom()函数接收数据 使用 closesocket()函数关闭套接字 调用 WSACleanup()函数释放 Winsock 库7. UDP 通信程序如何获取对方的地址信息? 在发送的时候若是广播的话是不会有对方 IP 地址的,一般用 send 进行发送,若是定点发送的话是可以将对方 IP 地址确定的8. UDP 通信程序是不是一定要绑定套接字到本地地址?不一定9. UDP 通信程序是否可以调用 connect()? 如果没有预先绑定地址和端口,要先发送数据之后,才能确定己方 UDP 采用的地址和端口,因为地址和端口是第一次发送数据时分配的。如果不想通过发送数据来 确定地址和端口,可以调用

10、connect 函数,不过这样以后该 SOCKET 只能跟 connect 函数中指定的端口和地址通信了。三、Winsock 程序设计进阶1. 套接字模式 Winsock 提供了两种套接字模式:阻塞和非阻塞模。 Windows 平台支持套接字以两种工作。 在阻塞模式下,在 I/O 操作完成前,执行操作的 Winsock 函数会一直等候下去,不会立即返回。 非阻塞模式下, Winsock 函数会立即返回。1.1 阻塞模式 在一个阻塞套接字上调用任何一个 Winsock API 函数,都会产生相同的后果“等待” 。 大多数 Winsock 应用都是遵照一种“生产者消费者”模型来编制的。在这种模型中

11、,应用程序需要读取(或写入)指定数量的数据,然后以它为基础执行一些计算。为了防止由于数据的缺乏造成应用程序完全陷于“凝固”状态,同时不必连续性地检查系统网络缓冲。可采用如下方法 将应用程序划分为一个读线程,以及一个计算线程,两个线程都共享同一个数据缓冲区。对这个缓冲区的访问需要受到一定的限制,用同步对象来控制访问,比如 Mutex。 读线程从网络连续地读入数据,并将其置入共享缓冲区内。读线程取得计算线程开始工作至少需要的数据量后,便触发一个事件,通知计算线程。 随后,计算线程从缓冲区取走(删除)一个数据块,然后进行计算。1.2 非阻塞模式 非阻塞模式套接字除具备阻塞套接字已有的各项优点之外,还

12、进行了少许扩充,功能更强。 套接字工作在非阻塞模式时, Winsock API 调用会立即返回。大多数情况下,这些调用都会“失败” ,并返回一个WSAEWOULDBLOCK 错误。 设置非阻塞套接字1.3 阻塞与非阻塞通信小结 通信包括阻塞和非阻塞两种模式。对于不同的协议,阻塞通信和非阻塞通信有不同的表现。 对于 UDP 协议,由于 UDP 没有发送缓存,因此所有 UDP 协议即使在阻塞模式下也不会发生阻塞。 对于面向连接的协议,连接建立阶段,阻塞与非阻塞也表现不一。在阻塞模式下,如果没有连接请求到达,则等待连接调用将阻塞直到有连接请求到达;但在非阻塞模式下,如果没有连接请求到达,等待连接调用

13、将直接返回。 在连接建立阶段,不管是阻塞模式还是非阻塞模式,发起连接请求的一方总是会使调用它的进程阻塞,阻塞间隔最少等于到达服务器的一次往返时间。 通信模式对应用程序的设计方法也有直接的影响。在非阻塞模式下,应用程序必须不断地轮询是否有数据到达或有连接请求到达。 这种轮询的方式耗费的 CPU 资源较大,要尽可能避免使用,而在阻塞模式下则不存在这一问题,但其缺点是进程或线程在执行 I/O操作时将被阻塞而不能执行其他的工作,因此在单进程或单线程应用中不能使用这种模式。 在多线程应用中比较适合采用阻塞模式,一个线程被阻塞不影响其他线程的工作。 2. 套接字 I/O 模型 Select 模型,WSAA

14、synSelect 模型,WSAEventSelect 模型,重叠模型,完成端口模型。Select 模型 Select 模型是 WinSock 中最常见的 I/O 模型。 通过调用 Select 函数可以确定一个或多个套接字的状态,判断套接字上是否存在数据,或者能否向一个套接字写入数据。 既能防止应用程序在套接字处于阻塞模式时,在一次 I/O 操作后被阻塞,同时也能防止在套接字处于非阻塞模式时,产生WSAEWOULDBLOCK 错误。使用 select 模型的编程步骤: 建立 fd_set 集合 s,用来存放欲使用的套接字。 将套接字添加到集合 s 中。 确定要检查的套接字集合 Xi(1= 0

15、)HandleData(buff);/HandleData()为数据处理函数/ 关闭套接字closesocket(s);return 0;2、请解释 int listen(SOCKET sockfd,int backlog)中 backlog 的具体含义。指定了正在等待连接的最大队列长度,它的作用在于处理可能同时出现的几个连接请求。3、调用 connect()时触发什么过程?三次握手过程4、UDP 编程时可否使用 connect() ,为什么?可以使用。因为 UDP 的客户端调用 connect()函数时,并不是真正地发出建立请求连接的请求,调用将从本地操作系直接返回。这样可以将服务器的地址信

16、息保存下来,在后续 UDP 端口发送数据时,由套接字自动在发送函数中填入服务器地址,而不需要由应用程序在调用发送函数时填入。5、recvfrom()填入的地址的作用是什么?用于返回发送方的地址(IP、PORT),如果不关心发送方地址时可设置地址参数为 NULL;如果需要回复信息则要填入参数以便 sendto 时使用。6、调用 recvfrom()之前是否必须绑定?为什么?不一定必须绑定。若在调用 recvfrom()之前没有调用 sendto()就必须调用 bind()显式绑定;若在调用 recvfrom()之前调用了 sendto()则由系统自动绑定,不必显式绑定。从以下方面比较 WSAAs

17、yncSelect 模型和 WSAEventSelect 模型的异同。 能处理的网络事件类型相同,常用网络事件包括 FD_ACCEPT、FD_READ 、FD_WRITE、FD_CLOSE 得到网络事件通知的途径不同。WSAAsyncSelect 模型由操作系统捕获网络事件并封装成 WINDWOS 消息,发送到窗口程序的消息队列中,应用程序从其消息队列中取出消息从而获得网络事件通知;而 WSAEventSelect 模型是通过等待关联的事件状态变化来获取事件通知。 单线程能处理的套接字个数不同,WSAEventSelect 模型为 64, WSAAsyncSelect 模型没有限制。 判断网络

18、事件类型和网络错误方法不同。WSAEventSelect 模型通过调用 WSAEnumNetworkEvents()函数传入的指向 WSANETWORKEVENTS 结构体的指针 lpNetworkEvents 来返回网络网络事件和错误代码。if(lpNetworkEvents- lNetworkEvents 参数 readfds 指向要做读检测的套接字描述符集合的指针,调用者希望从中读取数据;参数writefds 指向要做写检测的套接字描述符集合的指针;参数 exceptfds 指向要检测是否出错的套接字描述符集合的指针;(31)WinSock 提供了 4 个宏对 fd_set 结构进行操作

19、,分别是:* FD_CLR(s, *set):从集合 set 中删除描述字 s。* FD_ISSET(s, *set):若 s 为集合中一员,则非零,否则为零。* FD_SET(s, *set):向集合添加描述字。* FD_ZERO(s, *set):将 set 初始化为空集 NULL。(32)WSAAsyncSelect 模型是 WinSock 中另一个常用的异步 I/O 模型。利用这个模型可在一个套接字上接收以 Windows 消息 为基础的网络事件通知。(33)若无错误发生,WSAEnumProtocols()返回协议的数目,否则返回 INVALID_SOCKET 错误,应用程序可通过

20、WSAGetLastError()来获取相应的错误代码。(34)WinSock 2 引入了重叠 I/O 的概念并且要求所有的传输协议提供者都支持这一功能。它的基本原理是让应用程序使用一个重叠的数据结构,一次投递一个或多个 WinSock I/O 请求,针对那些提交的请求,在它们完成之后,应用程序可为它们提供服务。应用程序可通过 ReadFile 和 WriteFile 两个函数执行 I/O 操作。(35)当应用程序使用 setsockopt 函数把接收缓冲区长度设置为 0 时,对可靠传输协议,数据直到应用程序提供了接收缓冲区后才被接收,而对不可靠传输协议,数据将会丢失。 (36)WinSock

21、 2 中 QoS 的使用模型如下: (1) 对基于连接的传输服务,应用程序可以很方便地在使用 WSAConnect 函数提出连接请求时规定它所要求的服务质量(QoS)。(2) 无连接的套接字也可以使用 WSAConnect 函数为一个指定的通信规定特定的 QoS 级别,WSAIoctl 函数也可用来规定初始的 QoS要求,或者用于今后的 QoS 协商。(37)套接字具有很多套接字选项,这些选项代表套接字在不同需要下的行为,通过 setsockopt 函数和 getsockopt 函数可以灵活地设置和获取某个套接字的行为方式。(38)调用 setsockopt 和 getsockopt 函数时,

22、最常见的错误是试图获得一个套接字的信息,但那个套接字的基层协议却不具备某种指定的特性(或选项) 。4(1)函数 int gethostname(char *name, int namelen); 参数 name 是一个指向将要存放主机名的缓冲区指针。namelen 用于指定缓冲区的长度 。该函数把本地主机名存入由 name 参数指定的缓冲区中,返回的主机名是一个以 NULL 结束的字符串。主机名的形式取决于 WinSock 实现,它可能是一个简单的主机名,或者是一个域名。然而,返回的名字必定可以在 gethostbyname()和WSAAsyncGetHostByName()中使用。如果没有错

23、误发生, gethostname()返回 0;否则它返回SOCKET_ERROR。 (2)函数 struct hostent *gethostbyname(const char *name);中 name 为指向主机名的指针,它一般由函数 gethostname 返回。函数返回对应于给定主机名的包含主机名字和地址信息的 hostent 结构指针,该结构格式如下: struct hostentchar FAR* h_name;char FAR FAR* h_aliases;short h_addrtype;short h_length;char FAR FAR* h_addr_list; 其中:

24、字段 h_name 为正规的主机名;字段 h_aliases 是一个以空指针结尾的可选主机名队列;字段 h_addrtype 返回地址的类型,对 WinSock 这个域总是 AF_INET;字段 h_length 为每个地址的长度(字节数 ),对应于 AF_INET 这个域应该为 4;字段 h_addr_list 为以空指针结尾的主机地址的列表,返回的地址是以网络顺序排列的。(3)函数 GetAdaptersInfo 可以获得本地计算机的网络信息,从而获得该计算机的网卡名、网卡驱动程序、IP 地址、子网掩码、物理地址、是否启用了 DHCP、是否启用了 WINS 等网络信息。注意该函数在头文件

25、IpHlpApi.h 中声明,库文件为 IpHlpApi.lib。(4)函数 DWORD GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen); 其中:参数 pAdapterInfo 指向 IP_ADAPTER_INFO 结构链表缓冲区的指针;参数 pOutBufLen 指向一个 ULONG 变量的指针,该 ULONG 变量表示指向 pAdapterInfo 结构的大小。 参数中的 IP_ADAPTER_INFO 结构包含了本地计算机上一个特定网络适配卡的信息。(5)针对指定的工作站上安装哪种协议和各种协议特性的返回

26、问题,WinSock 2 提供了一种解决方法。如果一个协议支持多种行为,则每类行为在系统中都有各自的目录条目。比如,如果在自己的系统中安装了 TCP/IP,系统中就会有两个 IP 条目:一个条目针对 TCP,是可靠的面向连接的,另一个针对 IP,是不可靠且无连接的。 (6)要想获得系统中安装的网络协议的相关信息,可调用 WSAENumProtocols 函数,其原型为:int WSAENumProtocols( LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer,LPDWORD lpdwBufferLength );其中:参数 lpi

27、Protocols 是一个以 NULL 结尾的协议标识号数组,该参数可选,如果 lpiProtocols 为NULL,则返回所有可用协议的信息,否则返回数组中所列的协议信息;参数 lpProtocolBuffer 是一个用 PROTOCOL_INFO 结构填充的缓冲区,该结构用来存取和获得给定协议的完整信息;参数 lpdwBufferLength 在输入时,用于保存传递给 WSAENumProtocols()函数的lpProtocolBuffer 缓冲区长度;在输出时,存有获取所有请求信息需传递给 WSAENumProtocols()函数的最小缓冲区长度。若无错误发生,WSAENumProto

28、cols 函数返回协议的数目,否则,返回 INVALID_SOCKET错误,应用程序可通过 WSAGetLastError()函数来获取相应的错误代码。 (7)通常需要两次调用 WSAENumProtocols 函数以获取特定的协议信息,第一次调用时指定lpProtocolBuffer 为 NULL,调用失败,返回 WSAENOBUFS 错误,但参数 lpdwBufferLength 包含了所有协议信息需要的缓冲区长度。分配了恰当的缓冲区长度后,便可利用这个缓冲区进行第二次调用,协议的信息将包含在 WSAPROTOCOL_INFO 结构中。这样就可以对该结构进行分析从而获得所需要的协议信息。

29、(8)应用程序在使用套接字前,首先必须拥有一个套接字,系统调用 socket()向应用程序提供创建套接字的手段,其调用格式如下:SOCKET PASCAL FAR socket(int af, int type,int protocol);该调用要接收三个参数:aftype,protocol。参数 af 指定通信发生的区域,DOS 和 Windows仅支持 AF_INET,它是网际网区域,因此,地址族与协议族相同。参数 type 描述要建立的套接字的类型。参数 protocol 说明该套接字使用的特定协议如果调用者不希望持别指定使用的协议,则置为 o,使用默认的连接模式。根据这三个参数建立一个

30、套接字,并将相应的资源分配给它,同时返回一个整型套接字号。因此,socket()系统调用实际上指定了相关五元组中的 “协议”这一元。(9)bind()将套接字地址( 包括本地主机地址和本地端口地址 )与所创建的套接字号联系起来即将名字赋予套接字,以指定本地半相关。(10)int PASCAL FAR bind(SOCKBT s,const struct sockaddr FAR *name,int namelen); 参数 s 是由 socket()调用返回的并且末作连接的套接字描述符( 套接字号)。参数 name 是赋给套接字 s 的本地地址(名字),其长度可变,结构随通信域的不同而不同。

31、namelen 表明了 name 的长度。如果没有错误发生,bind()返回 o;否则返回值 SOCKETERROR。(11)socket() bind() connect() listen() accept()这五个套接字系统调用,可以完成一个完全五元相关的建立。(12)Windows Sockets 的套接字函数包括 sockets()bind()getpeername() getsockname()和closesocket()。它们主要完成创建、关闭套接字功能以及对套接字命名和名字获取。网络连接函数,此类函数包括 listen(),accept(),connect()和 shutdown

32、()。它们完成网络连接( 如虚电路) 的建立与关闭。此类函数中有部分可阻塞。数据传输函数,此类函数包括 send(),recv() ,sendto()和 recvfrom()。它们完成网络数据的发送与接收,全部是可以阻塞的函数。字节定序函数,此类函数包括 htonl(),htons(),ntohl()和 ntohs()。它们完成主机和网络之间数据字节顺序的转换。地址转换函数,此类函数包括 inet_addr(),inet_ntoa(),它们完成网络字符串地址和 Internet 地址之间的转换。套接字控制函数,此类函数包括 getsockopt(),setsockopt(),ioctsocke

33、t()和 select(),它们设置获取套接字的选项,控制检测套接字的工作状态。其中 se1ect()函数在必要时可能阻塞。(13)在非抢先 windows 环境,强烈推荐程序员使用非阻塞( 异步)操作,也就是说,推荐使用windows Sockets 提供的异步选择函数代替可能阻塞的 selct()函数,并且用网络事件消息来驱动可能阻塞的网络连接函数(accept() 和 connect()和数据传输函数,这样设计的程序能更好地工作。5(1)原始套接字可以对底层的传输协议加以控制,对 IP 头信息进行实际的操作,通过它可以模拟一些 IP 的实用工具,如 Tracert 和 Ping 等。原始

34、套接字 (raw socket)是使用 SOCK_RAW 这个套接字类型来创建的。(2)Ping 示例在程序中采取如下步骤:(1) 创建类型为 SOCK_RAW 的一个套接字,同时设定协议 IPPROTO_ICMP。(2) 创建并初始化 ICMP 头。(3) 调用 sendto 或 WSASendto,将 ICMP 请求发给远程主机。(4) 调用 recvfrom 或 WSARecvfrom,以接收任何 ICMP 响应。 (3)ICMP 和 ICMPv6(基于 IPv6 的 ICMP)的 echo 请求的唯一差别是计算 ICMP 头中的校验和。(4)在 IPv4 中,校验和仅简单地针对 ICMP 头和负载,但在 IPv6 中,因校验和应包括 IPv6 伪头、ICMPv6 头和负载进行处理而较为复杂。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报