资源描述
计算机网络课程设计汇报
题 目: 当地网络信息设置和
网络对时程序设计
系 别: 计算机科学和工程学院
专 业: 信息安全
学生姓名:
学 号:
指导老师: 王虎寅
4月 21日
引言 1
1 设计目标及任务 2
1.1 课程设计目标 2
1.2 课程设计任务 2
2 需求分析 2
2.1 用户需求 2
2.2 开发环境 2
3 设计和实现 3
3.1 总体分析和设计 3
3.1.1 主窗体设计 3
3.2 各个模块设计和实现 4
3.2.1 主机名字 4
3.2.2 IP 5
3.2.3 MAC 6
3.2.4 DNS 8
3.2.5 网络协议 10
3.2.6 IP统计信息 11
3.2.7 TCP统计信息 14
3.2.8 修改当地网络信息设置 15
3.2.9 时间模块 17
4 设计总结 20
4.1 碰到问题 20
4.2 总结体会 21
参考资料 21
附录 22
代码 22
引言
深入了解计算机网络基础原理,将书本上抽象概念和具体实现技术相结合,体会网络协议设计和实现过程,和专业技术人员所使用基础方法和技巧;熟悉相关应用开发工具,掌握网络协议应用开发技术;深入熟悉网络设备,学习组网技术,掌握网络计划和设计基础方法;培养一定自学能力和独立分析问题、处理问题能力;对设计中碰到问题,能经过独立思索、查阅资料、参考文件,寻求处理方案。
本篇汇报将这次课程设计所完成软件,从准备阶段到完成整个过程逐步介绍和创作过程中碰到问题和最终总结和心得体会,使得读者能有效了解软件实现功效和怎样去实现该功效,也期望读者能从中学习到些许经验。
1 设计目标及任务
1.1 课程设计目标
本课程设计是学习完成《计算机网络》课程后,进行一次全方面综合训练,培养深入了解和掌握网络组网过程及方案设计,为以后从事实际工作打下基础;并学会部分编程语言掌握和应用,比如VS 并掌握其MFC使用。
1.2 课程设计任务
设计一个当地网络信息设置和网络对时程序,关键功效以下:
(1)当地网络信息获取
计算机名称、IP地址、网卡地址、DNS设置、安装协议、提供服务、TCP/IP运行信息。
(2)修改当地计算机网络设置
(3)采取ntp协议从internet上某个时间服务器,获取时间信息,正确地更新当地机时钟,支持手动、定时自动两种方法
2 需求分析
2.1 用户需求
从用户角度来分析本软件应含有以下功效:首先要有友好简结而且方便操作界面,能给使用它人耳目一新感觉,这么话就要用到VS里面MFC了;其次就是经过该软件能够获取计算机部分基础配置信息和部分设置修改,如:获取计算机名称和IP地址、获取计算机子网掩码、获取计算机DNS设置、获取计算机网卡地址、获取计算机安装协议、获取计算机提供服务、获取计算机全部网络资源、获取计算机TCP/IP全部信息和对当地计算机网络设置修改。这么话,让人一打开这软件就能很轻易了解它到底有什么功效和它能为用户做些什么工作了。
2.2 开发环境
此次课程设计是在以下环境下设计创作完成:
操作系统:Windos 8.1
开发平台:Visual Studio
VS是一个基础完整开发工具集,它包含了整个软件生命周期中所需要大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等等。所写目标代码适适用于微软支持全部平台,包含Microsoft Windows、Windows Mobile、Windows CE、.NET Framework、.NET Compact Framework和Microsoft Silverlight 及Windows Phone。
Visual Studio是现在最流行Windows平台应用程序集成开发环境。
Visual Studio 提供多个强大工具和服务,帮助使用者发明新式应用程序或将现有应用程序转变为新式应用程序,令用户在多个屏幕和设备上享受到最好体验,同时仍和所需服务和数据保持联络。
3 设计和实现
3.1 总体分析和设计
获取当地网络信息,计算机名称、IP地址、子网掩码、DNS设置、网卡地址等等,需要大量代码一一对应,假如把她们细分成一个个模块,经过MFC对话框模式,点击一个按钮就显示出一个对应信息,那么将会简单、明了得多。所以,所需实现功效全部能在一个面板上经过对应按钮显示出来。
3.1.1 主窗体设计
新建MFC工程课设2.0,选择对话框模式,注意选择“Windows Sockets”复选框,其它保持默认。选择“Windows Sockets”后,系统就会自动完成Windows Sockets初始化和用完资源后释放。在窗体中添加各个控件,并修更名称,这么一个大致框架就出来了。以后我们只需要双击按钮,进入到按钮点击响应函数中去添加、修改代码,实现所需功效。
当然在实际设计中,在网络协议、IP统计信息、TCP统计信息这三个模块,考虑到弹出窗口来显示数据或许稍微显得有点不方便,所以采取在文本框中显示,而且同一时间只会显示一个内容。
图 1 主窗体设计
3.2 各个模块设计和实现
3.2.1 主机名字
获取主机名字,使用gethostname() 函数就能够实现了。gethostname() 函数会返回当地主机标准主机名,该函数把当地主机名存放入由name参数指定缓冲区中。返回主机名是一个以NULL结束字符串。主机名形式取决于Windows Sockets实现-它可能是一个简单主机名,或是一个域名。
---------------------------------------------------------------------------------------------------------------------
具体代码:
//初始化WinSock
WSADATA WSAData;
if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0)
{
return;
}
//取适当地计算机主机名称
CString strName = _T("");
gethostname(strName.GetBuffer(1024), 1024);
strName.ReleaseBuffer();
CString strText = _T("");
strText.Format(_T("当地计算机名称:\n%s"), strName);
AfxMessageBox(strText);
//清理WinSock
WSACleanup();
---------------------------------------------------------------------------------------------------------------------
结果:
图 2 主机名字
3.2.2 IP
此模块使用到gethostbyname()函数,
gethostbyname()函数说明——用域名或主机名获取IP地址,
所以你会从代码中发觉在“找到”IP之前,会先“找到”本机名字。
---------------------------------------------------------------------------------------------------------------------
具体代码:
//初始化WinSock
WSADATA WSAData;
if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0)
{
return;
}
//取适当地计算机主机名称
CString strName = _T("");
gethostname(strName.GetBuffer(1024), 1024);
strName.ReleaseBuffer();
//取适当地计算机信息
//gethostbyname()返回对应于给定主机名包含主机名字和地址信息hostent结构指针。
struct hostent* pHostEnt = gethostbyname(strName);
if (pHostEnt == NULL)
{
return;
}
//取适当地计算机IP地址
CString strText = _T("");
strText += _T("当地计算机IP地址:\n");
int n = 0;
while (pHostEnt->h_addr_list[n] != NULL)
{
CString strTemp = _T("");
strTemp.Format(_T("%d.%d.%d.%d\n"),
(pHostEnt->h_addr_list[n][0] & 0x00FF),
(pHostEnt->h_addr_list[n][1] & 0x00FF),
(pHostEnt->h_addr_list[n][2] & 0x00FF),
(pHostEnt->h_addr_list[n][3] & 0x00FF));
strText += strTemp;
n++;
}
AfxMessageBox(strText);
//清理WinSock
WSACleanup();
----------------------------------------------------------------------------------------------------------------------
结果:
图 3 IP
3.2.3 MAC
GetAdaptersInfo,
使用GetAdaptersInfo获取网卡具体信息(包含:Adapter Name,Mac,Ip,NetMask,NetGate)。
IP_ADAPTER_INFO,
结构体IP_ADAPTER_INFO包含当地计算机某一个网络适配器信息。
---------------------------------------------------------------------------------------------------------------------
具体代码:
DWORD nLength = 0;
if (GetAdaptersInfo(NULL, &nLength) != ERROR_BUFFER_OVERFLOW)
{
return;
}
IP_ADAPTER_INFO* pAdapterInfo = (IP_ADAPTER_INFO*)new BYTE[nLength];
//取适当地计算机网卡信息
if (GetAdaptersInfo(pAdapterInfo, &nLength) != ERROR_SUCCESS)
{
delete[] pAdapterInfo;
return;
}
//取适当地计算机MAC地址
CString strText = _T("当地计算机MAC地址:\n");
IP_ADAPTER_INFO* pCurrentAdapterInfo = pAdapterInfo;
while (pCurrentAdapterInfo != NULL)
{
//取得每个网卡MAC地址
CString strTemp = _T("");
strTemp.Format(_T("%02X-%02X-%02X-%02X-%02X-%02X\n"),
pCurrentAdapterInfo->Address[0],
pCurrentAdapterInfo->Address[1],
pCurrentAdapterInfo->Address[2],
pCurrentAdapterInfo->Address[3],
pCurrentAdapterInfo->Address[4],
pCurrentAdapterInfo->Address[5]);
strText += strTemp;
pCurrentAdapterInfo = pCurrentAdapterInfo->Next;
}
AfxMessageBox(strText);
delete[] pAdapterInfo;
---------------------------------------------------------------------------------------------------------------------
结果:
图 4 MAC
3.2.4 DNS
要用到函数是DWORD GetNetworkParams(PFIXED_INFO pFixedInfo,PULONG pOutBufLen) 参数及其功效说明以下:
pFixedInfo :输出指向FIXED_INFO结构指针,该结构是用来获取当地计算机网络参数。
pOutBufLen :输入指向一个ULONG变量指针,该ULONG变量指向pFixedInfo结构大小。
功效:函数GetNetworkParams()能够获取当地计算机网络参数,从而取得计算机DNS设置。成功,返回TRUE;失败,返回FALSE。该函数在头文件“Iphlpapi.h”中申明,由库文件“Iphlpapi.lib”来支持。
---------------------------------------------------------------------------------------------------------------------
具体代码:
FIXED_INFO * FixedInfo;
ULONG ulOutBufLen;
DWORD dwRetVal;
//IP_ADDR_STRING描述IP 地址链表节点。
IP_ADDR_STRING * pIPAddr;
FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
ulOutBufLen = sizeof(FIXED_INFO);
//获取本机网络参数 GetNetworkParams
if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &ulOutBufLen)) {
GlobalFree(FixedInfo);
FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, ulOutBufLen);
}
if (dwRetVal = GetNetworkParams(FixedInfo, &ulOutBufLen)) {
printf("获取网络参数失败.返回值: %08x\n", dwRetVal);
}
else {
CString strHostName;
CString strDomainName;
strDomainName.Format("域名:%s", FixedInfo->DomainName);
CString strDNS;
//DnsServerList 本机采取DNS服务器链表
strDNS.Format("DNS服务器:%s", FixedInfo->DnsServerList.IpAddress.String);
CString str;
str.Format("%s \n%s \n%s ", strHostName, strDomainName, strDNS);
MessageBox(str);
pIPAddr = FixedInfo->DnsServerList.Next;
while (pIPAddr) {
CString strIPAddr;
strIPAddr.Format("备选DNS服务器是:%s", pIPAddr->IpAddress.String);
MessageBox(strIPAddr);
pIPAddr = pIPAddr->Next;
}
}
---------------------------------------------------------------------------------------------------------------------
结果:
图 5 DNS_1
图 6 DNS_2
图 7 DNS_3
3.2.5 网络协议
WSADATA结构被用来储存调用AfxSocketInit全局函数返回Windows Sockets初始化信息。这个结构被用来存放被WSAStartup函数调用后返回Windows Sockets数据。它包含Winsock.dll实施数据。
WSAStartup,是Windows Sockets Asynchronous开启命令、Windows下网络编程接口软件 Winsock1 或 Winsock2 里面一个命令。
WSAEnumProtocols,获取现有传送协议相关信息。
---------------------------------------------------------------------------------------------------------------------
具体代码:
//初始化WinSock,目标:建立实例,申请资源,赋初值等等
m_ctrlList.ResetContent();
WSADATA WSAData;
if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0)
{
return;
}
int nResult = 0;
//取得需要缓冲区大小
DWORD nLength = 0;
nResult = WSAEnumProtocols(NULL, NULL, &nLength);
if (nResult != SOCKET_ERROR)
{
return;
}
if (WSAGetLastError() != WSAENOBUFS)
{
return;
}
WSAPROTOCOL_INFO* pProtocolInfo = (WSAPROTOCOL_INFO*)new BYTE[nLength];
//取适当地计算机协议信息
nResult = WSAEnumProtocols(NULL, pProtocolInfo, &nLength);
if (nResult == SOCKET_ERROR)
{
delete[] pProtocolInfo;
return;
}
for (int n = 0; n < nResult; n++)
{
m_ctrlList.AddString(pProtocolInfo[n].szProtocol);
}
delete[] pProtocolInfo;
//清理WinSock
WSACleanup();
---------------------------------------------------------------------------------------------------------------------
结果:
图 8 网络协议
3.2.6 IP统计信息
GetIpStatistics,函数功效:目前计算机IP统计信息。
其中包含各个具体信息数据,我们只需把她们显示出来就能够了。
-------------------------------------------------------------------------------------------------------具体代码:
m_ctrlList.ResetContent();
CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST1);
pListBox->ResetContent();
MIB_IPSTATS IPStats;
//取得IP协议统计信息
if (GetIpStatistics(&IPStats) != NO_ERROR)
{
return;
}
CString strText = _T("");
strText.Format(_T("接收数据包:%d"),
IPStats.dwInReceives);
pListBox->AddString(strText);
strText.Format(_T("接收标头错误:%d"),
IPStats.dwInHdrErrors);
pListBox->AddString(strText);
strText.Format(_T("接收地址错误:%d"),
IPStats.dwInAddrErrors);
pListBox->AddString(strText);
strText.Format(_T("转发数据报:%d"),
IPStats.dwForwDatagrams);
pListBox->AddString(strText);
strText.Format(_T("接收未知协议:%d"),
IPStats.dwInUnknownProtos);
pListBox->AddString(strText);
strText.Format(_T("丢弃接收数据包:%d"),
IPStats.dwInDiscards);
pListBox->AddString(strText);
strText.Format(_T("传送接收数据包:%d"),
IPStats.dwInDelivers);
pListBox->AddString(strText);
strText.Format(_T("输出请求:%d"),
IPStats.dwOutRequests);
pListBox->AddString(strText);
strText.Format(_T("路由丢弃:%d"),
IPStats.dwOutDiscards);
pListBox->AddString(strText);
strText.Format(_T("丢弃输出数据包:%d"),
IPStats.dwOutDiscards);
pListBox->AddString(strText);
strText.Format(_T("输出数据包无路由s:%d"),
IPStats.dwOutNoRoutes);
pListBox->AddString(strText);
strText.Format(_T("需要重新组合:%d"),
IPStats.dwReasmReqds);
pListBox->AddString(strText);
strText.Format(_T("重新组合成功:%d"),
IPStats.dwReasmOks);
pListBox->AddString(strText);
strText.Format(_T("重新组合失败:%d"),
IPStats.dwReasmFails);
pListBox->AddString(strText);
strText.Format(_T("数据报分段成功:%d"),
IPStats.dwFragOks);
pListBox->AddString(strText);
strText.Format(_T("数据报分段失败:%d"),
IPStats.dwFragFails);
pListBox->AddString(strText);
strText.Format(_T("分段已创建:%d"),
IPStats.dwFragCreates);
pListBox->AddString(strText);
-------------------------------------------------------------------------------------------------------结果:
图 9 IP统计信息
3.2.7 TCP统计信息
统计TCP连接信息GetTcpStatistics函数,和前面IP统计信息GetIpStatistics相同。
-------------------------------------------------------------------------------------------------------
具体代码:
m_ctrlList.ResetContent();
CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST1);
pListBox->ResetContent();
//MIB_TCPSTATS 包含本机上正运行TCP协议统计表
MIB_TCPSTATS TCPStats;
//取得TCP协议统计信息
if (GetTcpStatistics(&TCPStats) != NO_ERROR)
{
return;
}
CString strText = _T("");
strText.Format(_T("主动开放:%d"),
TCPStats.dwActiveOpens);
pListBox->AddString(strText);
strText.Format(_T("被动开放:%d"),
TCPStats.dwPassiveOpens);
pListBox->AddString(strText);
strText.Format(_T("失败连接尝试:%d"),
TCPStats.dwAttemptFails);
pListBox->AddString(strText);
strText.Format(_T("重置连接:%d"),
TCPStats.dwEstabResets);
pListBox->AddString(strText);
strText.Format(_T("目前连接:%d"),
TCPStats.dwCurrEstab);
pListBox->AddString(strText);
strText.Format(_T("接收分段:%d"),
TCPStats.dwInSegs);
pListBox->AddString(strText);
strText.Format(_T("发送分段:%d"),
TCPStats.dwOutSegs);
pListBox->AddString(strText);
strText.Format(_T("重新传输分段:%d"),
TCPStats.dwRetransSegs);
pListBox->AddString(strText);
结果:
图 10 TCP统计信息
3.2.8 修改当地网络信息设置
修改当地网络信息设置,具体为修改IP、DNS,使用system命令,调用命令提醒符,直接使用命令来达成修改目标,但只针对某一网络连接,此次课设针正确是笔记本电脑上带“WLAN” 这个网络连接。
此处分为两个按钮,分别是“设置自动获取IP”和“设置静态IP”,其中静态IP是提前设定好,用户无法修改。
在windows环境下,命令行程序为cmd.exe,是一个32位命令行程序,微软Windows系统基于Windows上命令解释程序,类似于微软DOS操作系统。输入部分命令,cmd.exe能够实施,比如输入shutdown -s就会在30秒后关机。总而言之,它很有用。
NetSH (Network Shell) 是windows系统本身提供功效强大网络配置命令行工具。
利用这些我们就能够实现功效了。
-------------------------------------------------------------------------------------------------------“设置自动获取IP”具体代码:
system("netsh interface ip set address WLAN dhcp");
system("netsh interface ip set dns WLAN dhcp");
-------------------------------------------------------------------------------------------------------
“设置静态IP”具体代码:
system("netsh interface ip set address WLAN static 10.1.2.90");
system("netsh interface ip set dns WLAN static 202.99.160.68");
------------------------------------------------------------------------------------------------------
结果:
点击按钮会弹出CMD框,然后实施命令。
点击“设置自动获取IP”时WLANIP属性:
图 11 IP属性_1
点击“设置静态IP”时WLANIP属性:
图 12 IP属性_2
3.2.9 时间模块
NTP(Network Time Protocol,网络时间协议)是用来使网络中各个计算机时间同时一个协议。它用途是把计算机时钟同时到世界协调时UTC,其精度在局域网内可达0.1ms,在互联网上绝大多数地方其精度能够达成1-50ms。
它能够使计算机对其服务器或时钟源(如石英钟,GPS等等)进行时间同时,它能够提供高正确度时间校正,而且能够使用加密确定方法来预防恶毒协议攻击。
为查看目前系统时间,也为了能对比修改以后时间,特意添加一个按钮来查看目前系统时间(只是目前系统时间,并非联网查看正确时间),
代码很简单:
CString str; //获取系统时间
CTime tm; tm = CTime::GetCurrentTime();
str = tm.Format("现在时间是%Y年%m月%d日 %X");
MessageBox(str, NULL, MB_OK);
能够选择连接服务器,使用Combo-box,能够选择预存有各个服务器,也能够自己输入一个服务器去尝试连接、修改时间。假如未连接服务器,那么自动修改按钮将无法被点击。
具体代码:
--------------------------------------“连接”按钮-------------------------------------------------
if (s != NULL) closesocket(s);
s = ::socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET){
MessageBox("初始化犯错");
exit(0);
}
UpdateData(true);
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(13);
//inet_addr()功效是将一个点分十进制IP转换成一个长整数型数(u_long类型),IP地址转化函数
servAddr.sin_addr.S_un.S_addr = inet_addr(m_combo);
m_state = "连接(" + m_combo + ")...";
UpdateData(false);
if (::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)
{
m_state = "连接失败!";
UpdateData(false);
return;
}
m_state = "连接成功!";
UpdateData(false);
m_button.EnableWindow(true);
//m_button2.EnableWindow(false);
-----------------------------------“自动修改”按钮----------------------------------------------
char ulTime[256];
int nRecv = ::recv(s, (char*)&ulTime, sizeof(ulTime), 0);
if (nRecv>0){
CString str, stra;
ulTime[nRecv] = '\0';
str = ulTime;
str = str.Right(44);
str.SetAt(2, '\0');
//SYSTEMTIME 包含年月日时
展开阅读全文