网络编程复习资料
1. 如果网络进程间采用基于TCP、UDP协议的无连接的通信方式,那么必须借助数据报套接字来编程。
2. ntohs()函数的含义是短整数网络顺序转换为本机顺序,用于端口号。
3. TCP和UDP协议属于传输层协议,HTTP和FTP则属于应用层协议。
4. TCP/IP协议栈采用静态(全局)分配和动态(本地)分配相结合的方法,将TCP和UDP各自的65535个端口号分为保留端口号和自由端口号。
5. 为了简化套接字网络编程,MFC提供了两个套接字类:阻塞模式和非阻塞模式。
6. CAsyncSocket类支持Windows消息驱动机制,体现在该类对象支持6种网络事件。请列举其中5个网络事件,FD-READ事件、FD-WRITE事件、FD-ACCEPT事件、FD-CONNECT事件和FD-CLOSE事件FD-OOB事件。
1. 控制台程序的入口函数是mian函数。
3. 从套接字所处的地位来讲,套接字上连应用进程,下连网络协议栈。
4. ntohl()函数的含义是长整数本机顺序转换为网络顺序,用于IP事件。
6. 用于映射命令消息的宏是ON-COMMAND。用于映射Windows消息宏的前缀是ON-WM- 。
1. FTP协议的端口号是21 。
2. 在Internet中,用一个三元组可以在全局中唯一地标识一个应用层进程,分别是应用层协议、本机IP地址和传输层端口号
3.套接字分为三种,分别是数据报套接字、流式套接字和原始式套接字、
4、专门针对Internet通信域,存储套接字相关的网络地址信息的结构体是sockaddr_in
5、sendto函数是用于发送信息的函数,相对应的信息接收函数是recvfrom()
6、消息名以前缀“WM_”打头的消息是系统消息
7、WinSock应用程序开发的第一步是对WinSock进行初始化,调用的函数WSAStartup
8、CInternetSession类中用于建立与FTP服务器连接的成员函数是GetFtpConnection
9、对于非阻塞的套接字工作模式,引入5种“套接字I/O模型”,分别是选择模型、事件选择模型、异步选择模型、重叠I/O、完成端口
10、监听函数调用listen(s,5),其中参数5的含义是将套接字s加入到集合set中。
11、为了更方便地利用Windows系统的消息驱动机制,MFC提供了两个套接字类,实现了对套接字函数的封装,分别是阻塞模式和非阻塞模式
12、socket(AF_INET,SOCK_DGRAM,0);该函数的功能是创建一个数据报套接字
1、HTTP协议的端口号是80。
2、针对各种通信域的套接字,存储相应地址信息的结构体sockaddr_in。
3、在MFC中,线程分为两种,分别是工作线程和用户界面线程
4、MFC消息类型有三种,分别是Windows消息、控制通知消息、命令消息
5、用于把一定范围的命令消息映射到一个消息处理函数的宏是
ON_COMMAND_RANGE。
6、CFtpConnection类中用于将本地文件上传到服务器的函数是PutFile
7、用于将套接字s加入到集合set中的宏是FD_SET(s,*set)
8、在WinSock中,错误代码可以通过调用WSAGetLastError()函数得到。
9、监听函数调用listen(s,3),其中参数3的含义是等待队列的长度。
10、WinSock进行I/O操作的两种工作模式分别是阻塞和非阻塞。
11、TCP和UDP协议属于传输层协议,RPC和FTP则属于应用层协议
12、异步套接字类中用于通知有数据可读的事件是 FD_READ,对应的回调函数是OnReceive ;用于通知可以写数据的事件是 FD_WRITE,对应的回调函数是OnSend 。
简要说明套接字的应用场合。
(1)不管是采用对等模式或者客户机/服务器模式,通信双方的应用程序都需要开发。(2)双方所交换数据的结构和交换数据的顺序有特定的要求,不符合现在成熟的应用层协议,甚至需要自己去开发应用层协议,自己设计最适合的数据结构和信息交换规程。
套接字编程分为面向连接和无连接两种类型,请说明面向连接套接字编程中客户端的编程流程。
创建流式套接字,发送连接请求,发送数据,接收数据,关闭套接字。
解释进程和线程的概念,简要说明如何正常终止线程和提前终止线程。
进程是处于运行过程中的程序实例,是操作系统调度和分配资源的基本单位。线程是进程的一个实体,执行和调度单位。正常终止线程:在函数执行完毕时能够退出控制函数,并返回一个用来表示终止原因的值。提前终止线程:在线程内部调用AfxEndThread函数,便可强迫终止。
简要说明select 选择模型的操作步骤。
首先,检查系统中是否有一个或多个套接字实例;其次,检查找到Winsock实现是否可用,主要确认版本号;再者,建立Winsock实现与应用程序的联系;最后,函数成功返回,返回必要的参数。
简要说明WSAStartup函数的初始化过程。
首先,检查系统中是否有一个或多个套接字实例;其次,检查找到Winsock实现是否可用,主要确认版本号;再者,建立Winsock实现与应用程序的联系;最后,函数成功返回,返回必要的参数。
什么是阻塞问题?UNIX操作系统下是如何应对的?
阻塞是指一个进程执行了一个函数或者系统调用,该函数由于某种原因不能立即完成,因而不能返回调用它的进程,导致进程受控于这个函数而处于等待的状态,进程的这种状态称为阻塞。利用UNIX操作系统的FORK()系统调用,编制多进程并发执行的服务器程序。
套接字编程分为面向连接和无连接两种类型,请说明面向连接套接字编程中服务器端的编程流程。
创建流式套接字,绑定该套接字,启动套接字监听,接受客户端的连接请求,读写数据,关闭套接字。
在全局中唯一地来标识网络中通信的两个进程需要五元组,请说明五元组由哪几部分组成。
传输层协议,本机IP地址,本地机传输层端口,远地机IP地址,远地址传输层端口
简要说明WSAEventSelect事件选择模型的操作步骤。
创建事件对象句柄;关联套接字和事件对象,注册关心的网络事件;等待网络事件触发事件对象句柄的工作状态;检查套接字上所发生的网络事件类型;处理网络事件
请简要说明基于Internet的C/S模式应用程序的特点。
非对称性:服务器提供服务,客户端使用服务;
对等性:客户机和服务器公有一套约定;
服务器的被动性:不主动提供服务;
客户机的主动性:客户机主动向服务器提出请求;
说明CAsyncSocket异步套接字类中用于通知数据可读和可写的事件及回调函数
可读事件:FD_READ事件通知,通知有数据可读;回调函数是OnReceive(int nErrorCode)。
可写事件:FD_WRITE事件通知,通知有数据可写;回调函数是OnSend(int nErrorCode)。
1. 能引起阻塞的套接字调用有哪些?
ACCEPT()等待接收客户端的连接请求;RECV和RECVFORM用于接收数据的函数;SEND和SENDTO用于发送数据的函数;CONNECT客户端连接服务器的函数;SELECT用于判断符合条件套接字的函数。
2. 请描述C/S模式的无连接套接字编程流程。
(1)服务器先启动,等待客户端发数据;
(2)服务器进程将套接字绑定到固定端口;
(3)客户端使用自由分配端口号;
(4)客户端首先发送数据,携带对方的地址;
(5)服务器接收数据,同时获取到发送端地址,便可回发数据。
3. 说明WinSock两种工作模式的优缺点。
WinSock有两种工作模式:阻塞和非阻塞模式。
阻塞模式:经过调用、等待和返回过程。如果不满足网络条件,会永远阻塞。
非阻塞模式:函数调用后会立即返回,不管是否成功。如果不满足网络条件,会造成资源浪费,很多无功而返的情况。
简述WSAAsyncSelect异步I/O模型的编程步骤。
①用createwindow函数创建一个窗口回调例程;
②设置好窗口的框架后,开始创建套接字;
③调用异步选择模型函数WSAAsyncSelect,并注册感兴趣的事件,指定接收消息的窗口句柄。
1什么是线程,什么是进程?
进程是处于运行过程中的程序实例,是操作系统调度和分配资源的基本单位。一个进程实体由程序代码、数据和进程控制块三部分构成。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
2实现网间进程通信必须解决哪些问题?
(1)网间进程的标识问题;(2)如何与网络协议栈连接的问题;(3)协议的识别问题;(4)不同的通信服务的问题
3举例说明面向消息的协议与基于流动协议有什么不同。
例如甲向乙发送三个消息,分别是:128、64和32字节。
面向消息的协议中,如果接受缓冲区是256字节,足以接收3条消息,且这三条消息全部达到。乙仍然需要发送3条读取消息。分别返回128、64、32字节,而不用一次读取来调用者单个数据包。
基于流的消息协议中,在接收端乙的堆栈把所有进来的消息数据包聚集在一起,放入堆栈,等待应用进程读取。进程发送读取命令,指定了进程接收缓冲区,如果进程缓冲区有256字节,系统马上返回全部224字节。
4说明用户和客户机,服务器和服务器类计算机的区别。
客户(client)和服务器都指的是应用进程,即计算机软件。“用户”(user)指的是使用计算机的人。服务器(server)这个术语来指那些运行着的服务程序。服务器类计算机(server-class computer)这一术语来称呼那些运行服务器软件的强大的计算机。
5什么是套接字?
答:是应用程序通过网络协议栈进行通信交互的接口。
6说明套接字特点。
答:(1)通信域。套接字通常只和同一域中的套接字交换数据。如果数据交换要穿越域的边界,就一定要执行某种解释程序。(2)套接字有三种类型,流式、数据包和原始套接字。(3)套接字由应用层创建,并为其服务,而后被释放。(4)使用确定的IP地址和传输层端口号。
7说明套接字应用场合。
答:(1)不管是采用对等模式或者客户机/服务器模式,通信双方的应用程序都需要开发。(2)双方所交换数据的结构和交换数据的顺序有特定的要求,不符合现在成熟的应用层协议,甚至需要自己去开发应用层协议,自己设计最适合的数据结构和信息交换规程。
8什么是阻塞问题?如何对应?
答:阻塞是指一个进程执行了一个函数或者系统调用,该函数由于某种原因不能立即完成,因而不能返回调用它的进程,导致进程受控于这个函数而处于等待的状态,进程的这种状态称为阻塞。利用UNIX操作系统的FORK()系统调用,编制多进程并发执行的服务器程序。
9说明WSAStartup函数初始化过程。
(1)查找WinSock.DLL文件,如果有WinSock实现,则调入相关信息。若无,则初始化失败。返回错误信息。(2)。确认版本号。(3)建立WinSock同应用程序的联系。(4)函数创建成功,在WSAData结构中返回许多信息,否则,通知用户“初始化失败”。
10多线程机制在网络编程中如何应用?
如果一个应用程序,有多个任务需要同时进行处理,那就最适合使用多线程机制。对于网络上客户机软件,采用多线程的编程技术,能克服在单线程的编程模式下,由于阻塞等待而产生的客户程序就不能及时响应用户的操作命令的问题。对于网络上服务器软件,采用多线程的编程技术,能更好地为多个客户服务。即便是对于一个客户,采用多线程机制也能大大提高应用程序的运行效率。
11使用CAsyncSocket类的一般步骤是什么?
序
号
服务器(Server)客户机(Client)
1 //构建一个套接字
CAsyncSocket sockSrvr; //构建一个套接字CAsyncSocket sockClient;
2 //创建SOCKET句柄,绑定到指定的
端口
sockSrvr.Create(nPort); //创建SOCKET句柄,使用默认参数sockClient.Create();
3 //启动监听,时刻准备接受连接请求
sockSrvr.Listen();
4 //请求连接到服务器
sockClient.Connect(strAddr,nport);
5 //构造一个新的空的套接字
CasyncSocket sockRecv;
//接收连接
sockSrvr.Accept(sockRecv);
6 //接收数据
sockSrvr.Receive(pBuf,nLen); //发送数据
sockClient.Send(pBuf,nLen);
7 //发送数据
sockSrvr.Send(pBuf,nLen); //接收数据
sockClient.Receive(pBuf,nLen);
8 //关闭套接字对象
sockSrvr.Close(); //关闭套接字对象sockClient.Close();
12使用WinInet类编程的一般步骤是什么?
(1)创建CInternetSession类对象,创建并初始化Internet会话。
(2)利用CInternetSession类的QueryOption或SetOption成员函数,可以查询或设置该类内含的Internet请求选项,这一步是可选。
(3)创建连接类对象,建立CInternetSession对象与网络服务器的连接,也就是应用程序与网络服务器的连接。
(4)创建文件检索类对象,对服务器进行检索
(5)如果需要使用异步操作模式,可以重载CInternetSession类的OnStatusCallback 函数,并启动应用程序使用状态回调机制。重载相关函数,加入自己的代码。
(6)如果还想更紧密地控制对于服务器文件的访问,可以进一步创建文件类对象实例,完成文件查找或文件读写操作。
(7)创建CInternetException类对象实例,处理错误。
(8)关闭各种类,将资源释放给系统。
13说明用户接口线程和工作线程的概念和特点。
用户接口线程:通常用来处理用户输入产生的消息和事件,并独立地响应正在应用程序其它部分执行的线程们产生的消息和事件。用户接口线程包含一个消息处理的循环,以应对各种事件。
工作线程:适用于处理那些不要求用户输入并且比较消耗时间的其他任务。对用户来说,工作线程运行在后台。这就使得工作线程特别适合去等待一个事件的发生。
14简述创建MFC的工作线程所必需的步骤。
(1)是编程实现控制函数。
(2)是创建并启动工作线程。
(3)创建工作线程的例子。
(4)创建工作线程的一般模式。
15如何正常终止线程?如何提前终止线程?
答:正常终止线程:执行完毕时退出控制函数,并返回三个用来表示终止原因的值即可。
提前终止线程:从线程内调用AfxEndThread函数,就可以强迫线程终止。
16非阻塞套接字的五种“套接字I/O模型”:
select(选择)、
WSAAsyncSelect(异步选择)、
WSAEventSelect(事件选择)、
Overlapped I/O(重叠式I/O)
以及Completion port(完成端口)。
17 WSAAsyncSelect异步I/O模型的编程步骤
⑴用CreateWindow函数创建一个窗口,并为该窗口提供一个窗口回调例程。
⑵调用WSAAsyncSelect函数创建套接字,指定关注的套接字、窗口句柄、打算接收的消息,以及程序感兴趣的套接字事件。成功执行WSAAsyncSelec函数,就打开了窗口的消息通知,并注册了事件。
⑶WSAAsyncSelec函数执行时,当注册的套接字事件之一发生时,指定的窗口会收到指定的消息,并自动执行该窗口的回调例程,可在其中添加自己的代码,处理相应的事件。
18 WSAEventSelect事件选择模型的编程步骤
⑴创建事件对象句柄
事件选择模型要求应用程序针对每一个套接字,首先创建一个事件对象。创建方法是调用WSACreateEvent函数,定义如下:
WSAEVENT WSACreateEvent(void);
⑵关联套接字和事件对象,注册关心的网络事件
将事件对象句柄与某个套接字关联在一起,同时注册感兴趣的网络事件类型。调用WSAEventSelect函数,函数的定义为:
int WSAEventSelect(
SOCKET s,
WSAEVENT hEventObject,
long lNetworkEvents
);
⑶等待网络事件触发事件对象句柄的工作状态
调用WSAWaitForMultipleEvents函数,等待网络事件触发事件对象句柄的工作状态。该函数的定义:
DWORD WSAWaitForMultipleEvents(
DWORD cEvents,
const WSAEVENT FAR * lphEvents,
BOOL fWaitAll,
DWORD dwTimeout,
BOOL fAlertable
);
⑷检查套接字上所发生的网络事件类型
调用WSAEnumNetworkEvents函数,检查套接字上发生了什么类型的网络事件。该函数定义如下:
int WSAEnumNetworkEvents(
SOCKET s,
WSAEVENT hEventObject,
LPWSANETWORKEVENTS lpNetworkEvents
);
⑸处理网络事件
在确定了套接字上发生的网络事件类型后,可以根据不同的情况做出相应的处理。完成了对WSANETWORKEVENTS结构中的事件的处理之后,应用程序应在所有可用的套接字上,继续等待更多的网络事件。
应用程序完成了对一个事件对象的处理后,便应调用WSACloseEvent函数,释放由事件句柄使用的系统资源。函数的定义如下:
BOOL WSACloseEvent(WSAEVENT hEvent);
该函数也将一个事件句柄作为自己唯一的参数,并会在成功后返回TRUE,失败后返回FALSE。
15什么是HTTP会话?HTTP会话周期由哪些阶段组成?
HTTP是超文本传输协议(Hypertext Transfer Protocol)的简称,HTTP协议也是基于TCP/IP的客户/服务器协议。主要是用于传输文件的协议。
HTTP会话周期由连接、请求、响应和断开4个阶段组成。
⑴建立TCP/IP连接
⑵Web客户机向服务器发送HTTP请求
⑶服务器向客户机回送HTTP响应
⑷断开TCP/IP连接
16简述电子邮件系统的构成。
答:一个电子邮件系统包括三个主要的构件,即用户代理,邮件消息传输代理,和电子邮件使用的协议。
1.多线程的使用。
CTestDlg::OnOk( )
{
int i=2; //定义一个整型数,赋值为2(2分)
AfxBeginThread(MyThreadFunc,&i); //开启线程,线程控制函数为MyThreadFunc }
UINT MyThreadFunc (LPVOID lpParam)
{
int* i = (int*) lpParam; //取出参数(2分)
switch (*i)
{
case 2:
AfxMessageBox(“测试成功”);
//当接收到的数为2时,弹出信息提示框,信息提示框显示“测试成功”(3分)
break;
default:
break;
}
return 0;
}
2.select模型的使用。
基于UDP协议的接收端程序中的recvfrom( )函数工作在非阻塞模式,使用select 选择模型对recvfrom( )函数的调用进行控制。部分代码已给出,按要求填空。
void main(void)
{
……………………………………………………
SOCKET s=socket(AF_INET,SOCK_DGRAM,0);
fd_set Readset; //定义一个套接字集合变量(2分)
FD_ZERO(&Readset); //清除套接字集合变量(2分)
FD_SET(s,&Readset); //将套接字s加入到套接字集合中(3分)int Readynum=0;
Readynum=select(0,&Readset,NULL,NULL,NULL);
if (Readynum>0)
{
if( FD_ISSET(s,&Readset))//判断套接字s是否还在套接字集合中(3分) {
recvfrom(s,buf,256,0,(sockaddr*)&from,&fromlength);
}
}
}
1. 设计一个文件拷贝的程序(基于对话框的工程),实现本地文件的移动。
①自行设计界面,包括填写源文件路径和目标文件路径,拷贝按钮。(4分,如果只有文字描述,没有绘制图形,给3分)
②写出对话框界面上控件对应的变量。(变量名可以自拟)(2分)
为IDC_EDIT_SOURCE_PATH添加VALUE类型的CString变量m_strSource(1分,变量名自拟)
为IDC_EDIT_TARGET_PATH添加VALUE类型的CString变量m_strTar(1分,变量名自拟)
③写出拷贝按钮的处理函数。(4分)
UpdateData(TRUE);(2分)
CopyFile(m_strSourc,m_strTar,FALSE);(2分)
3.编写点对点通信的接收端程序,使用UDP协议。要求如下:①遵循无连接的套接字编程流程;②端口取值7000;③输出接收到的信息。
#include
#include
#pragma comment(lib,"ws2_32.lib")//以上三句可以不写
void main(void)
{
sockaddr_in from,bind;//变量名可自定义
WSADATA wsdata;
WSAStartup(MAKEWORD(2,0),&wsdata);(1分)
SOCKET s=socket(AF_INET,SOCK_DGRAM,0);(1分)
bind.sin_family=AF_INET;(1分)
bind.sin_addr.s_addr=inet_addr("192.168.0.66");(1分)//地址可以自定义
bind.sin_port=htons(7000);(1分)
bind(s,(sockaddr *)& bind,sizeof(sockaddr));(1分)
int fromlength=sizeof(SOCKADDR);
char buf[256];
while(1)
{
recvfrom(s,buf,256,0,(sockaddr*)&from,&fromlength);(2分)
Sleep(1000);
printf("%s\n",buf);(2分)
}
}
2.CHtmlView类的使用。
基于单文档的工程,在菜单和工具栏中添加刷新功能。其中,CMyWebView由CHtmlView 类派生而来。
①菜单和工具栏中刷新功能执行相同的操作,请问如何实现;(4分)
②写出刷新功能的映射宏;(3分)
③
void CMyWebView::OnUpdate()
{
// 刷新当前的网页(3分)
}
只要将两者的ID号取相同的名字即可,或者取不同ID号,映射到同一个刷新函数上。ON_COMMAND(ID_UPDATE,OnUpadate)
Refresh();
3.编写点对点通信的发送端程序,使用UDP协议。要求如下:
①遵循无连接的套接字编程流程;(7分)
②端口取值7000;(1分)
③发送成功提出提示。(2分)
#include
#include
#pragma comment(lib,"ws2_32.lib")//以上三句可以不写
void main(void)
{
sockaddr_in from,bind;//变量名可自定义
WSADATA wsdata;
WSAStartup(MAKEWORD(2,0),&wsdata);(1分)
SOCKET s=socket(AF_INET,SOCK_DGRAM,0);(1分)
bind.sin_family=AF_INET;(1分)
bind.sin_addr.s_addr=inet_addr("192.168.0.66");(1分)//地址可以自定义bind.sin_port=htons(7000);(1分)
int fromlength=sizeof(SOCKADDR);
char buf[256];
while(1)
{
sendto(s,buf,256,0,(sockaddr*)&from,&fromlength);(2分)
Sleep(1000);
printf("ok");(2分)
}
WSACleanUp();(1分)
}