1.系统概要设计
MiniQQ的体系结构(如图1.1所示),包括服务器端和客户端;服务器端又包括验证用户登录、保存用户信息、显示在线用户、转发用户信息、保存聊天记录、转发文本消息;客户端包括用户登录,文字聊天、截屏传输、文件传输、软键盘、视频聊天、查看聊天记录等功能模块。
2.详细设计
2.1 验证用户登录基本思想
首先,服务端收到客户端发送过来的账号密码,其会和数据库中的数据进行比较,如果id和pd比较都相等,那么服务器端将会使icode等于0.,然后发送到客户端,如果id和pd其中有一个不相等或者都不相等,那么就会继续比较数据库中的senderid与id是否相同,如果相同就令mark=1,接着再令icode=0,然后发送到客户端;如果不相同就令mark=0,然后将接收到的id和pd插入数据库,然后令icode=2,然后发送到客户端;然后结束。
case
NewParticipant:
{
in>>sport>>senderID>>pd>>senderipAddress;
int regiser;
regiser=0;
/********judge id and pwd*******/
QSqlDatabase
db1=QSqlDatabase::database("connection1");//连接数据库1
QSqlQuery query1(db1);
QString
select_all_data="select * from QQchat";
query1.prepare(select_all_data);
query1.exec();
while(query1.next())
{
//qDebug()<<"running";
qDebug()<
2.2 记录用户信息的基本思想
因为客户端登录的机器不断改变,IP地址不是固定的,所以客户端每次登录的时候,服务端都会记录当前客户端的信息。服务端采用建立链表的方式来记录当前客户端信息。客户端登录成功以后,服务器会把客户端的账号信息、IP地址信息、对应的端口号信息加入到链表中记录下来
下面是链表建立核心代码:
链表的节点结构
CID是登录用户账号信息
CIP是登录用户IP地址
Thisport是登录用户的端口号
typedef struct node
{
QString CID;
QString CIP;
qint16
thisport;
node *next;
}ND;
建立的链表类
Head头指针
Tail尾指针
Search查询指针
NDcount当前节点数目
class List
{
public:
List();
~List();
void
create_List(QString senderID,QString ipAddress,qint16 sport);
int
length_List();
void
delete_List(QString senderID);
QString
output_ip();
QString
output_ip1();
QString next_List();
QString
output_id();
qint16
output_port();
private:
ND* Head;
ND* Tail;
ND* Search;
int NDcount;
QSqlDatabase
db2;
};
当服务器启动时,对建立IPID_LIST链表初始化。NDcount记录在线用户个数。
List::List()
{
NDcount=0;
Head=new
node;
Head->next=NULL;
Search=Head;
Tail=Head;
}
create_List()当有用户加入时,创建一个节点,记录客户端的IP和端口号。
void List::create_List(QString senderID,QString
ipAddress,qint16 sport)
{
ND *s;
s=new node;
s->CID=senderID;
s->CIP=ipAddress;
s->thisport=sport;
s->next=NULL;
Tail->next=s;
Tail=s;
NDcount++;
}
length_List()用来输出在线人数。
int List::length_List()
{
return
NDcount;
}
delete_List()当有用户离开时删除该节点。Search指针是一个私有成员,用来查询节点,当search指针指向需要删除的节点,就把该指针指向头结点`。
void List::delete_List(QString
senderID)
{
ND *p,*q;
p=Head;
q=Head->next;
while(q!=NULL)
{
if(q->CID==senderID)
{
if(Search==q)
Search=Head;
if(q==Tail)
Tail=p;
p->next=q->next;
delete q;
NDcount--;
break;
}
p=p->next;
q=q->next;
}
}
next_List()用来输出该节点的下一个节点ID信息。
QString List::next_List()
{
Search=Search->next;
if(Search==NULL)
{
Search=Head->next;
}
return
Search->CID;
}
output_ip()用来输出searc指针指向当前节点的IP。
QString List::output_ip()
{
return
Search->CIP;
}
List::~List()
{
ND *p;
p=Head;
while(p!=NULL)
{
delete
p;
p=p->next;
}
}
output_id()用来输出search
指针指向当前节点的ID信息
QString List::output_id()
{
return
Search->CID;
}
outp
ut_port()用来输出search指针指向当前节点的端口信息
qint16 List::output_port()
{
return
Search->thisport;
}
由于代码较多,下面只给出思想,不给出代码,需要源代码的话到最后的链接下载。
2.2显示在线用户思想
服务端记录用户登录信息后,会把该用户的信息显示在登录界面上,方便管理员查看
2.3用户退出基本思想
在客户端退出的时候,会给服务器发送一个退出数据包,服务器将记录的客户端信息从链表中删除,然后把该用户的退出信息转发给其他的在线用户,其他用户收到退出数据包后,会在box界面中删除该用户的ID号。
2.4转发用户信息基本思想
采用UDP进行转发信息。在用户登录成功以后,用户要从服务器上获取所有的其他在线用户,以便与其进行通信。服务器会把所有的在线用户发送给新加入用户,并且把新加入用户的信息发送给所有的在线用户。
2.5保存聊天记录基本思想
首先,服务端收到客户端的查看聊天记录请求,接着服务器端根据请求方的id在数据库中查找聊天记录,接着将聊天记录发送到客户端。
2.6转发文本消息基本思想
采用UDP进行数据的转发。客户端会把所有要发送的文本消息发送给服务端,服务端对该消息保存到数据库中并转发给目标主机。源主机发送的数据包中包含有源ID,源IP,目的ID和文本信息。服务端接收到该数据包后根据目的ID查询链表,获取目的ID的IP,然后对该文本消息进行转发。
2.7用户登录基本思想
采用UDP进行发送登录信息。用户在登录界面输入服务器IP,用户名和密码,然后把含有用户名和密码的数据包发送给服务端,服务端得到用户名和密码后进行判断,用户名是否存在,如果不存在就注册。如果存在就进行判断密码是否正确,如果不正确则返回数据包中不允许登录,反之允许登录到下一个界面。
2.8 文字聊天基本思想
采用UDP进行数据传输。客户端从widget界面中获取文本信息,从box界面中获取目的ID,然后对数据进行发送。源主机发送的数据包中包含有源ID,源IP,目的ID和文本信息。
2.9 截屏传输基本思想
首先需要截取下整个屏幕,再通过qt中的橡皮筋标记下需要截取的图片,再将需要截取的图片保存到一个Qpixmap类型的变量中,之后显示在在客户端上。发送方点击发送图片,会将图片转换成Qstring类型的数据,通过udp传输给接收方。接收方收到之后将Qstring转换成图片显示在自己的客户端上。
2.10文件传输的基本思想
首先接收端需要开启监听端口。其次在发送端需要从本机中获取文件,把文件转化为QString类型的数据。从文件中获取文件总大小、文件名长度、文件名组成首部,发送给接收端,其次再把文件的剩余数据发给接收端。接收端在接收到首部之后就获取到了文件的总大小、文件名长度和文件名,接着把文件的数据部分写入文件,然后就在已经编译好的miniqq文件夹中创建了此文件,打开文件看数据是否有所丢失。
2.11软键盘设计基本思想
使用qt中的button控件,每一个控件上都有对应的字母标志,点击对应的按钮会把字母显示到上方的edittext控件里,一个控件调整字母大小写,一个退格控件,点击确定按钮会把edittext控件里文本信息传输到对应的聊天界面中。
2.12查看聊天记录基本思想
注意,视频部分需要安装OpenCV,不然会无法编译
聊天记录在发送文本信息的时候,服务器转发时保存在数据库中。所以要查看聊天记录必须向服务器发送请求,然后服务器向请求的客户端发送聊天记录数据。
2.13视频聊天基本思想
采用UDP传输数据,客户端先向服务端请求接收方的IP,然后通过UDP直接进行视频传输。
以下为功能部分截图:
源码下载:(https://download.csdn.net/download/qq_42161686/10897928)
注:源码包括已经编译好的在Linux下的可执行文件,以及源代码。