2024年6月12日发(作者:)

《Windows网络编程基础教程》(第2版)习题及参考答案

第 1 章 习题

1. 选择题

(1) 答案:D

(2) 答案:C

(3) 答案:B

(4) 答案:C

(5) 答案:D

(6) 答案:B

(7) 答案:B

(8) 答案:D

(9) 答案:B

(10) 答案:B

(11) 答案:C

2. 填空题

(1) 答案:广播、单播

(2) 答案:路由器

(3) 答案:FF-FF-FF-FF-FF-FF

(4) 答案:目的计算机、广播地址

(5) 答案:路255.255.255.255、 0.0.0.0

(6) 答案:目的端口号

(7) 答案:操作系统通信

(8) 答案:路操作系统的核心、函数库

(9) 答案:流式套接字、数据报套接字

3. 简答题

(1) 什么是网络协议?说出协议的三要素及它们的含义。

答: 网络协议,就是指通信双方在通信时所必须遵循的用于控制数据传输的规则、标准和约

定,是通信双方所使用的“语言”,它规定了有关功能部件在通信过程中的操作,定义了数据

发送和数据接收的过程。

网络协议包括三方面内容。一是“语法”,主要是指数据以及控制信息的结构或格式;第

二方面内容是“语义”,它是指对构成协议的协议元素含义的具体解释;第三方面是“同步”,

同步也称为“时序”,它规定了通信过程中各种事件的先后顺序。

(2) 画出以太网帧结构示意图,并简要叙述以太网帧中各字段的含义。

答:以太网帧结构如下图所示:

6B

6B

2B

46 ~ 1500 B4B

目的地址 源地址 类型 数据字段 校验码

其中,目的地址,指明要接收该帧的计算机的MAC地址。如果是一个广播帧,即该帧是

广播给网络中的所有计算机的,目的地址应指明为广播地址。

源地址字段,用于指明发送该帧的计算机的MAC地址。通过源地址,收到该帧的计算机

1

《Windows网络编程基础教程》(第2版)习题及参考答案

就会知道是哪台计算机发送了该帧。

类型字段主要用于指明接收端对数据部分的处理方式,也就是说,接收端收到数据后,如

果经过检验没发现错误,帧中的数据应该交给哪个程序处理。

数据字段,也被称为用户数据,是网络真正要传送的内容,长度在46~1500个字节之间。

校验码是接收方用来检查数据在传输过程中是否出错的,也称为帧校验序列(FCS),由

发送方根据帧的其他部分的内容使用某种算法计算得到。

(3) 简述ISO的OSI/RM网路体系结构模型各层的功能。

答:OSI/RM模型将计算机网络按功能分为七个层次,从下到上依次为物理层、数据链路层、

网络层、传输层、会话层、表示层和应用层。

物理层的主要功能是,利用通信介质为需要直接通信的节点之间建立、维护和释放物理连

接,实现二进制比特流的传输,进而为其上的数据链路层提供数据传输服务。

数据链路层的主要功能是在物理层提供的比特流传输服务基础上,以帧为单位,实现无差

错数据传输,简单一点说就是在数据链路两端实现无差错数据传输。

网络层的功能是,在链路层提供的服务基础之上,通过中间节点的数据转发,实现任意两

台计算机间的通信。网络层以“分组”(packet)为数据传输单位,通过适当的路由选择,可

以为网络上的任意两台计算机之间提供通信服务,并能实现拥塞控制和网络互联。

传输层直接为应用进程提供通信服务,传输层提供的这种“应用进程到应用进程”的数据

传输服务通常被称为端到端(end-to-end)通信服务。传输层为多个应用进程共用网络通信服

务提供了支撑。除此之外,传输层还可以在网络层提供的不可靠的数据报服务之上,通过采用

可靠传输协议为应用进程提供可靠的数据通信服务。

会话层组织两个会话进程之间的通信,管理数据的交换。

表示层用于处理在两个通信系统中交换信息的表示方式,包括数据格式变换、数据加密与

解密、数据压缩与恢复等。

应用层是体系结构中的最高层,其主要任务是通过网络应用进程间的通信来实现特定的网

络应用,该层定义应用的总体框架以及进程间通信和交互的具体规则。

