山东农业大学,老师: 。出题:会换选项,大题搞明白,下面有参考。
第二章
解释下列语句出的含义。
(1)CStrings;
(2)CStrings(“Hello,VisualC++”);
(3)CString s(‘A’,100);
(4)CStrings(buffer,100);
(5)CStrings(anotherCString)。
答:(1)构造一个长度为 0 的字符串对象。
(2)构造一个名称为 s 的字符串对象,并把字符串初始化为 Hello,Visual C++6.0。
(3)构造一个名称为 s 的字符串对象,s 字符串的内容是 100 个 A。
(4)构造一个名称为 s 的字符串对象,s 字符串的内容是 buffer 的头 100 个字符,再 加一个 NULL。
(5)构造一个名称为 s 的字符串对象,s 字符串的内容和 anotherCString 字符串的内 容相同。
简述句柄的含义?
答:句柄是一个(通常为 32 位的)无符号整数(unsignedint),通常用它来标识一个内
核对象。
消息映射是指什么?是如何实现的?
答:消息映射是指在每个能接收和处理消息的类中定义的一个消息和消息处理函数的对照
表,即消息映射表,在该表中,类所能处理的所有消息及其对应的消息处理函数的地址都
成对地列在这个静态表中。当有消息需要处理时,程序只要搜索消息映射表,查看表中是
否含有该消息,就可知道该类能否处理此消息,如果能处理,则调用表中对应的消息处理
函数。
简述为对话框应用程序添加自定义消息 WM_MYSOCKMSG 的步骤。
答:在对话框中添加自定义消息的方法为:
a)定义消息号:使用宏定义语句 #define‛增加一个用户自定义消息,该定义的作用范围 应该包括整个类。该消息号不能与现有消息的消息相同。通常用户自定义的消息号从系统定 义的常量 WM_USER 开始分配。例如: #define WM_MYSOCKMSG (WM_USER+1)
b)使用“类向导”添加自定义消息:选择要处理消息的对话框类,选中“消息”选项卡, 单击选项卡下部的“添加自定义消息”按钮,在弹出的“添加自定义消息”对话框中填入自 定义消息和消息处理函数的名称。输入自定义消息后,向导会自动生成一个缺省的消息处理 函数名,一般直接采用这个缺省的消息处理函数名则可,当然也可以重新命名该函数,类向 导会自动在对话框类的实现文件(.cpp)中添加消息处理函数的框架。
c)编辑消息处理函数:在对话框类的实现文件中找到消息处理函数,在函数题中添加程 序代码。
第三章
在网络通信中为什么要引入端口?
答: 在网络通信过程中,需要唯一识别通信两端的端点,即运行于某机器中的应用程序。 如果没有引入端口,则只能通过进程号进行识别。进程号是系统动态分配的,不同的系统 会使用不同的进程标识符,应用程序在运行之前并不知道自己的进程号,如果需要运行 后再广播进程号则很难保证通信的顺利进行。而引入端口后,就可以利用端口号识别应 用程序,同时通过固定端口号来识别和使用公共服务,如 HTTP 和 FTP 等。
由于网络原因,调试程序时发送数据总是不能成功,问采用何种方法可找出发送数据 不能成功的具体原因?
答:在程序中,调用 send()函数后,如果发送数据不成功,则调用 WSAGetLastError() 获取套接字的错误代码,通过该代码便可查得错误原因。
第四章
画框图说明服务器端和客户机端操作流式套接字的基本步骤。
答:
服务器进程首先启动,并等待客户端的连接建立请求,其基本通信过程如下:
(1)调用 socket 函数建立一个套接字,该套接字用于监听;
(2)调用 bind 函数为套接字绑定一个端口号和 IP 地址;
(3)调用 listen 函数,设置套接字处于监听状态;
(4)如果程序不退出,反复执行以下各步:
①用 accept 函数等待客户机的连接到来。如果有远程计算机的连接请求到来,则用一个新 的套接字建立起与客户机之间的通信连接;
②使用 recv 函数和 send 函数利用新建的连接与客户端通信;
③通信完毕调用 closesocket 函数关闭连接;
(5)调用 closesocket 函数关闭监听套接字,程序结束。
客户端的主要职责就是发起与服务器的通信,它对套接字的使用方式与服务器端相比是有所差别的。客户端程序的流程如下:
(1)用 socket 函数建立一个套接字,设定服务器的 IP 和端口;
(2)调用 connect 函数连接远程计算机指定的端口;
(3)利用新建的连接与服务器通信;
(4)通信完毕调用 closesocket 函数关闭连接。
第五章
无简答,只有编程
第六章
套接字的阻塞模式与非阻塞模式有何区别?如何将一个套接字设为非阻塞模式?
略(参考教材相关章节)
简要叙述使用 WSAAsyncSelect 模型编写网络通信程序的步骤。
略(参考教材相关章节)
第七章
1.画框图说明无连接数据报套接字编程的基本步骤。
答:无连接的套接字编程有两种模式:C/S(客户/服务器)模式和 P2P(对等)模式。
- 对等模式数据报套接字的编程模型:
- 客户/服务器模式编程模型
2.画框图说明使用数据报套接字发送广播数据的基本流程。
第八章
请简要叙述 ping 程序的工作原理及实现方法
答:Ping 是通过 ICMP 协议实现的。Ping 程序发送 ICMP 回送请求消息给目的主机,ICMP 协议规定,目的主机必 须返回 ICMP 回送应答消息给源主机。如果源主机在一定时间内收到应答,则认为主机可达。PING 利用 ICMP 协 议包来侦测另一个主机是否可达。原理是构造并发送多个类型码为 0 的 ICMP 回送请求包,其中用发送时的时间 来填写时间戳字段,使用原始套接字发送给目的机器,收到 ICMP 回送请求包的目的主机则将收到的 ICMP 包用类 型码改为 8,重新计算校验和并替换后再封装到 IP 分组中发送回去作为回应。ping 程序接收目的机器会送回来 的 ICMP 回送响应包,并以此计算发送和接收之间的时间间隔,同时统计有多少个包被送达。用户依此就可以判 断网络大致的情况。
//以下题全部没写报错语句
1.编写程序,查询本机的主机名称及 IP 地址
#include “WinSock2.h”
#include “iostream”
#pragma comment(lib,”ws2_32.lib”)
Using namespace std;
Int main(int argc,char **argv)
{
/***定义变量***/
struct hostent * hptr;
char **pptr;
char hostname[256];
/***初始化WinSock DLL***/
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2,2);
WSAStartup(wVersionRequested,&wsaData);
//获取本机名字
If(gethostname(hostname,sizeof(hostname)))
{
Cout<<”获取主机名失败”<<eendl;
WSACleanup();
Return 0;
}
cout<<”本机名:”<<hostname;
If((hptr=gethostbyname(hostname))==NULL)
{
Cout<<”通过主机名获取IP失败”<<endl;
WSACleanup();
Return 0;
}
//输出IP地址
pptr=hptr->h_addr_list;
cout<<”本机IP:”;
while(* pptr!=NULL)
{
cout<<inet_ntoa(*(struct addr_in)(* pptr))<<endl; //将一个十进制网络字节序转换为点分十进制IP格式的字符串。
pptr++;
}
WSACleanup();
Return 0;
}
/***************************************************************************************************/
2. 编写一个 TCP 客户程序,该程序把本机 C:盘根目录下的一个文件 a.txt 的内容发送给服
务器(文件内容发完就关闭连接)。
#include “WinSock2.h”
#include “iostream”
#include “fstream”
//#include “direct.h”
#include “fileMessage.h”
#define PORT 65432
#pragma comment(lib,”ws2_32.lib”)
Using namespace std;
Int main(int argc,char **argv)
{
SOCKET sock_client;
Struct sockaddr_in server_addr;
Int addr_len=sizeof(struct sockaddr_in);
/***初始化winsock DLL***/
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2,2);
If(WSAStartup(wVersionRequested,&wsaData)!=0)
{
Cout<<”加载winsock动态链接库失败”<<endl;
Return 0;
}
/***创建套接字***/
if((sock_client=socket(AF_INET,SOCK_STREAM,0))<0) //建立一个socket
cout<<”创建一个套接字失败”<<endl;
WSACleanup();
Return 0;
}
/****连接服务器***/
Memset((void *)&server_addr,0,addr_len);
Server_addr.sin_family=AF_INET;
Server_addr.sin_port=hton(PORT);
Server_addr.sin_addr.s_addr=inet_addr(“127.0.0.1”);
If(connect(sock_client,(struct sockaddr *)&server_addr,addr_len)!=0)
{
Cout<<”连接失败!”<<endl;
Closesocket(sock_client);
WSACleanup();
Return 0;
}
/****定义文件传输所需要的变量***/
Struct fileMessage filemsg;
Char filename[500]=”c:\\a.txt”;
//Long int filelen;
/*******打开要传输的文件***/
Ifstream infile(filename,ios::in|ios::binary);
If(!inFile.is_open())
{
Cout<<”Cannot open”<<filename<<endl;
closeSocket(socl_client);
WSACleanuo();
Return 0;
}
/***获取文件长度**/
inFile.seekg(0,ios::end); //将文件位置指针移动到文件在末尾
size =inFile.tellg() //获取当前文件位置指针,其值为文件长度
inFile.seekg(ios::beg);
/***发送文件名及文件长度***/
Filemsg.filesize=htol(size);
Send(socket_client,(char *)& filemsg,sizeof(filemsg),0) //发送filemsg
/****发送文件内容****/
While(!inFile.eof())
{
Infile.read(filebuffer,sizeof(filebuffer));
Size=infile.gcount(); //获取世界读取的字节数
Send(sock_client,filebuffer,size,0);
}
Cout<<”结束”<<endl;
Infile.close();
Closesocket(sock_client);
WSACleanup();
Return 0;
}
3. 编写一个 TCP 服务器程序,该程序把一个客户发来的数据(数据量不定,对方发完将关闭
连接)保存在本机 C:盘根目录下的一个文件 a.txt 中。
#include “WinSock2.h”
#include “iostream”
#include “fstream”
#include “direct.h”
#include “fileMessage.h”
#define PORT 65432
#pragma comment(lib,”ws2_32.lib”)
Using namespace std;
Int main(int argc,char **argv)
{
SOCKET sock_server; //定义接收客户端套接字的变量
struct sockaddr_in addr; //用于填写绑定地址的结构变量
int len = sizeof(struct sockaddr_in);
/***初始化winsock DLL***/
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2,2);
If(WSAStartup(wVersionRequested,&wsaData)!=0)
{
Cout<<”加载winsock动态链接库失败”<<endl;
Return 0;
}
/****创建监听套接字****/
If((sock_server=socket(AF_INET<SOCKSTREAM,0))<0)
{
Cout<<”创建套接字失败”<<endl;
WSACleanup();
Retrun 0;
}
/*****绑定IP地址与端口***/
Memset((void *)&addr,0,addr_len);
Addr.sin_family=AF_INET;
Add.sin_port=htons(PORT);
Add.sin_addr.s_addr=htonl(INADDR_ANY); //允许本机任何IP地址
If(bind(sock_server,(struct sockaddr *)&addr,sizeof(addr))!=0)
{
Cout<<”绑定失败!”<<endl;
Closesocket(sock_server);
WSACleanup();
Return 0;
}
/*****开始监听****/
If(listen(sock_server,5)!=0)
{
Cout<<”listen函数调用失败!”<<endl;
Closesocket(sock_server);
WSACleanup();
Return 0;
}
Else
Cout<<”listening…………”endl;
/***定义文件传输所需要的变量*****/
Struct filemessage filemsg;
Long int filelen;
Char filename[500]=”c:\\a.txt”;
Char filebuffer[1100];
/****创建文件保存目录***/
_mkdir(filename); //用于创建文件夹,其生命在direct.h
/***接受文件名及长度**/
Filelen=ntohl(filemsg.filesize);
Strcat(filename,filemsg.filename); //在