南京邮电大学
课程设计II 报告
( 2014 / 2015 学年 第 一 学期)
题目:
专 业 信息安全 学 生 姓 名 赢猛 班 级 学 号 Q11010330 指 导 教 师 孙国梓 指 导 单 位 计算机学院信息安全系 日 期 2015年1月7日
-
-
网络服务监测系统
一、 课题内容和要求
针对局域网内的网络服务,远程监控指定网络服务(Web/FTP/SMTP 等) 的服务器,当相应网络服务或服务器停止时,能够迅速发现并实现邮件或短信报警。需要实现基本配置,能够对相关的过程进行记录和统计管理,方便查询。 系统运行和开发环境: 1) Windows 操作系统下的 Windows 网络编程(VC6 或更高版本、 JAVA、 Python) 2) 应用多线程技术和数据库基本操作
二、需求分析
--3--
总体框架图:
本课题内容可分为两个大模块:
1.数据库操作模块:
1) 将监测的记录写入数据库中,并返回操作代码
2) 根据条件,对数据库中的数据进行条件查询,并输出查询到的记录 3) 根据条件,对数据库中的数据进行条件删除,并返回操作代码
2.服务器服务监测模块:
1) 根据网址或ip 地址对服务器服务开启情况进行监测,如果服务关闭,则进
一 步判断服务器有没有关机
2) 如果服务关闭或服务器关机,则发送邮件至指定的邮箱报警
三、概要设计
主要用到数据库、网络编程和MFC 编程三种技术编程内容;
1. 数据库:(1)向数据库中插入记录,构造数据库命令”insert into info
values
(‘url’,’type’,’time’,’status’)”;,
使
用
sqlite3_exec()执行命令
(2)按条件从数据库中读取记录,构造数据库命令”select
*from intl where URL = ‘url’”;,使用sqlite3_exec()执行命令,数据库返回记录放在缓冲区中,送至用户界面显示
--4--
(3)按条件删除数据库中记录,构造数据库命令”delete from
info where URL = ‘url’”;, 使用sqlite3_exec()执行命令,
2. 网络编程:(1)使用socket connect连接,
(2)使用ping 方式探测主机,
(3)MFC 编程,对界面进行编写,设置相应的全局变量,用
于存放数据
在程序中使用的数据均存储在变量中,最终写入数据库,数据库的存储形式为: 网址 服务 监测时间 服务运行状态
四、详细设计
1. 数据库操作: (1)打开数据库:
--5--
sqlite3* OpenSQL()
//打开一个固定的存储服务器消息的sqlite3数据库 {
int result = -1; sqlite3 *db = NULL;
}
result = sqlite3_open("info.db",&db);//使用数据库包含的方法打开数
//据库文件
return db;
(2)将记录写入数据库:
//写数据库
int WriteInfo(char* url, char* type, char* Status, sqlite3 *db)
//url是查询网址,type 是服务器类型,系统时间在函数内部获得,status //是服务器状态,PS. 需要获得sqlite3数据库实例 {
…
//调用库函数执行insert
result = sqlite3_exec(db, sql, NULL, NULL, &err);
}
…
//外部使用注意关闭数据库 return 0;
(3)对数据库按条件查询记录:
/数据库查询函数 char* Query(char* URL) {
//根据获得网址信息,打开数据库查询网址的服务器信息,并存到buffer
内作为返回值返回
--6--
db = OpenSQL();
//打开数据库 sqlite3_get_table执行查询语句获得一个N 维char 数
组存放查询结果
res = sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &err);
if(((nrow+1)*ncolumn)
>
(allnum
*
ncolumn))
start
=
…
(nrow+1)*ncolumn - (allnum * ncolumn);
for(i = start; i
//将查询结果写入缓存区内,一行一条结果 …
} }
char* QueryWithType(char* URL, char* type) {
//根据获得网址信息,打开数据库查询网址的服务器信息,并存到buffer 内作为返回值返回
//打开数据库 sqlite3_get_table执行查询语句获得一个N 维char 数…
db = OpenSQL(); ...
return buffer;
组存放查询结果
res = sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &err);
--7--
…
}
for(i = start; i
{
//将查询结果写入缓存区内,一行一条结果 …
} }
(4)按照条件删除数据库中对应记录:
int Delete(char *URL) {
db = OpenSQL();
//执行删除
res = sqlite3_exec(db, sql, NULL, NULL, &err); char sql[200] = "delete from info where URL = "; …
//构造删除语句 …
}
2. 探测服务模块: //探测函数
bool scan() { while(1) {
--8--
… return 0;
//result:0表示连接成功 //1表示连接失败
//2表示本地socket 创建失败(暂时不启用) WORD version = MAKEWORD(1,1); WSADATA data;
int result = WSAStartup(version, &data); if ( 0 != result ) { }
//参数设置 …
//设置socket SOCKET theSock;
theSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == theSock) { }
WSACleanup(); return false; return false;
if(ioctlsocket(theSock,FIONBIO, &ul)!=0)//设置connect 为非阻塞模式 { }
…
if(-1 == connect(theSock, (sockaddr*)&ServerAddress, sizeof(sockaddr))) {
tm.tv_sec = 1; //等待超时 1 s tm.tv_usec = 0; FD_ZERO(&set);
--9--
&len);
FD_SET(theSock, &set);
if(0 != select(theSock+1, NULL, &set, NULL, &tm)) {
getsockopt(theSock, SOL_SOCKET, SO_ERROR, (char*)&error,
}
if(error == 0)
result = 0;
else
result = 1;
} else
result = 1;
else
result=0;
if ( 0 == result ) { // AfxMessageBox("open"); }else{
// AfxMessageBox("close"); }
char* status; switch(result) { }
if(0 != result) {
Send(p, ServiceType, status);//连接失败,发送邮件
--10--
result=ping(p);
…
}
} } sqlite3 *db; db = OpenSQL(); WriteInfo(p, ServiceType, status, db); //AfxMessageBox(status); Close(db); WSACleanup(); int to = _ttoi(timeout); Sleep(to*1000);
//ping探测服务器
int ping(char *p)
{
…
/* 设置选项, 接收和发送的超时时间 */
timeout = user_opt_g.timeout;
...
/* 发送请求并接收响应 */
icmp_make_data(icmp_data, data_size, seq_no++);
send_len = sendto(icmp_soc, icmp_data, data_size, 0,
(struct sockaddr*)&dest_addr, sizeof(dest_addr));
result = icmp_process_reply(icmp_soc);
free(icmp_data);
closesocket(icmp_soc);
WSACleanup();
3. 发送邮件函数:
//**************
//发送邮件函数
//************
void Send(char *url,char *type,char*stau)
{
char *EmailTo=(LPSTR)(LPCTSTR)MailAddress;//发给的邮箱
char EmailContents[1000];
char info[100];
sprintf(info,"Subject: %s\r\n\r\n","NOTICE!!!");
//AfxMessageBox(info);
sprintf(EmailContents,"From: \r\n" "To:
\r\n" "%s" "%s\n" "%s\n" "%s\n",EmailTo,info,url,type,stau);
}
、五、测试数据及其结果分析
1. 设计结果:
(1)监控开始:
SendMail(EmailTo,EmailContents);
图1 监控开始
(2)查询www.baidu.com 的Web 服务监控20条记录:
图2 查询www.baidu.com 的Web 服务监控20条记录
(3)查询www.baidu.com 的FTP 服务监控20条记录:
图3 查询www.baidu.com 的FTP 服务监控20条记录
(4)查询www.baidu.com 的SMTP 服务监控20条记录:
图4 查询www.baidu.com 的SMTP 服务监控20条记录
(5)查询所有数据:
图5 查询所有数据
(6)删除www.baidu.com 的监控记录:
图6 删除www.baidu.com 的监控记录
(7)清除所有监控记录:
图7 清除所有监控记录
(8)邮件警告:
图8 邮件警告
2. 性能分析。
(1)数据库读写删:能实时进行,能立即将监测记录存入数据库中,由于数据库更新操作,在存入后不能立即读出,需1s 左右时间才能读到用户界面
(2)服务监测模块:服务正常运行时,可以实时监测到并写入数据库;当服务关闭或服务器关闭,因为需要对网络超时进行设定,所以需要1~2s的延迟,然后发送邮件警告,并写入数据库
(3)用户界面:可以实时对用户输入和点击进行反应,
六、调试过程中的问题
1. 数据库模块:
当将数据库中的数据直接通过缓存在用户界面显示时,如果数据库记录较多,会造成内存溢出,程序中断,
解决方案:将数据库读出的数据取最后更新的记录用来发送给缓存,
2. 服务探测模块:
(1)使用connect 阻塞模式连接时,当服务关闭,因为等待返回信息,程序需要等待75s 后才能进行超时处理,严重影响实时效果
解决方案:将connect 设置为非阻塞模式,并将超时时间设置,使程序能较为及时响应处理
(2)探测模块需要在后台一直运行
解决方案:开启另外一个线程用于探测模块
(3)connect 连接方式只能判断服务开启与关闭,不能判断服务关闭时服务器是否关机
解决方案:使用ping 服务器方式监测服务器是否关闭
算法改进:(1)能在打开监控线程之后,关闭监控线程
(2)可以对多个服务器进行同时探测 (3. )可以对同一服务器的不同服务进行探测 (4)对于记录的处理提供更多的处理接口
七、课程设计总结
在本次课程设计过程中,对于网络编程有了更好的使用,同时通过对ping 的学习使用,网络编程的能力有了更好的提高;通过数据库和MFC 界面的编程,对数据库的使用和MFC 界面编程有了很好的学习和初步的使用能力;
在本次设计中,因为知识储备的限制,在刚开始时只能对监测情况作初步处理,不能较好地区分出各种情况,经过进一步的学习,才能对不同情况进行单独处理;
同时,本次课程设计也是我们团队分工合作的成果;通过每个人的共同努力,将各自学习的成果共享,使每个人都得到了学习;通过互相讨论,检查问题,也很好的纠正了每个人的错误,也是让课程设计任务能很好完成的关键。
南京邮电大学
课程设计II 报告
( 2014 / 2015 学年 第 一 学期)
题目:
专 业 信息安全 学 生 姓 名 赢猛 班 级 学 号 Q11010330 指 导 教 师 孙国梓 指 导 单 位 计算机学院信息安全系 日 期 2015年1月7日
-
-
网络服务监测系统
一、 课题内容和要求
针对局域网内的网络服务,远程监控指定网络服务(Web/FTP/SMTP 等) 的服务器,当相应网络服务或服务器停止时,能够迅速发现并实现邮件或短信报警。需要实现基本配置,能够对相关的过程进行记录和统计管理,方便查询。 系统运行和开发环境: 1) Windows 操作系统下的 Windows 网络编程(VC6 或更高版本、 JAVA、 Python) 2) 应用多线程技术和数据库基本操作
二、需求分析
--3--
总体框架图:
本课题内容可分为两个大模块:
1.数据库操作模块:
1) 将监测的记录写入数据库中,并返回操作代码
2) 根据条件,对数据库中的数据进行条件查询,并输出查询到的记录 3) 根据条件,对数据库中的数据进行条件删除,并返回操作代码
2.服务器服务监测模块:
1) 根据网址或ip 地址对服务器服务开启情况进行监测,如果服务关闭,则进
一 步判断服务器有没有关机
2) 如果服务关闭或服务器关机,则发送邮件至指定的邮箱报警
三、概要设计
主要用到数据库、网络编程和MFC 编程三种技术编程内容;
1. 数据库:(1)向数据库中插入记录,构造数据库命令”insert into info
values
(‘url’,’type’,’time’,’status’)”;,
使
用
sqlite3_exec()执行命令
(2)按条件从数据库中读取记录,构造数据库命令”select
*from intl where URL = ‘url’”;,使用sqlite3_exec()执行命令,数据库返回记录放在缓冲区中,送至用户界面显示
--4--
(3)按条件删除数据库中记录,构造数据库命令”delete from
info where URL = ‘url’”;, 使用sqlite3_exec()执行命令,
2. 网络编程:(1)使用socket connect连接,
(2)使用ping 方式探测主机,
(3)MFC 编程,对界面进行编写,设置相应的全局变量,用
于存放数据
在程序中使用的数据均存储在变量中,最终写入数据库,数据库的存储形式为: 网址 服务 监测时间 服务运行状态
四、详细设计
1. 数据库操作: (1)打开数据库:
--5--
sqlite3* OpenSQL()
//打开一个固定的存储服务器消息的sqlite3数据库 {
int result = -1; sqlite3 *db = NULL;
}
result = sqlite3_open("info.db",&db);//使用数据库包含的方法打开数
//据库文件
return db;
(2)将记录写入数据库:
//写数据库
int WriteInfo(char* url, char* type, char* Status, sqlite3 *db)
//url是查询网址,type 是服务器类型,系统时间在函数内部获得,status //是服务器状态,PS. 需要获得sqlite3数据库实例 {
…
//调用库函数执行insert
result = sqlite3_exec(db, sql, NULL, NULL, &err);
}
…
//外部使用注意关闭数据库 return 0;
(3)对数据库按条件查询记录:
/数据库查询函数 char* Query(char* URL) {
//根据获得网址信息,打开数据库查询网址的服务器信息,并存到buffer
内作为返回值返回
--6--
db = OpenSQL();
//打开数据库 sqlite3_get_table执行查询语句获得一个N 维char 数
组存放查询结果
res = sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &err);
if(((nrow+1)*ncolumn)
>
(allnum
*
ncolumn))
start
=
…
(nrow+1)*ncolumn - (allnum * ncolumn);
for(i = start; i
//将查询结果写入缓存区内,一行一条结果 …
} }
char* QueryWithType(char* URL, char* type) {
//根据获得网址信息,打开数据库查询网址的服务器信息,并存到buffer 内作为返回值返回
//打开数据库 sqlite3_get_table执行查询语句获得一个N 维char 数…
db = OpenSQL(); ...
return buffer;
组存放查询结果
res = sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &err);
--7--
…
}
for(i = start; i
{
//将查询结果写入缓存区内,一行一条结果 …
} }
(4)按照条件删除数据库中对应记录:
int Delete(char *URL) {
db = OpenSQL();
//执行删除
res = sqlite3_exec(db, sql, NULL, NULL, &err); char sql[200] = "delete from info where URL = "; …
//构造删除语句 …
}
2. 探测服务模块: //探测函数
bool scan() { while(1) {
--8--
… return 0;
//result:0表示连接成功 //1表示连接失败
//2表示本地socket 创建失败(暂时不启用) WORD version = MAKEWORD(1,1); WSADATA data;
int result = WSAStartup(version, &data); if ( 0 != result ) { }
//参数设置 …
//设置socket SOCKET theSock;
theSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == theSock) { }
WSACleanup(); return false; return false;
if(ioctlsocket(theSock,FIONBIO, &ul)!=0)//设置connect 为非阻塞模式 { }
…
if(-1 == connect(theSock, (sockaddr*)&ServerAddress, sizeof(sockaddr))) {
tm.tv_sec = 1; //等待超时 1 s tm.tv_usec = 0; FD_ZERO(&set);
--9--
&len);
FD_SET(theSock, &set);
if(0 != select(theSock+1, NULL, &set, NULL, &tm)) {
getsockopt(theSock, SOL_SOCKET, SO_ERROR, (char*)&error,
}
if(error == 0)
result = 0;
else
result = 1;
} else
result = 1;
else
result=0;
if ( 0 == result ) { // AfxMessageBox("open"); }else{
// AfxMessageBox("close"); }
char* status; switch(result) { }
if(0 != result) {
Send(p, ServiceType, status);//连接失败,发送邮件
--10--
result=ping(p);
…
}
} } sqlite3 *db; db = OpenSQL(); WriteInfo(p, ServiceType, status, db); //AfxMessageBox(status); Close(db); WSACleanup(); int to = _ttoi(timeout); Sleep(to*1000);
//ping探测服务器
int ping(char *p)
{
…
/* 设置选项, 接收和发送的超时时间 */
timeout = user_opt_g.timeout;
...
/* 发送请求并接收响应 */
icmp_make_data(icmp_data, data_size, seq_no++);
send_len = sendto(icmp_soc, icmp_data, data_size, 0,
(struct sockaddr*)&dest_addr, sizeof(dest_addr));
result = icmp_process_reply(icmp_soc);
free(icmp_data);
closesocket(icmp_soc);
WSACleanup();
3. 发送邮件函数:
//**************
//发送邮件函数
//************
void Send(char *url,char *type,char*stau)
{
char *EmailTo=(LPSTR)(LPCTSTR)MailAddress;//发给的邮箱
char EmailContents[1000];
char info[100];
sprintf(info,"Subject: %s\r\n\r\n","NOTICE!!!");
//AfxMessageBox(info);
sprintf(EmailContents,"From: \r\n" "To:
\r\n" "%s" "%s\n" "%s\n" "%s\n",EmailTo,info,url,type,stau);
}
、五、测试数据及其结果分析
1. 设计结果:
(1)监控开始:
SendMail(EmailTo,EmailContents);
图1 监控开始
(2)查询www.baidu.com 的Web 服务监控20条记录:
图2 查询www.baidu.com 的Web 服务监控20条记录
(3)查询www.baidu.com 的FTP 服务监控20条记录:
图3 查询www.baidu.com 的FTP 服务监控20条记录
(4)查询www.baidu.com 的SMTP 服务监控20条记录:
图4 查询www.baidu.com 的SMTP 服务监控20条记录
(5)查询所有数据:
图5 查询所有数据
(6)删除www.baidu.com 的监控记录:
图6 删除www.baidu.com 的监控记录
(7)清除所有监控记录:
图7 清除所有监控记录
(8)邮件警告:
图8 邮件警告
2. 性能分析。
(1)数据库读写删:能实时进行,能立即将监测记录存入数据库中,由于数据库更新操作,在存入后不能立即读出,需1s 左右时间才能读到用户界面
(2)服务监测模块:服务正常运行时,可以实时监测到并写入数据库;当服务关闭或服务器关闭,因为需要对网络超时进行设定,所以需要1~2s的延迟,然后发送邮件警告,并写入数据库
(3)用户界面:可以实时对用户输入和点击进行反应,
六、调试过程中的问题
1. 数据库模块:
当将数据库中的数据直接通过缓存在用户界面显示时,如果数据库记录较多,会造成内存溢出,程序中断,
解决方案:将数据库读出的数据取最后更新的记录用来发送给缓存,
2. 服务探测模块:
(1)使用connect 阻塞模式连接时,当服务关闭,因为等待返回信息,程序需要等待75s 后才能进行超时处理,严重影响实时效果
解决方案:将connect 设置为非阻塞模式,并将超时时间设置,使程序能较为及时响应处理
(2)探测模块需要在后台一直运行
解决方案:开启另外一个线程用于探测模块
(3)connect 连接方式只能判断服务开启与关闭,不能判断服务关闭时服务器是否关机
解决方案:使用ping 服务器方式监测服务器是否关闭
算法改进:(1)能在打开监控线程之后,关闭监控线程
(2)可以对多个服务器进行同时探测 (3. )可以对同一服务器的不同服务进行探测 (4)对于记录的处理提供更多的处理接口
七、课程设计总结
在本次课程设计过程中,对于网络编程有了更好的使用,同时通过对ping 的学习使用,网络编程的能力有了更好的提高;通过数据库和MFC 界面的编程,对数据库的使用和MFC 界面编程有了很好的学习和初步的使用能力;
在本次设计中,因为知识储备的限制,在刚开始时只能对监测情况作初步处理,不能较好地区分出各种情况,经过进一步的学习,才能对不同情况进行单独处理;
同时,本次课程设计也是我们团队分工合作的成果;通过每个人的共同努力,将各自学习的成果共享,使每个人都得到了学习;通过互相讨论,检查问题,也很好的纠正了每个人的错误,也是让课程设计任务能很好完成的关键。