(4) 简述路由器在收到一个IP分组后的处理过程。

答:①从收到的分组的首部提取目的 IP 地址 D。

① 对与路由器直接相连的子网(下一跳地址为“直接交付”的那些表项对应的网络),

先用各网络的子网掩码和D逐位相“与”,看是否和相应的网络地址匹配。若匹配,则将分组

直接交付。否则执行步骤①。

③ 若路由表中有目的地址为 D 的特定主机路由,则将分组传送给指明的下一跳路由器;

否则,执行步骤④。

④ 对路由表中的其余的每一表项的子网掩码和 D 逐位相“与”,若其结果与某一项的目

的网络地址匹配,则将分组传送给该项指明的下一跳路由器,若结果与多项都匹配,则选子网

掩码最大的路由表项作为该分组的路由;若无匹配项,则执行步骤⑤。

⑤ 通过ICMP协议,向源主机报告转发分组出错。

(5) 传输层协议如何区分同一主机上的不同应用进程?

答:通过引入端口号来区分不同应用进程。同一机器上的每个应用进程都被分配有一个端口号,

发送方发送数据时,需要在报文首部填上目的进程的端口号,目的机器收到报文后,就可以根

据报文中的目的端口号将数据交给目的进程。

(6) 如何表示网络环境中的进程地址?

答:(IP地址、传输层协议、端口号)

(7) 网络应用程序的结构模型主要有哪些?

2

《Windows网络编程基础教程》(第2版)习题及参考答案

答:C/S模型、B/S模型、P2P模型。

(8) 图1.20是从网上捕获的一个以太帧的80字节数据(16进制表示)。第一列为每行数据第一字

节的序号(从0开始,也是16进制表示的)。

图1.20捕获的某以太网帧的前128字节数据

对照图1.2和图1.11完成以下各题:

①写出该帧的目的MAC地址和源MAC地址。

②已知以太网帧的类型字段值为0800时,其数据部分为一个IP分组,由图1.20可以看到,

捕获的该帧中的数据部分确实为一个IP分组。请回答:该IP分组的源IP地址和目的IP地址格式

多少?用点分十进制表示。

③已知IP分组首部中,协议字段的值为1时,对应的数据部分是ICMP报文;协议字段的值为

2时,对应的数据部分是IGMP报文;协议字段的值为6时,对应的数据部分是TCP报文段;协议字

段的值为17时,对应的数据部分是UDP数据报。请根据图1.20所给数据回答,该IP分组的数据

部分是ICMP报文、TCP报文段、UDP数据报还是其他?

答:①目的MAC地址 00-21-27-21-51-ee 源MAC地址 00-15-c5-c1-5e-28

②源IP地址为:0a 02 80 64 点分十进制表示为:10.2.128.100

目的IP地址为:40 aa 62 20 点分十进制表示为:64.176.98.32

③因为该分组的IP协议字段值为 06 ,所以其数据部分是TCP报文段。

3

《Windows网络编程基础教程》(第2版)习题及参考答案

第 2 章 习题

1. 选择题

(1) 答案: C

(2) 答案: D

(3) 答案: C

(4) 答案: D

(5) 答案: D

(6) 答案: C

(7) 答案: B

(8) 答案: B

(9) 答案: D

(10) 答案: A

(11) 答案: B

(12) 答案: A

2. 填空题

(1) 答案: 窗口句柄

(2) 答案: Hello,C++

(3) 答案: UNICODE转换格式(UTF)

(4) 答案: AddString()、ResetConten()

(5) 答案:属性、CreateWindow() 函数

(6) 答案: 变量映射 、 控件类别 、 值类别

3. 简答题

(1) 在对话框窗口属性中Caption属性、Font属性以及Border属性各起什么作用?编写对话框应用

程序时,如何让程序的主对话框窗口不显示右上角的最大化和最小化按钮?

答:①Caption属性的值是对话框窗口标题栏显示的文字;Font属性用于设置对话框窗口中控

件上显示的文字的字体、字形和字号;Border属性用于确定窗口的边框类型。

①若要对话框窗口不显示右上角的最大化和最小化按钮,应将Minimize box和Maximize box

这两个属性值均设为False,均设置为true则是显示最大化和最小化按钮。

