病毒库自动升级模拟设计文档.docx
《病毒库自动升级模拟设计文档.docx》由会员分享,可在线阅读,更多相关《病毒库自动升级模拟设计文档.docx(19页珍藏版)》请在冰豆网上搜索。
病毒库自动升级模拟设计文档
病毒库自动升级模拟实验报告
一、课程设计要求
A采用推送方式将最新病毒库数据发送到从服务器
Si采用推送方式将最新病毒库数据发送到客户机Cij
客户机Cij可以从Si接收数据,也可以从其他客户机接收数据
A,Si,Cij通信采用socket进行通信
系统使用UNIX/Linux+C实现
二、系统概要设计
1.主服务器概要设计
功能:
1)响应从服务器的请求
2)推送新病毒库至从服务器
3)日志记录
4)节点失效检测(针对从服务器)
5)人机交互
工作流程:
1)启动后在端口1上进行监听,响应从服务器的请求
2)利用端口2推送最新病毒库数据至与之连接的从服务器
3)节点失效检测采用心跳机制来检测从服务器的连接状况
4)人机交互模块等待系统管理员输入命令
5)各个模块每处理一次事务都会调用日志操作模块,将操作写入日志
从服务器列表内容
1)与从服务器进行命令通信的socket:
sockfd1
2)与从服务器传输文件使用的socket:
sockfd2
3)从服务器ID、IP地址、当前病毒库版本号
4)从服务器在线状态、监听的端口号1、端口号2
日志内容:
1)何时在端口1/2上进行监听
2)人机交互内容和结果
3)从服务器连接/断开的相关信息
4)主服务器推送病毒库的相关信息
人机交互内容:
1)更新病毒库
2)添加合法从服务器
3)添加合法客户机
4)查看从服务器/客户机的信息
5)删除从服务器/客户机
6)重新启动服务
7)退出程序
2.从服务器概要设计
功能:
1)在端口1上监听,响应客户机的请求
2)与主服务器进行通信
3)接收主服务器推送的最新病毒库数据
4)推送最新病毒库至在线的客户机
5)日志操作
6)节点失效检测(针对客户机)
7)人机交互
工作流程:
1)启动后连接主服务器
2)加载病毒库版本信息,向主服务器发送自身病毒库信息(进一步与主服务器通信)
3)在端口1上监听,等待客户机的连接请求,根据通信信息进一步行动
4)在端口2上监听,用于传输病毒库文件
5)节点失效检测采用心跳机制动态维护客户机列表
6)人机交互模块始终等待用户输入命令,执行命令
7)各模块处理一次事务后调用日志操作模块,将操作保存在日志中
客户机列表内容:
1)客户机的ID、IP地址、端口号1、端口号2
2)客户机上最新病毒库版本信息
3)客户机在线状况
人机交互内容
1)升级病毒库
2)显示本机病毒库版本信息
3)显示客户机信息
4)重启服务
5)退出程序
日志内容类似于主服务器的日志内容;
3.客户机设计
功能:
1)与主服务器通信,接收病毒库文件
2)为其他客户机提供病毒库文件
3)人机交互
4)日志操作
工作流程:
1)启动后连接从服务器(Si:
port1)
2)加载病毒库版本信息和ID,向从服务器发送信息(进一步工作由从服务器决定)
3)根据从服务器的命令,进行相关处理(包括接收病毒库文件、为其他客户机提供最新病毒库文件)
4)启动人机交互,始终等待用户输入命令,执行命令
5)处理事务后将操作保存在日志中
人机交互内容:
1)升级病毒库
2)显示本机病毒库版本
3)退出程序
三、系统详细设计
病毒库的版本号由主版本号和此版本号组成,类型是32位整型。
病毒库文件使用三个有关联的文件表示:
病毒库版本文件(versionfile)、病毒索引文件(indexfile)和病毒特征值文件(datafile)。
Ø病毒版本文件:
包含了各个版本的主版本号(majorv)、次版本号(minorv)、新添病毒位于索引文件中的开始位置(begin)、相对前一版本新添病毒的总数量(size)、已写入病毒库中的病毒的总数量(wsize)、该版本包含病毒的总数(total)等信息。
按块的形式读写。
Ø病毒索引文件:
包含了某一病毒的ID、病毒特征值在病毒特征文件的开始位置、病毒特征值的大小的等信息。
按块的形式读写。
Ø病毒库特征值文件:
由所有病毒特征值组成的文件。
按字节的形式读写。
三个文件的内容和关联如下图:
将上面三个文件中的内容读入内存时,采用链表存储,链表的结构如下图:
保存病毒信息的数据结构,通过读取indexfile和datafile文件创建该链表
typedefstructvirus{
u32ID;//病毒编号
u32begin;//病毒特征值在文件中的开始位置
u32size;//病毒特征值的大小
char*data;//病毒特征值的内容
structvirus*next;
}*VirusList;
保存病毒库信息的数据结构,读取versionfile和VirusList链表创建该链表
typedefstructversion{//保存病毒库信息
u32majorv;//主版本号
u32minorv;//次版本号
u32begin;//该版本的病毒库新添的病毒的索引起始位置
u32size;//该版本的病毒库新添的病毒总数目
u32wsize;//该版本的病毒库已更新的病毒数目(对于主服务器无意义)
u32total;//该版本包含的所有病毒数目
structvirus*vhead;//该版本新添的病毒信息
structversion*next;
}*VersionList;
读取versionfile文件:
structversioninfo{
u32majorv;//主版本号
u32minorv;//次版本号
u32begin;//该版本病毒库新添的病毒的索引起始位置
u32size;//该版本的病毒库新添的病毒总数
u32wsize;//该版本已写入的新添的病毒数目
u32total;//该版本已包含的所有病毒数目
};
读取indexfile文件:
structindexinfo{
u32ID;//病毒ID
u32begin;//病毒特征值在病毒数据文件中的开始位置
u32size;//病毒特征值的大小
}
上面三个文件和相关的数据结构被主服务器、从服务器和客户机程序共同拥有,并且内容类似,操作方法相同。
主服务器使用的私有文件有:
configure,versionfile,indexfile,datafile,slaveserverfile。
configure文件是主服务器配置文件,主要包括两个监听端口号:
端口1用于与从服务器进行命令通信,端口2用于推送文件。
versionfile,indexfile,datafile三个文件是病毒库的相关文件。
slaveserverfile保存了所有合法的从服务器的信息,用于验证从服务器的身份,主要包括:
从服务器的ID、IP地址、病毒库主版本号、病毒库次版本号等信息。
configure文件和slaveserverfile都是以块的形式读写,读写这两个文件的数据结构如下:
structmsconfiginfo{//读取configure文件
u32port1;
u32port2;
}
structslaveserverinfo{//读取slaveserverfile文件
u32ID;//从服务器的ID
charip[18];//从服务器的IP地址
u32majorv;//病毒库主版本号
u32minorv;//病毒库次版本号
}
主服务器运行是动态维护从服务器列表,主要包括与从服务器通信使用的socket值、从服务器的ID、IP地址、病毒库主版本号、病毒库次版本号、连接状态等信息。
表示从服务器列表的数据结构为:
typedefstructsservernode{
intsockfd1;//进行控制命令通信使用的socket值
intsockfd2;//推送文件使用的socket值
u32ID;//从服务器ID
charip[18];//从服务器的IP地址
u32majorv;//从服务器病毒库主版本号
u32minorv;//从服务器病毒库次版本号
unsignedcharstate;//从服务器连接状态
structsservernode*next;
}*SserverList;
从服务器使用的私有文件有:
configure,versionfile,indexfile,datafile。
configure文件是从服务器使用的配置文件,其他文件是保存病毒库的信息。
configure文件的主要内容有:
从服务器ID、主服务器的IP地址、主服务器的端口号1、主服务器的端口号2、端口号1、端口号2。
读取该文件使用的数据结构如下:
structssconfiginfo{
u32ID;//从服务器的ID
charsip[18];//主服务器的IP地址
u32serport1;//主服务器的端口号1
u32serport2;//主服务器的端口号2
u32port1;//自身使用的端口号1
u32port2;//自身使用的端口号2
}
从服务器动态维护一张客户机列表,主要包括客户机的ID、通信使用的socket值、IP地址、客户机病毒库主版本号、客户机病毒库次版本号、客户机提供文件服务器使用的两个端口号(一个用于控制,一个用于传输文件),列表的数据结构如下:
typedefstructclientnode{
u32ID;//客户机的ID
intsockfd1;//与客户机进行命令通信使用的socket值
intsockfd2;//推送文件至客户机使用的socket值
charip[18];//客户机的IP地址
u32majorv,minorv;//客户机上病毒库主版本号和次版本号
u32port1,port2;//客户机文件服务器的两个端口号
unsignedcharstate;//客户机连接状态
structclientnode*next;
}*ClientList;
在系统中,所有合法的从服务器的信息存储在slaveserverfile中,由主服务器进行维护;所有合法的客户机的信息存储在userinfo文件中,由主服务器和从服务器共同维护,主服务器对其具有读写权限,从服务器对其仅有读权限。
对于大型系统,用户的信息都被存储在数据库中,多个程序同时访问数据库时,数据库系统可以对并发访问进行处理。
但是本系统使用userinfo文件代替数据库,可能会出现读写不一致问题,对于这一问题可使用一个额外的程序来控制多个程序对该文件的并发访问。
处于简约性,这里直接忽略读写不一致问题,不使用额外的程序控制。
userinfo文件的主要内容有:
客户机的序列号(即ID)、客户名称、客户申请序列号的时间、客户机序列号到期时间等信息,读写该文件使用的数据结构如下:
structuserinfo{
u32ID;//客户机的序列号
charuname[64];//客户名称
charubtime[16];//序列号申请时间
charuetime[16];//序列号到期时间
}
userinfo是一个全局文件,而每个从服务器会在本地保存一个客户机信息缓存文件,用于保存于该从服务器常通信的客户机的信息。
当从服务器验证客户机身份时,从服务器先从缓存文件中查找客户机的信息,当查找不到时,再查找全局文件userinfo,这样便可提高效率。
缓存文件的名称为tmpuserinfo,使用structuserinfo数据结构进行操作。
客户机使用的私有文件有:
configure,versionfile,indexfile,datafile,configure是其配置文件,其他文件则是病毒库相关文件。
configure文件中主要包括客户机的ID、从服务器IP地址、从服务器使用的端口号1、从服务器使用的端口号2、自身的端口号1、端口号2。
读写该文件使用的数据结构如下:
structcconfiginfo{
u32ID;//客户机ID
charsip[18];//从服务器IP地址
u32serport1,serport2;//从服务器使用的两个端口号
u32port1,port2;//自身提供文件服务器使用的两个端口号
}
1.主服务器详细设计
主服务器A处理流程:
1.读取病毒库版本文件(versionfile),创建病毒库信息链表,表中只有版本信息,无病毒信息;
2.读取从服务器信息文件(slaveserverfile),创建从服务器列表,其中连接状态为0,表示未连接,sockfd1和sockfd2全为0,表示没有进行网络连接;
3.初始化日志操作模块;
4.启动人机交互线程;
5.启动节点失效检测线程,检测从服务器的连接状况;
6.读取配置文件,获取两个端口号;
7.初始化socket,在端口1上进行监听
8.等待从服务器的连接,连接并通过身份验证后启动一个线程专用于接收从服务器的信息;
9.步骤8出错后,记录日志;
10.等待人机交互线程的终止;
人机交互模块设计:
1.等待系统管理员输入命令:
commandparam
2.解析命令:
command={show,adds,addc,exit,drop,update}
3.执行命令:
命令不是exit则执行4,如果是exit直接退出
4.输出命令执行结果
5.返回步骤1
人机交互使用的命令:
1)显示命令show
showslaveservers[ID]显示从服务器的信息
showclients[ID]显示客户机的信息
showversion显示本机的病毒库版本信息
2)添加从服务器命令adds
addsipaddrxxx.xxx.xxx.xxx返回新添从服务器的序列号(即ID)
3)添加客户机命令addc
addcubtime2010-01-10uetime2013-01-01返回新添客户机的序列号
4)删除从服务器和客户机命令drop
dropslaveserverIDxxxx
dropuserIDxxxx
5)更新病毒库命令update
update更新本机的病毒库信息
updateall更新本机和所有从服务器的病毒库信息
6)退出程序命令exit
exit先进行清理工作,再退出程序。
失效检测模块设计:
动态维护从服务器链表,只对其进行读操作
1.遍历整个链表,向state为1的从服务器发送心跳包;
2.等待T秒钟,执行1
接收从服务器信息线程:
传递的参数:
符合条件的从服务器对应的链表节点指针,即sserver*ptr
流程:
1.提取参数的信息(sockfd1,state,IP地址,port1,port2,majorv,minorv,wsize)
2.等待接收从服务器的信息{}
3.信息有效,进行相关处理并给与应答,返回2,否则说明执行4
4.修改ptr->state=0,
2.从服务器(与主服务器有关部分)详细设计
主流程:
1.读取病毒库版本文件,创建病毒库信息链表(只有版本信息,无病毒信息)
2.读取配置文件,获取服务器的相关信息和自身的相关信息(端口号)
3.连接服务器{记下socket值},发送自身信息
4.身份验证成功后启动与主服务器通信线程,验证失败要求输入序列号(ID),再次验证,直至成功启动“与主服务器通信”线程或超过三次而退出程序
5.初始化日志操作模块
6.启动人机交互模块
7.启动失效检测模块(针对客户进的失效检测)
8.初始化socket,在端口1上监听,等待客户机的连接
9.接受客户机的连接请求,等待接收客户机发来的身份信息
10.对客户机的身份信息进行验证
11.如果验证成功,为之启动一个“与客户机通信线程”,否则返回9
12.步骤9出错,记录日志
13.等待人机交互线程的终止
待详细设计的步骤有4、6、7、11中的线程。
“与主服务器通信”线程的设计:
1)等待接收数据
2)分析数据:
推送最新病毒库或其他信息(心跳包等)分类处理
3)如果是推送最新病毒库,则还需启动另一个线程“接收最新病毒库”线程{连接主服务器的端口2,等待接收病毒文件片段,先缓存再给予应答,当缓存一定数量后,按病毒文件片段的升序方式写入文件……}
4)如果是其他信息,给与相应应答。
3.从服务器详细设计(与客户端有关的部分)
(1)P2P设计与实现
P2P设计能够减轻服务器的负载,从服务器维护客户端链表,当有客户端请求更新时候,先查看客户端是否为空,如果为空服务器自身更新,否则将链表中IP传给客户端。
详细流程如下:
1.客户端连接服务器,服务器判断其版本是否为最新,如果最新加入到客户端链表中。
否则进入2.
2.判断客户端链表是否为空,如果为空,服务器自身更新客户端病毒库文件
如果客户端链表不为空,则从链表的第一个位置上得到在线且有最新版本的客户端IP地址,同时服务器计算病毒库文件偏移量,和IP一同发送给待更新的客户端。
3.客户端得到IP后与此IP建立连接,并进行传输病毒文件。
4.如果传输成功,向服务器发送成功报告,并加入到客户端链表中。
如果传输失败,则重复步骤2.
(2)断点续传设计与实现
1在客户端配置文件中读取offset值,如果为0则表示上次更新成功,否则上次更新失败,且上次已经更新了offset个字节。
2.客户端将这个值与版本信息一同发送给服务器。
服务器根据版本和offset值,计算需要发送的病毒库文件总的偏移量。
3.如果是P2P方式传输,则把这个总的偏移量发给待更新的客户端,然后此客户端再把这个偏移量发送给P2P的服务方,之后开始传输。
如果是服务器自身传输则直接发送病毒文件。
4.如果更新成功,修改配置文件中offset值为0且更新配置文件中的版本号。
如果更新失败,将已经传输的字节数写入到配置文件offset中。
(3)从服务器与客户端有关的工作流程:
1.验证客户端的ID如果合法继续,否则推出线程
2.接收客户端的命令,根据不同的命令进行不同的服务
3.如果命令为UPDATE:
检查客户端的版本号是否最新,如果是最新版本,则加入到客户端在线链表中,如果不是最新的且客户端链表中为空则服务器向客户端更新病毒库文件,如果不是最新且客户端链表中不为空,则进行P2P传输。
4.如果命令为QIUT:
如果此客户端在客户端链表中,则从链表中删除该客户端信息,释放资源,写入日志。
否则释放资源,写入日志。
主要数据结构:
1.拥有最新版本的客户端在线链表数据结构,主要保存用户的ID,套接字描述符,ip地址,端口号,版本信息。
Typedefstructclient_node
{
unsignedintclient_id;
intsc;
charclient_ip[20];
unsignedintclient_port;
charversion[10];
structclient_node*next;
}client_online_list;
2.用户的ID信息链表数据结构,主要是用于验证是否是合法用户。
Typedefstructclient_idnode
{
unsignedintclient_id;
structclient_idnode*next;
}client_idvalue;
主要函数:
1.voidgetmostnewversion(structssinfossi,char*mostnewversion)
此函数主要是得到最新的版本号,用于和客户端发送来的版本比较,从而判断是否需要更新。
2.intGetVersionData(constchar*versionold,constchar*versionnew,char*buf,constintoffset)
此函数根据传入的旧的版本号,最新版本号从而得到新版本和旧版本之间的偏移量从而实现增量更新,并将数据存入到buf中。
3.intGetVersionOffset(constchar*_ersion)
此函数根据传入的旧版本的信息得到从病毒库文件起始位置至某个旧版本的总的偏移量。
4.insert_client_online(client_online_head,client_id,client_ip,client_port,version,sc);
当客户端的病毒库版本为最新时,将其插入到拥有最新版本客户端在线的链表中,用于P2P传输。
4.客户端详细设计
(1)客户端工作流程:
1.读取配置文件中服务器IP,PORT。
版本号,偏移量等信息
2.建立与服务器连接线程,建立人机交互线程
3.发送客户端ID。
如果验证通过继续,否则退出程序
4.发送病毒库版本号和偏移量,如果是服务器自己更新病毒库文件则准备接收文件。
如果服务器发送来其他客户端的IP,则建立此客户端连接,形成P2P传输。
5.根据人机交互线程的命令。
提供服务,如果人机交互命令为UPDATE,则调用更新函数更新病毒库,之后同步骤4.如果人机交互命令为QIUT,发送退出命令,并退出程序。
主要函数:
1.void*as_server(void*data)
此函数为一个线程,用于P2P中服务器一方,向其他客户端提供病毒库文件传输服务。
2.void*command_input(void*data)
此函数用于人机交互线程,根据输入的不同命令,提供不同的服务,比如手动更新病毒库,查看版本号等。
3.void*as_client(void*data)
此函数用于P2P中的客户端线程,与从服务器通讯或者与P2P中服务器通讯。
3.intRecvVirusToTempvir(intsc)
此函数实现将接收到的病毒库文件暂时存放到文件temp_virus中,目的是为了传输完成后一次性写入病毒库文件。
intCpyTempvirTovirus()
此函数将病毒库临时文件复制到病毒库文件中
intcreate_recv(charip_recv[],charoffset[])
此函数用于建立P2P服务器的连接,从而从其他客户端得到病毒库文件。
四、系统测试
从服务器与客户端联合测试:
1.客户端ID371421(病毒库版本最新)登录到服务器后显示如下:
*****************menu***********************
0-----------quittheclient
1-----------checktheversion
*********************************************
CLIENTSERVERstart