(2) 请列举出ListBox控件的常用属性并说明其作用,要求不少于三个。如何向ListBox空间中添

加一个字符串?如何将一个单选ListBox控件中选中的列表项内容保存到一个CString对象

中?

答:①Selection属性,该属性有4个选项:Single,表示在给定的选项中,至多有一个被选中,

此时列表框为单选列表框;Multiple,表示可以有多个选项被选中,但忽略Shift键和Ctrl键;

Extended,允许选择多个选项,在选择时可以使用Shift键和Ctrl键;None,不允许选择任何

选项。

Sort属性用于设置列表框内容应是否按字母顺序排序,缺省为True,表示列表内容按字母

顺序自动排序。

4

《Windows网络编程基础教程》(第2版)习题及参考答案

Multi-column属性指定是否创建一个多列列表框,缺省值为False,即创建单列列表框。

① 调用AddString()方法可向ListBox空间中添加一个字符串。

① 设m_List是一个列表框控件变量,使用如下代码可将列表框中选中的列表项的内容保存到

字符串对象str中:

CString str;

int i,n;

n=m_nt();

for(i=0;i

if(m_(i)>0)break;

m_t(i,str);

(3) 什么是 DDX 机制?对编辑框控件(Edit Control),除使用DDX实现变量与控件的数据交换

外,能否调用其方法来实现数据交换?如果能的话,应该使用编辑框控件的哪两个方法?

答:①通过某个控件输入的数据可以保存到对话框类的某个成员变量中,反过来,对话框类的

某个成员变量的值也可以在对话框的某个控件上显示,这就是所谓控件与变量的数据交换,简

称DDX。控件与变量的数据交换是通过使用基于ID的变量映射来实现的。所谓变量映射,就

是利用“类向导”,将一个对话框类的成员变量通过控件的ID和控件进行关联(映射)。与

控件关联的变量通常都被称为“控件变量”。

①能。

①可使用成员函数SetWindowText()和GetWindowText()来改变或获取编辑框控件上的文

字。

(4) 当单击一个命令按钮时,系统会发送BN_CLICKED消息给窗口,窗口收到该消息后就调用相

应的消息处理函数来响应这一事件。消息处理函数是由编程者编写的一个窗口类的成员函数。

请问:消息是如何同消息处理函数关联起来的?

答:消息是通过“消息映射’同消息处理函数关联起来的,实现消息映射的代码在添加消息处

理函数时由“类向导”自动添加。

(5) 在使用VC++编写图形界面的Windows应用程序时,MessageBox函数十分有用,请查阅资料,

给出该函数的功能、使用格式以及各参数的取值类型及相应含义。

答:执行MessageBox()函数将显示一个模态对话框,该对话框一般包括一个系统图标、 一组

按钮和一个简短的文字信息。函数返回一个整数值,该值代表用户单击了哪个按钮。

函数原型:

int MessageBox(LPCTSTR lpszText,LPCTSTR lpszCaption=NULL, UINT nType = MB_OK);

参数

lpszText:指向一个字符串,该字符串是要显示的消息。

lpszCaption:指向一个字符串,该字符串是弹出窗口的标题。

nType:指定消息框的类型,其取值如下表所示。

参数取值

MB_OK

MB_YESNO

MB_ABORTRETRYIGNORE

MB_YESNOCANCEL

MB_RETRYCANCEL

MB_OKCANCEL

含义

默认值。有一个确认按钮在里面。

有是和否在里面。

有Abort(放弃),Retry(重试)和Ignore(跳过)

消息框含有三个按钮:Yes,No和Cancel

有Retry(重试)和Cancel(取消)

消息框含有两个按钮:OK和Cancel

返回值:是一个整数,代表用户单击了哪个按钮,具体如下表所示:

5

《Windows网络编程基础教程》(第2版)习题及参考答案

返回值

1

2

3

4

5

6

7

IDOK

IDCANCEL

IDABORT

IDRETRY

IDIGNORE

IDYES

IDNO

对应符号常量

OK

CANCEL

ABORT

RETRY

IGNORE

YES

NO

选择的按钮

4. 编程题

(1) 提示:将编辑框中的字符串转换成double 型,需要使用函数atof(),在使用MFC编程时

可使用_tftof()代替。

(2) 提示:需要修改控件的ID才能给静态文本控件和图片控件(Picture Control)定义控件

变量。可调用图片控件的SetBitmap()方法显示位图,但使用该方法必须事先调用LoadImage()函

数将位图加载到内存。另,图片控件只能显示位图,因此要显示的照片文件应为位图格式(bmp)。

(3) 提示:可增加一个布尔变量changed标记编辑框中的内容是否改变,该变量初始化为

false,编辑框内容一旦发生变化则设为true,内容保存后变量值恢复为false,退出时检查该变

量值,根据该变量值完成相应操作。

程序代码参见:《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

6

《Windows网络编程基础教程》(第2版)习题及参考答案

第 3 章 习题

1. 选择题

(1) 答案: B

(2) 答案: D

(3) 答案: A

(4) 答案: B

(5) 答案: B

(6) 答案: C

(7) 答案: A

(8) 答案: A

(9) 答案: D

(10) 答案: D

2. 填空题

(1) 答案: BSD UNIX

(2) 答案: WSA

(3) 答案: #pragma comment(lib,"Ws2_")

(4) 答案:WSACleanup()

(5) 答案: 32位的无符号长整型数

答案:网络字节顺序的无符号长整型IP地址

(6) 答案: 错误代码

(7) 答案:解析DNS域名“”的IP地址、struct addrinfo hints, *p_addrinfo;

getaddrinfo(“”, NULL, &hints, &p_addrinfo);

(8) 答案:192.168.2.26

(9) 答案:将IP地址192.168.1.1转换网络字节顺序的无符号长整型存入变量a、 in_addr

3. 简答题

(1) 如果系统支持WinSock2,编程时能否使用头文件Winsock.h和导入库? 为什么?

答:可以。因为WinSock2完全兼容WinSock1,因此,当系统中安装的是WinSock2时,程序

中既可以使用WinSock1的头文件和导入库,也可以使用WinSock2的头文件和导入库。

(2) 将WinSock导入库链接到应用程序有哪两种方式?如何操作?

答: 一种是通过在项目属性页中的“配置属性链接器输入”的“附加依赖项”中直接添加导

入库名字;另一种则是在程序使用预处理命令“#pragma comment”。例如,程序要使用WinSock2

时,可使用如下预处理命令:

#pragma comment (lib, "Ws2_")

(3) sockaddr_in结构与sockaddr结构有何异同?当使用TCP/IP协议时,如何为sockaddr结构变量

赋值?举例说明。

答:sockaddr结构为通用套接字地址结构,当使用TCP/IP时,该结构内容与sockaddr_in完全

相同。在为sockaddr结构的变量赋值时,可先利用C/C++语言的强制类型转换将该结构变量的

地址赋给一个sockaddr_in类型的指针,然后通过该指针将各项内容填入结构体变量中。例如,

7

《Windows网络编程基础教程》(第2版)习题及参考答案

可首先定义一个sockaddr_in结构类型的指针变量p,通过强制类型转换让p指向sockaddr结构

类型的变量,然后通过指针p可按sockaddr_in类型的各字段完成赋值。例如:

struct sockaddr a;

struct sockaddr_in *p;

p=(sockaddr_in *) &a;

p->sin_family=AF_INET;

p->sin_port=54321;

p->sin_addr=inet_addr("192.168.1.1");

(4) 由于网络原因,调试程序时发送数据总是不能成功,问采用何种方法可找出发送数据不能成功

的具体原因?

答:可调用WSAGetLastError()函数获取发送数据出错的错误代码,然后根据错误代码获知具

体原因。

(5) 什么是网络字节顺序?当网络通信程序在发送整数时为什么应该使用网络字节顺序?

答:计算机在存储多字节数据时存在大端字节顺序(Big Endian)和小端字节顺序(Little Endian)

两种方式,当不同字节顺序的计算机在通过网络交换数据时,如果不作任何处理,将会出现严

重问题。因此在编写网络程序时,规定发送端要发送的多字节数据必须先转换成与具体CPU

无关的网络字节顺序再发送,接收端接收到数据后再将数据转换为主机字节数据。网络字节顺

序采用的是大端存储方式。

4. 编程题

答案参见:《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

8

《Windows网络编程基础教程》(第2版)习题及参考答案

第 4 章 习题

1. 选择题

(1) 答案: C

(2) 答案: D

(3) 答案: A

(4) 答案: D

(5) 答案: C

(6) 答案: D

(7) 答案: A

(8) 答案: B

(9) 答案: B

(10) 答案: D

(11) 答案: A

(12) 答案: D

2. 填空题

(1) 答案:

创建一个流式套接字

(2) 答案:

等待连接请求队列最大长度为 4

(3) 答案:

也与

监听

套接字相同

(4) 答案:

setsockopt()

(5) 答案:INVALID_SOCKET

(6) 答案:SOCKET_ERROR

(7) 答案:阻塞

(8) 答案:

客户端地址

(9) 答案:

实际收到的字节数

3. 编程题

答案参见:《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

9

《Windows网络编程基础教程》(第2版)习题及参考答案

第 5 章 习题

1. 选择题

(1) 答案: C

(2) 答案: A

(3) 答案: C

(4) 答案: C

(5) 答案: D

(6) 答案: D

(7) 答案: B

(8) 答案: A

(9) 答案:B

(10) 答案: B

2. 填空题

(1) 答案: 进程

(2) 答案:就绪状态、运行状态、阻塞状态

(3) 答案:运行、阻塞(挂起)

(4) 答案:主线程

(5) 答案:实参

(6) 答案:并发

3. 简答题

(1) 实现线程间的通信有几种方法?

答:可用全局变量、事件对象以及自定义消息等方法实现线程间的通信。

(2) 什么是事件对象?程序中要用事件对象实现线程间的通信需要那几个步骤?

答:事件对象是Windows系统内核维护的一种数据结构,由于是内核维护的,因此只能被内

核访问,应用程序无法在内存中直接找到并改变其内容。事件对象有两种工作状态:一种“有

信号”(signaled)状态;另一种是“无信号” (nonsignaled)状态。当与事件对象关联的事

件发生时,事件对象会从“无信号”状态变成“有信号”状态。

事件对象在多线程编程中常用于线程间的通信和线程的同步。事件对象可用于线程间简单

的消息传递。具体步骤为:

①创建全局事件对象并将其设为无信号状态;

①要发送消息的线程在需要发送信号的地方调用SetEvent()函数或ResetEvent()来将事件对

象设置为“有信号”状态。

①要接收消息的线程在需要接收消息的地方调用WaitForSingleObject()函数或

WaitForMultipleObject()捕捉事件的“有信号”状态,捕捉到该状态,就说明所需的消息收到。

(3) 什么是线程的互斥?有哪些方法可实现线程间的互斥?

答:①线程互斥是指,当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线

程去使用,其他要使用该资源的线程必须等待,直到占用资源者释放该资源。

①实现互斥访问的方法有多种,比较典型的有使用临界区对象(CcriticalSection)、使用互

10

《Windows网络编程基础教程》(第2版)习题及参考答案

斥对象(Mutex)和使用信号量。下面以使用互斥对象为例,了解实现线程互斥的具体方法。

(4) 线程间的同步是指什么?实现同步的方法有哪些?

答: 线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另外一个或多个线

程的消息,当它没有得到这些线程的消息时应等待,直到消息到达时才被唤醒。同步可以理解

为这样一种情况,若干个线程各自对自己的数据进行处理,然后在某个点必须汇总一下数据,

否则不能进行下一步的工作。也可以理解为这样一种情况:若干线程等待某个事件发生,当等

待的事件发生时,便一起开始执行。

在Windows系统中,通常使用事件对象实现同步。事件对象是最简单的同步对象,用于

一个线程在某种情况发生时唤醒另外一个线程。

4. 编程题

(1)程序主对话框上部的列表框用于显示收到的信息,下部的编辑框用于输入要发送的信息。

在接收数据时,如果数据没有到达时调用recv()函数将会引起线程阻塞,造成整个程序对用户

操作没有反应,为此采用多线程技术解决这一问题,即,创建一个单独的线程来负责接收并显示数

据。由于C++类的普通成员函数都有一个隐含的参数——this指针,因此不能作为线程函数,而在

本题中,线程函数需要访问主窗口类的成员(包括列表框的控件变量、自定义的套接字变量和网络

地址变量等成员),所以需要将线程函数定义为主对话框的友元函数,并将this指针作为参数传

递给线程函数,线程函数通过this指针可访问主窗口类的各成员。

程序编写步骤简述如下:

①设计界面:添加控件、修改控件属性并为相关控件添加控件变量,这里将“发送”按钮的

disable属性设置为true,连接建立成功后再用代码将其改为false;

①为主窗口类添加sockaddr_in、SOCKET成员变量;

①对服务器程序:在主对话框类的OnInitDialog()函数后面添加代码:包括创建套接字、绑定

地址、开始监听、创建接收数据的线程(也包括接收连接请求);

①编写各命令按钮的事件处理函数:对服务器端只有“发送”按钮和“退出”按钮,而对客户

端还有“连接”按钮,该按钮主要完成创建套接字、建立连接和启动数据接收线程等任务;

①编写用于接收数据的线程函数。

详细代码参见《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

(2) 可以实现。服务器界面上增加一个记录客户IP地址的列表,用于选择不同的通话对象;

在主窗口类中增加一个存储与各不同客户通信的已连接套接字的套接字数组。OnInitDialog()函数

中启动一个单独的线程专门用于接收连接请求,该线程每成功建立一个连接都要启动一个用于接收

数据的子线程,并将已连接套接字存入数组。

具体参见《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

(3)参见《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

11

《Windows网络编程基础教程》(第2版)习题及参考答案

第 6 章 习题

1. 选择题

(1) 答案: C

(2) 答案: B

(3) 答案: A

(4) 答案: D

(5) 答案: A、B、C

(6) 答案: A

(7) 答案: A

(8) 答案: D

(9) 答案: B

(10) 答案: C

(11) 答案: C

(12) 答案: D

2. 填空题

(1) 答案:非阻塞的

(2) 答案: Select模型 、 异步选择模型 、事件选择模型

(3) 答案: 1 、 FIONBIO

(4) 答案:FD_READ 、FD_WRITE、FD_ACCEPT

(5) 答案:0

(6) 答案:取消为套接字所有注册的网络事件

(7) 答案:正确的

(8) 答案: FD_WRITE

3. 简答题

(1) 简述WSAAsyncSelect模型和WSAEventSelect模型的主要区别及各自的优缺点。

答:WSAEventSelect模型与WSAAsyncSelect都属于异步I/O模型,二者的不同之处在于网络事

件发生时系统通知应用程序的形式不同。WSAAsyncSelect模型是基于Windows的消息机制的,

网络事件发生时系统将以消息的形式通知应用程序,并且消息必须与窗口句柄相关联,因此程序

必须要有窗口对象。而WSAEventSelect模型是以事件对象为基础的,网络事件需要与事件对象

关联,当网络事件发生时经由事件对象句柄通知应用程序,不需要窗口对象。

(2) 简述异步操作与同步操作的主要区别。

答:在同步模型中,不管 I/O事件是否发生,应用程序都会按既定流程主动试着进行I/O操作,

而且直至操作成功才会罢休,在I/O操作完成之前无法进行其他操作,因而效率较低。在异步I/O

模型中,当I/O事件发生时,系统将采用某种机制通知应用程序,应用程序只有在收到事件通知

时才调用相应的函数进行I/O操作,在收到通知前,则可执行其他操作,因而效率大大提高。

4. 编程题

(1)参见:《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

12

《Windows网络编程基础教程》(第2版)习题及参考答案

(2)由于客户界面没有输入服务器IP地址及端口号的控件,因此只能在代码中直接指定。界面上

也没有发起连接的按钮,因此将创建套接字、建立连接、为套接字注册网络事件等代码全都放在主

对话框的OnInitDialog()方法中。详细参见:《Windows网络编程基础教程》(第2版)课后习题

编程题参考代码.rar。

(3)参见:《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

13

《Windows网络编程基础教程》(第2版)习题及参考答案

第 7 章 习题

1. 选择题

(1) 答案: D

(2) 答案: A

(3) 答案: C

(4) 答案: D

(5) 答案:C

(6) 答案: B

(7) 答案: D

(8) 答案: C

(9) 答案: A

(10) 答案: A

2. 填空题

(1) 答案:创建一个数据报套接字

(2) 答案: getsockopt ()

(3) 答案:connect()

(4) 答案:客户/服务器模式

(5) 答案:数据报

(6) 答案:有限广播地址、255.255.255.255

(7) 答案:setsockopt()

(8) 答案:SO_BROADCAST

(9) 答案:广播地址

(10) 答案:INADDR_BROADCAST 、INADDR_ANY 、INADDR_ANY、INADDR_BROADCAST

3. 简答题

(1) 数据报套接字不必绑定本地地址就可以发送信息,因此接收者难以知道是谁发送的信息。这

种说法是否正确?为什么?

答:这种说法不正确。如果数据报套接字不绑定本地地址,它所用的本地IP地址及端口号会

在调用connect()函数或第一次调用sendto()发送数据时,由系统自动为数据报套接字选定,接

收端可由recvfrom()获取这些信息。

(2) 如果数据报套接字已接收到一台机器发来的数据,则该套接字将不会再接收另一台机器发来

的数据报,即使数据报的目的端口号与自己绑定的端口号一致。这种说法是否正确?为什么?

答:这种说法不正确。因为数据报套接字可以接收任何目的端口号与自己绑定端口号一致的数

据报。

(3) 在使用数据报套接字通信的程序中,假设服务器程序向客户程序连续发送了3个数据长度分

别为500B、1000B、1500B的数据报,设置客户端的应用程序接收缓冲区的大小为1000字节,

连续调用3次recvfrom()函数,请问能否正确收到这3个数据报?编写程序验证一下,并解

释为什么?

答:前两个可以正确收到,最后一个只能收到前1000字节,且recvfrom()函数返回

14

《Windows网络编程基础教程》(第2版)习题及参考答案

SOCKET_ERROR。因为,如果发送端发送的数据报长度如果大于recvfrom()函数指定的接收缓冲

区长度,后面的数据将会丢失,并返回SOCKET_ERROR

错误代码WSAEMSGSIZE(10040)。

4. 编程题

(1) 参见《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

(2) 服务器端(接收端)使用WSAAsycSelect模型,程序界面可设计如下:

具体实现方法参见《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

客户端(发送端)连续发送100个大小为1K的数据包,代码见《Windows网络编程基础教程》

(第2版)课后习题编程题参考代码.rar。

(3) 参见《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

15

《Windows网络编程基础教程》(第2版)习题及参考答案

第 8 章 习题

1. 选择题

(1) 答案: D

(2) 答案: C

(3) 答案: B

(4) 答案: C

(5) 答案: A

(6) 答案:A

(7) 答案:A

(8) 答案:D

2. 填空题

(1) 答案:TCP、UDP、IP

(2) 答案:管理员

(3) 答案:回送请求、回送应答

(4) 答案:IPPROTO_RAW、1

(5) 答案:IPPROTO_RAW、1

(6) 答案:混杂

3. 编程题

(1) 如果UDP目标端口号未开启,向目标主机发送一个UDP数据报,目标主机将会返回一个ICMP

端口不可达差错报文,否则什么也不反回。理论上,利用这一原理编写UDP端口扫描程序应该是

可行的,但事实上,由于UDP和ICMP都不是可靠协议,并且许多系统都对产生ICMP差错报文

的时间进行了限制,因此这种UDP端口扫描并不可靠,要想得到较为准确的结果需要多次扫描。

Widows 10对原始套接字接收ICMP报文进行了限制,不能接收TCP和UDP包产生的ICMP

差错报文,因此《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar中的参考

代码UDPScan只能在WINDOWS XP运行才有效果。

在Win10上可以利用如下方法实现端口扫描,将套接字设为非阻塞模式,先使用sendto向目

标端口发送UDP数据报,再调用recvfrom()接收数据,这时可利用该函数的错误码判断目标端口是

否打开,如果错误码为10054(WSAECONNRESET)则可断定端口未打开。详细代码参看《Windows网

络编程基础教程》(第2版)课后习题编程题参考代码.rar中的参考代码UDPScandgram项目。

(2) 参见:《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

16

《Windows网络编程基础教程》(第2版)习题及参考答案

第 9 章 习题

1. 简述使用CAsyncSocket类编写网络通信程序的步骤。

答:(1)创建基类为CAsyncSocket类的新套接字类,目的是重载CAsyncSocket类中的

OnReceive()以及OnAccept()等函数;

(2)为新建的类添加新成员,该成员为指向主对话框对象的对话框类指针pDlg;

(3)为新建的类添加重载的网络事件处理函数OnReceive()以及OnAccept()等,这些函数通过

本类的成员——(2)所添加的指向主对话框对象的对话框类指针来访问窗口类中用于连接建

立和数据收发的函数;

(4)为主窗口类添加新套接字类的对象成员,并使这些对象的pDlg指针指向本窗口;

(5)为主窗口类添加使用套接字对象进行连接建立和数据收发的成员函数。

2. 在为重载CAsyncSocket类的网络事件处理函数而定义CAsyncSocket类的派生类时,为什么通

常需要在类中添加一个对话框指针变量作为成员?

答:需要通过该指针访问窗口对象的成员。

3. 参见:《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar

4. CSocket类和CAsyncSocket类在功能上有何异同?

答:CSocket类是CAsyncSocket类的派生类,是对WindSock API函数的更进一步的封装。它

的特点主要体现在以下几个方面:

(1)与CAsyncSocket类相同,CSocket帮助完成了许多诸如字节顺序转换和字符串转换等问

题的处理,用户编程时不必再考虑;

(2)继承了CAsyncSocket类的网络事件通知接收功能和自动调用网络事件处理函数的功能,

简化了利用Windows消息驱动机制编写网络通信程序的步骤;

(3)与CAsyncSocket类不同的一点是,CSocket类提供了套接字阻塞的工作模式,当调用那

些能引起阻塞的方法时,如果不满足执行条件时,这些将会阻塞等待,一直到满足条件操作结

束才返回,而不会像CAsyncSocket类的同名方法那样立即返回并产生一个错误码为

WSAWOULDBLOCK的错误。

(4)CSocket可以结合CArchive类和CSocketFile类一起使用,大大简化了数据的收发的处理

过程,可以大大减少程序编写的复杂性。

5. 什么是对象的串行化?如何定义并实现一个可支持串行化的类?

答:对象的串行化也称为对象的持久化或序列化,是指让对象将其当前状态写入到永久性存储

体中,以便下次可以从永久性存储体中读取对象的状态,从而重建对象。对象串行化的关键是

对象本身要负责读写自己的状态。一个可串行化的对象必须能够实现基本的串行化操作。而对

象最基本的串行化操作必须借助CArchive类来实现。

一个对象可串行化的类需要按以下步骤来定义并实现:

(1)从CObject类的间接或直接派生类自己的类。

(2)定义类时,在类的说明中使用宏DECLARE_SERIAL(本类的名称),该宏有一个参数,该

参数必须是所定义的类的名字;

(3)定义一个默认构造函数(不带参数的构造函数);

(4)在类的实现之前调用宏

IMPLEMENT_SERIAL(类名,基类名, 大于等于0的任意数)

(5)重载Serialize()成员函数。

6. 参见:《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar

17

《Windows网络编程基础教程》(第2版)习题及参考答案

7. 在借助CArchive类使用串行化方法编写网络通信程序时,CSocketFile类的主要作用是什么?

答:CSocketFile类就是一个CFile类的派生类,在创建CSocketFile类的对象时要求必须关联一个

CSocket对象,而该CSocketFile类的对象又可在创建CArchive对象时通过将CFile参数指定为该

CSocketFile对象与CArchive对象关联,这样通过对象的串行化操作,对象中的数据就可通过

CArchive对象和CSocketFile对象在CSocket对象和可串行化对象之间传输,从而可以实现网络上

的数据接收(对应串行化的加载)和发送(对应串行化的存储)。

8. 简述使用CSocket类、CSocketFile类以及CArchive类编写网络通信程序的步骤。

答案参见教材第9.2.4节

9. 例9.3的客户端程序见:《Windows网络编程基础教程》(第2版)课后习题编程题参考代码.rar。

该程序不能和例9.1的服务器程序正确通信。因为采用串行化方法收发数据时,要求收发双方

都必须使用串行化方法,而且串行化类的定义必须完全一致,类名、数据成员等都必须相同。

18