目录
协议部分
也就是应用层协议,需要区分你发送的信息是要干什么,客户端和服务器都要有
1.protoch.h
#ifndef PROTOCOL_H
#define PROTOCOL_H
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
typedef unsigned int uint;
//注册------------------------------------------------
#define ENROLL_OK "enroll ok"
#define ENROLL_FAILED "enroll failed : name exists"
//登录------------------------------------------------
#define LOGIN_OK "LOGIN ok"
#define LOGIN_FAILED "LOGIN failed : you are relogin or (name or pwd) error"
//查询在线用户-----------------------------------------
#define ONLINE "you search person is online"
#define OFFLINE "you search person is offline"
#define NO_PEOPLE "you search person is not exist"
//添加好友-------------------------------------------
#define UNKONW_ERROR "unknow ERROR"
#define EXIST_FRIEND "friend exist"
#define ADD_FRIEND_OFFLINE "the user is offline"
#define ADD_FRIEND_NO_EXIST "the user is not exist"
//删除好友-------------------------------------------
#define DELETE_SUCCESS "delete friend success"
#define DELETE_FALURE "delete friend falure"
enum ENUM_MSG_TYPE
{
ENUM_MSG_TYPE_MIN = 0,
ENUM_MSG_TYPE_ENROLL_REQUEST, //注册请求 //c
ENUM_MSG_TYPE_ENROLL_RESPOND, //注册回复 //s
ENUM_MSG_TYPE_LOGIN_REQUEST, //登录请求 //c
ENUM_MSG_TYPE_LOGIN_RESPOND, //登录回复 //s
ENUM_MSG_TYPE_ALL_ONLINE_REQUEST, //查询在线用户请求 //c
ENUM_MSG_TYPE_ALL_ONLINE_RESPOND, //查询在线用户回复 //s
ENUM_MSG_TYPE_SEARCH_USER_REQUEST, //查找用户请求 //c
ENUM_MSG_TYPE_SEARCH_USER_RESPOND, //查找用户回复 //s
ENUM_MSG_TYPE_ADD_FRIEND_REQUEST, //加好友请求 //c s
ENUM_MSG_TYPE_ADD_FRIEND_RESPOND, //加好友回复 //s c
ENUM_MSG_TYPE_ADD_FRIEND_AGREE, //同意添加好友 //c
ENUM_MSG_TYPE_ADD_FRIEND_REFUSE, //拒绝添加好友 //s
ENUM_MSG_TYPE_FLUSH_FRIENDS_REQUEST, //刷新在线好友请求 //c
ENUM_MSG_TYPE_FLUSH_FRIENDS_RESPOND, //刷新在线好友回复 //s
ENUM_MSG_TYPE_FLUSH_ALLFRIENDS_REQUEST, //刷新所有好友请求 //c
ENUM_MSG_TYPE_FLUSH_ALLFRIENDS_RESPOND, //刷新所有好友回复 //s
ENUM_MSG_TYPE_delete_FRIENDS_REQUEST, //删除好友请求 //c
ENUM_MSG_TYPE_delete_FRIENDS_RESPOND, //删除好友回复 //s
ENUM_MSG_TYPE_PRIVATE_CHAT_REQUEST, //私聊好友请求 //c
ENUM_MSG_TYPE_PRIVATE_CHAT_RESPOND, //私聊好友回复 //s
//ENUM_MSG_TYPE_REQUEST, //注册请求 //c
//ENUM_MSG_TYPE_RESPOND, //注册回复 //s
ENUM_MSG_TYPE_MAX = 0x00ffffff
};
struct PDU
{
uint uiPDULen; //总的协议数据大小
uint uiMsgType; //消息类型
uint uiMsgLen; //实际消息长度
char cadata[64];//文件名
int caMsg[]; //实际消息
};
PDU *mkPDU(uint uiMsgLen);//动态申请空间。
#endif // PROTOCOL_H
2.protocl.cpp
#include"protocol.h"
PDU *mkPDU(uint uiMsgLen)
{
uint uiPDULen = sizeof(PDU)+uiMsgLen;
PDU *pdu = (PDU*)malloc(uiPDULen);
if(NULL==pdu)
{
exit(EXIT_FAILURE);
}
memset(pdu,0,uiPDULen);
pdu->uiMsgLen = uiMsgLen;
pdu->uiPDULen = uiPDULen;
return pdu;
}
客户端
头文件
1.clicent.h
#ifndef CLICENT_H
#define CLICENT_H
#include <QMainWindow>
#include <QTcpSocket>
#include <protocol.h>
QT_BEGIN_NAMESPACE
namespace Ui { class clicent; }
QT_END_NAMESPACE
class clicent : public QMainWindow
{
Q_OBJECT
public:
clicent(QWidget *parent = nullptr);
~clicent();
static clicent &getInstance();
void loadconfig(); //加载配置
QTcpSocket &gettcpsocket(){return m_tcpsocket;}
QString login_name();
void add_friend(const QString addname);
public slots:
void showconnect();
void recvsmsg();
private slots:
void on_pushButton_login_clicked();
void on_pushButton_enroll_clicked();
private:
Ui::clicent *ui;
//------------------------------------------------------
QString m_strIP; //字符类型,存放ip地址
quint16 us_port; //无符号16位整形
QTcpSocket m_tcpsocket;//一个用与tcp连接的对象,连接服务器,和服务器进行交换。
QString m_strloginname;//登录时所用的用户名
};
#endif // CLICENT_H
2.online_user.h
#ifndef ONLINE_USER_H
#define ONLINE_USER_H
#include <QDockWidget>
#include "protocol.h"
namespace Ui {
class online_user;
}
class online_user : public QDockWidget
{
Q_OBJECT
public:
explicit online_user(QWidget *parent = nullptr);
~online_user();
static online_user &getInstance();
void show_online_user(PDU*pdu);
private slots:
void on_pushButton_flush_clicked();
void on_pushButton_add_friends_clicked();
private:
Ui::online_user *ui;
};
#endif // ONLINE_USER_H
3.private_chat.h
#ifndef PRIVATE_CHAT_H
#define PRIVATE_CHAT_H
#include <QDockWidget>
#include <protocol.h>
namespace Ui {
class private_chat;
}
class private_chat : public QDockWidget
{
Q_OBJECT
public:
explicit private_chat(QWidget *parent = nullptr);
~private_chat();
static private_chat &getInstance();
QString retname(){return chatname;}
void set_chatname(QString chatname);
QString ret_chatname();
void updata_msg(PDU *pdu);
private slots:
void on_pushButton_send_msg_clicked();
private:
Ui::private_chat *ui;
QString chatname;
};
#endif // PRIVATE_CHAT_H
4.search_user.h
#ifndef SEARCH_USER_H
#define SEARCH_USER_H
#include <QDockWidget>
namespace Ui {
class search_user;
}
class search_user : public QDockWidget
{
Q_OBJECT
public:
explicit search_user(QWidget *parent = nullptr);
~search_user();
static search_user &getInstance();
private slots:
void on_pushButton_search_clicked();
void on_pushButton_adduser_clicked();
private:
Ui::search_user *ui;
};
#endif // SEARCH_USER_H
5.user_operate.h
#ifndef USER_OPERATE_H
#define USER_OPERATE_H
#include <QMainWindow>
#include <online_user.h>
#include "search_user.h"
#include "private_chat.h"
namespace Ui {
class User_operate;
}
class User_operate : public QMainWindow
{
Q_OBJECT
public:
explicit User_operate(QWidget *parent = nullptr);
~User_operate();
static User_operate&getInstance();
void show_friends(PDU* pdu);
void show_ALLfriend(PDU *pdu);
static void flush_friend();
static void flush_ALLfriend();
private_chat* search_chat_windows(QString chatname);
QList<private_chat*> retQlistchat_windows(){return chat_windows;}
private slots:
void on_pushButton_onlineuser_clicked();
void on_pushButton_searchuser_clicked();
void on_pushButton_flush_friends_clicked();
void on_pushButton_deletefriend_clicked();
void on_pushButton_private_chat_clicked();
private:
Ui::User_operate *ui;
online_user *onuser;
search_user *seuser;
QList<private_chat*> chat_windows;
};
#endif // USER_OPERATE_H
源文件
1.clicent.cpp
#include "clicent.h"
#include "ui_clicent.h"
#include "user_operate.h"
#include "protocol.h"
#include "private_chat.h"
#include <QFile>
#include <QMessageBox>
QString allname;
clicent::clicent(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::clicent)
{
ui->setupUi(this);
//加载配置文件--------------------
loadconfig();
//连接服务器---------------------------------------
connect(&m_tcpsocket,SIGNAL(connected()),this,SLOT(showconnect())); //发送数据
connect(&m_tcpsocket,SIGNAL(readyRead()),this,SLOT(recvsmsg())); //接受数据
m_tcpsocket.connectToHost(QHostAddress(m_strIP), us_port); //连接服务器
}
clicent::~clicent()
{
delete ui;
}
clicent &clicent::getInstance()
{
static clicent instance;
return instance;
}
void clicent::loadconfig()
{
QFile file(":/client.config"); //选取文件路径
if(file.open(QIODevice::ReadOnly)) //bool类型,只读打开,成功返true
{
QByteArray badata = file.readAll(); //以字节形似读取所有数据出来
QString strdata = badata.toStdString().c_str(); //将badata转化为字符串类型
file.close(); //关闭文件
strdata.replace("\r\n"," "); //将/r/n替换成空格
QStringList strlist = strdata.split(" "); //以空格为准,将strdata里的数据进行分割后放入strlist
m_strIP = strlist.at(0);
us_port = strlist.at(1).toUShort();
}
else
{
QMessageBox::critical(this,"open config","open config failed");
}
}
QString clicent::login_name()
{
return allname;
}
void clicent::add_friend(const QString addname)
{
if(addname == allname)
{
QMessageBox::information(this,allname,"don't add yourself");
return;
}
//创建pdu包-----------------------------------
PDU *pdu = mkPDU(0);
pdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_REQUEST;
QString myname = allname;
memcpy(pdu->cadata,addname.toStdString().c_str(),addname.size());
memcpy(pdu->cadata+32,myname.toStdString().c_str(),myname.size());
//发送包---------------------------------------------------
m_tcpsocket.write((char*)pdu,pdu->uiPDULen);
//----------------------------------------------------------
free(pdu);
pdu = NULL;
}
void clicent::showconnect()
{
QMessageBox::information(this,"提示","连接服务器成功");
}
void clicent::recvsmsg()
{
QString name = allname;
//读取收到的pdu中的数据-------------------------------------------
uint uiPDULen = 0;
m_tcpsocket.read((char*)&uiPDULen,sizeof(uint));
uint uiMsgLen = uiPDULen - sizeof(PDU);
PDU *pdu = mkPDU(uiMsgLen);
m_tcpsocket.read((char*)pdu+sizeof(uint),uiPDULen-sizeof(uint));
//对数据类型进行判断以确定要执行什么--------------------------------
switch(pdu->uiMsgType)
{
case ENUM_MSG_TYPE_ENROLL_RESPOND: //注册回复类型
{
if(strcmp(pdu->cadata,ENROLL_OK) == 0)
{
QMessageBox::information(this,name,"注册成功");
}
else if(strcmp(pdu->cadata,ENROLL_FAILED) == 0)
{
QMessageBox::warning(this,name,"注册失败,重命名");
}
else
{
QMessageBox::warning(this,name,"注册失败,请联系管理员");
}
break;
}
case ENUM_MSG_TYPE_LOGIN_RESPOND: //登录回复类型
{
if(strcmp(pdu->cadata,LOGIN_OK) == 0)
{
QMessageBox::information(this,name,"登录成功");
User_operate::getInstance().show(); //显示登录后的界面
this->hide();
}
else if(strcmp(pdu->cadata,LOGIN_FAILED) == 0)
{
QMessageBox::warning(this,name,"登录失败,you are relogin or (name or pwd) error");
}
else
{
QMessageBox::warning(this,name,"登录失败,请联系管理员");
}
break;
}
case ENUM_MSG_TYPE_ALL_ONLINE_RESPOND: //在线用户类型
{
online_user::getInstance().show_online_user(pdu);
break;
}
case ENUM_MSG_TYPE_SEARCH_USER_RESPOND: //查找用户类型
{
//QString name = click_logined::getInstance().retname();
if(strcmp(pdu->cadata,ONLINE) == 0)
{
QString data = QString("'%1'在线").arg("用户");
QMessageBox::information(this,name,data);
}
else if(strcmp(pdu->cadata,OFFLINE) == 0)
{
QString data = QString("'%1'不在线").arg("用户");
QMessageBox::information(this,name,data);
}
else
{
QString data = QString("'%1'不存在").arg("用户");
QMessageBox::information(this,name,data);
}
break;
}
case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST: //添加好友请求
{
char myname[32] = {'\0'};
strncpy(myname,pdu->cadata+32,32);
QString data = QString("'%1' want to become your friend").arg(myname);
int ret = QMessageBox::information(this,name,data,QMessageBox::Yes,QMessageBox::No);
//产生一个回复的respdu
PDU *respdu = mkPDU(0);
memcpy(respdu->cadata,pdu->cadata,64);
if(ret == QMessageBox::Yes)
{
respdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_AGREE;
}
else
{
respdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_REFUSE;
}
//发送respdu-------------------------------------
m_tcpsocket.write((char*)respdu,respdu->uiPDULen);
free(respdu);
respdu = NULL;
break;
}
case ENUM_MSG_TYPE_ADD_FRIEND_RESPOND: //添加好友回复
{
QMessageBox::information(this,name,pdu->cadata);
break;
}
case ENUM_MSG_TYPE_ADD_FRIEND_AGREE: //添加好友同意
{
char addname[32] = {'\0'};
strncpy(addname,pdu->cadata,32);
QString data = QString("%1 agree your request").arg(addname);
QMessageBox::information(this,name,data);
break;
}
case ENUM_MSG_TYPE_ADD_FRIEND_REFUSE: //添加好友拒绝
{
char addname[32] = {'\0'};
strncpy(addname,pdu->cadata,32);
QString data = QString("%1 refuse your request").arg(addname);
QMessageBox::information(this,name,data);
break;
}
case ENUM_MSG_TYPE_FLUSH_FRIENDS_RESPOND: //刷新好友回复
{
User_operate::getInstance().show_friends(pdu);
break;
}
case ENUM_MSG_TYPE_FLUSH_ALLFRIENDS_RESPOND://刷新所有好友
{
User_operate::getInstance().show_ALLfriend(pdu);
break;
}
case ENUM_MSG_TYPE_delete_FRIENDS_RESPOND: //删除好友回复
{
if(strcmp(pdu->cadata,DELETE_SUCCESS) == 0)
{
QMessageBox::information(this,name,DELETE_SUCCESS);
User_operate::flush_friend();
User_operate::flush_ALLfriend();
}
else
{
QMessageBox::information(this,name,DELETE_FALURE);
}
break;
}
case ENUM_MSG_TYPE_PRIVATE_CHAT_REQUEST: //私聊好友发送
{
//qDebug()<<"收到";
char chat_name[32] = {'\0'};
char myname[32] = {'\0'};
strncpy(chat_name,pdu->cadata+32,32);
strncpy(myname,pdu->cadata,32);
//qDebug()<<chat_name<<myname;
private_chat * chat_window = User_operate::getInstance().search_chat_windows(chat_name);
if(chat_window == NULL)
{
chat_window = new private_chat;
chat_window->set_chatname(chat_name);
QString data = QString("'%1 chat with '%2' by this windows").arg(clicent::getInstance().login_name()).arg(chat_name);
chat_window->setWindowTitle(data);
User_operate::getInstance().retQlistchat_windows().append(chat_window);
//qDebug()<<"chat_window append ok";
}
chat_window->updata_msg(pdu);
User_operate::getInstance().addDockWidget(Qt::BottomDockWidgetArea,chat_window);
chat_window->show();
break;
}
default:
{
break;
}
}
free(pdu);
pdu = NULL;
}
void clicent::on_pushButton_login_clicked()
{
QString strname = ui->lineEdit_username->text();
allname = ui->lineEdit_username->text();
QString strpwd = ui->lineEdit_userpassward->text();
if(!strname.isEmpty()&&!strpwd.isEmpty())
{
//pdu构建----------------------------------------------
PDU *pdu = mkPDU(0);
pdu->uiMsgType = ENUM_MSG_TYPE_LOGIN_REQUEST; //消息类型为登录类型
strncpy(pdu->cadata,strname.toStdString().c_str(),32); //获取账户
strncpy(pdu->cadata+32,strpwd.toStdString().c_str(),32); //获取密码
//socket发送-------------------------------------------
m_tcpsocket.write((char*)pdu,pdu->uiPDULen);
free(pdu);
pdu = NULL;
}
else
{
QMessageBox::critical(this,"提示","登录失败:用户名和密码不能为空");
}
}
void clicent::on_pushButton_enroll_clicked()
{
QString strname = ui->lineEdit_username->text();
QString strpwd = ui->lineEdit_userpassward->text();
if(!strname.isEmpty()&&!strpwd.isEmpty())
{
//pdu构建----------------------------------------------
PDU *pdu = mkPDU(0);
pdu->uiMsgType = ENUM_MSG_TYPE_ENROLL_REQUEST; //消息类型为注册类型
strncpy(pdu->cadata,strname.toStdString().c_str(),32); //获取注册账户
strncpy(pdu->cadata+32,strpwd.toStdString().c_str(),32); //获取注册密码
//socket发送-------------------------------------------
m_tcpsocket.write((char*)pdu,pdu->uiPDULen);
free(pdu);
pdu = NULL;
}
else
{
QMessageBox::critical(this,"提示","注册失败:用户名和密码不能为空");
}
}
2.online_user.cpp
#include "online_user.h"
#include "ui_online_user.h"
#include "clicent.h"
#include "user_operate.h"
#include "QMessageBox"
online_user::online_user(QWidget *parent) :
QDockWidget(parent),
ui(new Ui::online_user)
{
ui->setupUi(this);
}
online_user::~online_user()
{
delete ui;
}
online_user &online_user::getInstance()
{
static online_user instance;
return instance;
}
void online_user::show_online_user(PDU *pdu)
{
ui->listWidget_onlineuser->clear();//清空数据
if(pdu == NULL)
{
QMessageBox::critical(this,clicent::getInstance().login_name(),"有问题");
return;
}
else
{
//提取数据----------------------
uint uisize = pdu->uiMsgLen/32; //获取数据个数
char catmp[32];
for(uint i = 0;i<uisize;i++)
{
memcpy(catmp,(char*)(pdu->caMsg)+i*32,32);
ui->listWidget_onlineuser->addItem(catmp);
}
}
//显示界面------------------------------------
User_operate::getInstance().addDockWidget(Qt::RightDockWidgetArea,this);
this->show();
}
void online_user::on_pushButton_flush_clicked()
{
//发送pdu,请求在线用户---------------------------
PDU *pdu = mkPDU(0);
pdu->uiMsgType = ENUM_MSG_TYPE_ALL_ONLINE_REQUEST;
clicent::getInstance().gettcpsocket().write((char*)pdu,pdu->uiPDULen);
//释放pdu---------------------------------------
free(pdu);
pdu = NULL;
//收到数据包后在显示,否则数据不会出来-------------------
}
void online_user::on_pushButton_add_friends_clicked()
{
//发送添加好友包-----------------------------------
QString addname = ui->listWidget_onlineuser->currentItem()->text();
clicent::getInstance().add_friend(addname);
}
3.private_chat.cpp
#include "private_chat.h"
#include "ui_private_chat.h"
#include "clicent.h"
#include "protocol.h"
#include "QMessageBox"
#include "stdlib.h"
private_chat::private_chat(QWidget *parent) :
QDockWidget(parent),
ui(new Ui::private_chat)
{
ui->setupUi(this);
}
private_chat::~private_chat()
{
delete ui;
}
private_chat &private_chat::getInstance()
{
static private_chat instance;
return instance;
}
void private_chat::set_chatname(QString chatname)
{
this->chatname = chatname;
}
QString private_chat::ret_chatname()
{
return chatname;
}
void private_chat::updata_msg(PDU *pdu)
{
if(pdu == NULL )
{
return;
}
else
{
char sendname[32] = {'\0'};
memcpy(sendname,pdu->cadata+32,32);
QString strmsg = QString("%1 say: %2").arg(sendname).arg((char*)pdu->caMsg);
ui->textEdit_show_msg->append(strmsg);
}
}
void private_chat::on_pushButton_send_msg_clicked()
{
//获取双方名字-----------------------
char chat_name[32];
char myname[32];
strncpy(chat_name,retname().toStdString().c_str(),32);
strncpy(myname,clicent::getInstance().login_name().toStdString().c_str(),32);
//qDebgu()<<myname<<"发送pdu"<<chat_name;
//获取要发送的信息--------------------
QString strdata = ui->lineEdit_msg_input->text();
if(strdata.isEmpty())
{
QMessageBox::information(this,clicent::getInstance().login_name(),"send message is NULL");
return ;
}
else
{
//构建pdu---------------------------
PDU *pdu = mkPDU(strdata.size()+1);
pdu->uiMsgType = ENUM_MSG_TYPE_PRIVATE_CHAT_REQUEST;
strncpy(pdu->cadata,chat_name,32);
strncpy(pdu->cadata+32,myname,32);
//qDebug()<<pdu->cadata+32<<"发送pdu"<<pdu->cadata;
strncpy((char*)pdu->caMsg,strdata.toStdString().c_str(),strdata.size()+1);
//发送pdu---------------------------
clicent::getInstance().gettcpsocket().write((char*)pdu,pdu->uiPDULen);
updata_msg(pdu);
//释放pdu---------------------------
free(pdu);
pdu = NULL;
}
}
4.search_user.cpp
#include "search_user.h"
#include "ui_search_user.h"
#include "protocol.h"
#include "QMessageBox"
#include "clicent.h"
search_user::search_user(QWidget *parent) :
QDockWidget(parent),
ui(new Ui::search_user)
{
ui->setupUi(this);
}
search_user::~search_user()
{
delete ui;
}
search_user &search_user::getInstance()
{
static search_user instance;
return instance;
}
void search_user::on_pushButton_search_clicked()
{
QString searchname = ui->lineEdit_searchname->text();
//构建pdu包---------------------------------
if(!searchname.isEmpty())
{
//生成pdu包---------------------------------------
PDU* pdu = mkPDU(0);
pdu->uiMsgType = ENUM_MSG_TYPE_SEARCH_USER_REQUEST;
strncpy(pdu->cadata,searchname.toStdString().c_str(),32);
clicent::getInstance().gettcpsocket().write((char*)pdu,pdu->uiPDULen);
//释放pdu---------------------------------------
free(pdu);
pdu = NULL;
}
else if (searchname.isEmpty())
{
QMessageBox::critical(this,"提示","name不能为空");
}
else
{
return;
}
}
void search_user::on_pushButton_adduser_clicked()
{
//发送添加好友包-----------------------------------
QString addname = ui->lineEdit_searchname->text();
clicent::getInstance().add_friend(addname);
}
5.user_operate.cpp
#include "user_operate.h"
#include "ui_user_operate.h"
#include "online_user.h"
#include "protocol.h"
#include "clicent.h"
#include "private_chat.h"
#include "QInputDialog"
#include "QMessageBox"
User_operate::User_operate(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::User_operate)
{
ui->setupUi(this);
//---------------------------------------------
onuser = new online_user;
seuser = new search_user;
flush_ALLfriend();
flush_friend();
setWindowTitle(clicent::getInstance().login_name());
}
User_operate::~User_operate()
{
delete ui;
}
User_operate &User_operate::getInstance()
{
static User_operate instance;
return instance;
}
void User_operate::show_friends(PDU *pdu)
{
ui->listWidget_friends->clear();
if(pdu == NULL)
{
return;
}
else
{
//提取数据----------------------
uint uisize = pdu->uiMsgLen/32; //获取数据个数
char catmp[32];
for(uint i = 0;i<uisize;i++)
{
memcpy(catmp,(char*)(pdu->caMsg)+i*32,32);
ui->listWidget_friends->addItem(catmp);
}
}
//显示界面------------------------------------
this->show();
}
void User_operate::show_ALLfriend(PDU *pdu)
{
ui->listWidget_Allfriend->clear();
if(pdu == NULL)
{
return;
}
else
{
//提取数据----------------------
uint uisize = pdu->uiMsgLen/32; //获取数据个数
char catmp[32];
for(uint i = 0;i<uisize;i++)
{
memcpy(catmp,(char*)(pdu->caMsg)+i*32,32);
ui->listWidget_Allfriend->addItem(catmp);
}
}
//显示界面------------------------------------
this->show();
}
void User_operate::flush_friend()
{
//发送pdu,请求在线好友---------------------------
PDU *pdu = mkPDU(0);
pdu->uiMsgType = ENUM_MSG_TYPE_FLUSH_FRIENDS_REQUEST;
QString strname = clicent::getInstance().login_name();
memcpy(pdu->cadata,strname.toStdString().c_str(),strname.size());
clicent::getInstance().gettcpsocket().write((char*)pdu,pdu->uiPDULen);
//释放pdu---------------------------------------
free(pdu);
pdu = NULL;
}
void User_operate::flush_ALLfriend()
{
//发送pdu,请求所有好友---------------------------
PDU *pdu = mkPDU(0);
pdu->uiMsgType = ENUM_MSG_TYPE_FLUSH_ALLFRIENDS_REQUEST;
QString strname = clicent::getInstance().login_name();
memcpy(pdu->cadata,strname.toStdString().c_str(),strname.size());
clicent::getInstance().gettcpsocket().write((char*)pdu,pdu->uiPDULen);
//释放pdu---------------------------------------
free(pdu);
pdu = NULL;
}
private_chat *User_operate::search_chat_windows(QString chatname)
{
for(int i = 0;i<chat_windows.size();i++)
{
chat_windows.at(i)->ret_chatname();
//qDebug()<<"search_chat_windows;"<<chat_windows.at(i)->ret_chatname();
if(chatname == chat_windows.at(i)->ret_chatname())
{
return chat_windows.at(i);
}
}
return NULL;
}
void User_operate::on_pushButton_onlineuser_clicked()
{
//发送pdu,请求在线用户---------------------------
PDU *pdu = mkPDU(0);
pdu->uiMsgType = ENUM_MSG_TYPE_ALL_ONLINE_REQUEST;
clicent::getInstance().gettcpsocket().write((char*)pdu,pdu->uiPDULen);
//释放pdu---------------------------------------
free(pdu);
pdu = NULL;
//收到数据包后在显示,否则数据不会出来-------------------
}
void User_operate::on_pushButton_searchuser_clicked()
{
//显示dockwidget--------------------------------
addDockWidget(Qt::RightDockWidgetArea,seuser);
seuser->show();
}
void User_operate::on_pushButton_flush_friends_clicked()
{
flush_friend();
flush_ALLfriend();
}
void User_operate::on_pushButton_deletefriend_clicked()
{
char defriend[32] = {'\0'};
char myname[32] = {'\0'};
if(ui->listWidget_friends->currentItem() == NULL)
{
return;
}
strncpy(defriend,ui->listWidget_friends->currentItem()->text().toStdString().c_str(),32);
strncpy(myname,clicent::getInstance().login_name().toStdString().c_str(),32);
QString data = QString("Are you sure to delete '%1'").arg(defriend);
int ret = QMessageBox::information(this,clicent::getInstance().login_name(),data,QMessageBox::Yes,QMessageBox::No);
if(ret == QMessageBox::Yes)
{
//创建pdu包-----------------------
PDU* pdu = mkPDU(0);
pdu->uiMsgType = ENUM_MSG_TYPE_delete_FRIENDS_REQUEST;
memcpy(pdu->cadata,defriend,32);
memcpy(pdu->cadata+32,myname,32);
//发送pdu包------------------------
clicent::getInstance().gettcpsocket().write((char*)pdu,pdu->uiPDULen);
//释放pdu---------------------------------------
free(pdu);
pdu = NULL;
}
return;
}
void User_operate::on_pushButton_private_chat_clicked()
{
//获取私聊名字--------------------
if(ui->listWidget_friends->currentItem()==NULL)
{
QMessageBox::information(this,clicent::getInstance().login_name(),"please choose your chat name");
return;
}
QString chatname = ui->listWidget_friends->currentItem()->text();
private_chat *chat_window = search_chat_windows(chatname);
if(chat_window == NULL)
{
chat_window = new private_chat;
chat_window->set_chatname(chatname);
QString data = QString("'%1 chat with '%2' by this windows").arg(clicent::getInstance().login_name()).arg(chatname);
chat_window->setWindowTitle(data);
chat_windows.append(chat_window);
//qDebug()<<"chat_window append ok";
}
//显示私聊页面--------------------
addDockWidget(Qt::BottomDockWidgetArea,chat_window);
chat_window->show();
}
6.main.cpp
#include "clicent.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//User_operate w;
clicent w;
w.show();
return a.exec();
}
qt设计师界面
1.clicent.ui
2.online_user.ui
3.private_chat.ui
4.search_user.ui
5.user_operate.ui
服务器
头文件
1.mytcpserver.h
#ifndef MYTCPSERVER_H
#define MYTCPSERVER_H
#include"mytcpsocket.h"
#include <QTcpServer>
#include<QList>
#include"protocol.h"
class myTcpServer : public QTcpServer
{
Q_OBJECT
public:
myTcpServer();
static myTcpServer & getInstance(); //C++单例程模式
void incomingConnection(qintptr socketDescriptor);
void resend(char *addname,PDU*respdu);
public slots:
void deletesocket(MyTcpSocket *mysocket);
private:
QList<MyTcpSocket*> m_tcpsocketlist;
};
#endif // MYTCPSERVER_H
2.mytcpsocket.h
#ifndef MYTCPSOCKET_H
#define MYTCPSOCKET_H
#include <QTcpSocket>
class MyTcpSocket : public QTcpSocket
{
Q_OBJECT
public:
explicit MyTcpSocket(QObject *parent = nullptr);
QString getname(){return m_strname;}
signals:
void offline(MyTcpSocket *mysocket);
public slots:
void recvMsg();
void clientoffline();
private:
QString m_strname;
};
#endif // MYTCPSOCKET_H
3.opedb.h
#ifndef OPEDB_H
#define OPEDB_H
#include <QObject>
#include <QSqlDatabase> //连接数据库
#include <QSqlQuery> //查询数据库
#include<QStringList>
class OpeDB : public QObject
{
Q_OBJECT
public:
explicit OpeDB(QObject *parent = nullptr);
~OpeDB(){m_db.close();}
//-------------------------------------------------------
static OpeDB& getInstance();
void init();
bool handle_enroll(const char*name,const char*pwd); //注册函数
bool handle_login(const char*name,const char*pwd); //登录函数
void handle_offline(const char*name); //下线操作函数
QStringList handle_alline(); //查找在线用户函数
int handle_searchuser(const char*name); //搜索某一用户操作函数
int handle_addfriend(const char *addname,const char *myname); //添加好友操作函数
bool handle_addfriend_if_agreeconst (char *addname,const char *myname); //同意添加好友请求
QStringList handle_flush_friends(const char*name); //刷新好友列表
QStringList handle_flush_ALLfriends(const char*name); //刷新所有好友列表
bool handle_delefriend(char *delefriend,const char *myname); //删除好友操作
signals:
public slots:
private:
QSqlDatabase m_db;
};
#endif // OPEDB_H
4.tcpservice.h
#ifndef TCPSERVICE_H
#define TCPSERVICE_H
#include <QWidget>
#include <QFile>
//#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class tcpservice; }
QT_END_NAMESPACE
class tcpservice : public QWidget
{
Q_OBJECT
public:
tcpservice(QWidget *parent = nullptr);
~tcpservice();
//------------------------------------------------------
void loadconfig();
private:
Ui::tcpservice *ui;
//------------------------------------------------------
QString m_strIP; //字符类型,存放ip地址
quint16 us_port; //无符号16位整形
};
#endif // TCPSERVICE_H
源文件
1.mytcpserver.cpp
#include "mytcpserver.h"
#include "QDebug"
myTcpServer::myTcpServer()
{
}
myTcpServer &myTcpServer::getInstance()
{
static myTcpServer instance;
return instance;
}
//针对父类的虚函数重写,每当监听到新的连接时就会自动调用此函数。
void myTcpServer::incomingConnection(qintptr socketDescriptor)
{
//qDebug()<<"new client connect";
MyTcpSocket *ptcpsocket = new MyTcpSocket;
ptcpsocket->setSocketDescriptor(socketDescriptor);
m_tcpsocketlist.append(ptcpsocket);
connect(ptcpsocket,SIGNAL(offline(MyTcpSocket*)),this,SLOT(deletesocket(MyTcpSocket *)));
}
void myTcpServer::resend(char *addname, PDU *respdu)
{
if(addname == NULL || respdu == NULL)
{
return ;
}
for(int i = 0;i<m_tcpsocketlist.size();i++)
{
if(m_tcpsocketlist.at(i)->getname()==addname)
{
m_tcpsocketlist.at(i)->write((char*)respdu,respdu->uiPDULen);
break;
}
}
}
void myTcpServer::deletesocket(MyTcpSocket *mysocket)
{
//-------------------------------------------------
//for(int i = 0;i<m_tcpsocketlist.size();i++)
//{
// qDebug()<<m_tcpsocketlist.at(i)->getname();
//}
//迭代器遍历----------------------------------------
//个人认为这里可以改进
QList<MyTcpSocket*>::Iterator iter = m_tcpsocketlist.begin();
for(;iter!=m_tcpsocketlist.end();iter++)
{
if(mysocket == *iter)
{
delete *iter;
*iter = NULL;
m_tcpsocketlist.erase(iter);
//qDebug()<<"a clicent off line";
break;
}
}
//----------------------------------------------------
}
2.mytcpsocket.cpp
#include "mytcpsocket.h"
#include "mytcpserver.h"
#include "protocol.h"
#include"opedb.h"
#include<QDebug>
#include<QStringList>
MyTcpSocket::MyTcpSocket(QObject *parent)
: QTcpSocket{parent}
{
connect(this,SIGNAL(readyRead()),this,SLOT(recvMsg()));
connect(this,SIGNAL(disconnected()),this,SLOT(clientoffline()));
}
//对收到的数据进行处理
void MyTcpSocket::recvMsg()
{
//qDebug()<< this->bytesAvailable(); //当前的this是一个QTCPSOCKET类。
uint uiPDULen = 0;
this->read((char*)&uiPDULen,sizeof(uint));
uint uiMsgLen = uiPDULen - sizeof(PDU);
PDU *pdu = mkPDU(uiMsgLen);
this->read((char*)pdu+sizeof(uint),uiPDULen-sizeof(uint));
//类型处理--------------------------------------------------------
switch(pdu->uiMsgType)
{
case ENUM_MSG_TYPE_ENROLL_REQUEST: //注册消息类型
{
//获取名字密码--------------------------------------------
char caname[32] = {'\0'};
char capwd[32] = {'\0'};
strncpy(caname,pdu->cadata,32);
strncpy(capwd,pdu->cadata+32,32);
//-------------------------------------------------------
PDU*respdu = mkPDU(0); //注册回复消息
respdu->uiMsgType = ENUM_MSG_TYPE_ENROLL_RESPOND; //注册回复类型
bool ret = OpeDB::getInstance().handle_enroll(caname,capwd);
if(ret) //对是否成功添加到数据库进行判断
{
strcpy(respdu->cadata,ENROLL_OK);
}
else
{
strcpy(respdu->cadata,ENROLL_FAILED);
}
//回复消息-------------------------------------------------
this->write((char*)respdu,respdu->uiPDULen);
free(respdu);
respdu = NULL;
break;
}
case ENUM_MSG_TYPE_LOGIN_REQUEST: //登录消息类型
{
//获取名字密码--------------------------------------------
char caname[32] = {'\0'};
char capwd[32] = {'\0'};
strncpy(caname,pdu->cadata,32);
strncpy(capwd,pdu->cadata+32,32);
//登录回复消息---------------------------------------------
PDU*respdu = mkPDU(0);
respdu->uiMsgType = ENUM_MSG_TYPE_LOGIN_RESPOND; //登录回复类型
bool ret = OpeDB::getInstance().handle_login(caname,capwd);
if(ret) //对是否成功添加到数据库进行判断
{
strcpy(respdu->cadata,LOGIN_OK);
m_strname = caname;
}
else
{
strcpy(respdu->cadata,LOGIN_FAILED);
}
//回复消息-------------------------------------------------
this->write((char*)respdu,respdu->uiPDULen);
free(respdu);
respdu = NULL;
break;
}
case ENUM_MSG_TYPE_ALL_ONLINE_REQUEST: //在线用户类型
{
//获取所有在线用户信息------------------------------
QStringList res = OpeDB::getInstance().handle_alline();
//制作PDU包----------------------------------------
uint uimsglen = res.size()*32;
PDU *respdu = mkPDU(uimsglen);
respdu->uiMsgType = ENUM_MSG_TYPE_ALL_ONLINE_RESPOND;
for(int i = 0;i<res.size();i++)
{
memcpy((char*)(respdu->caMsg)+i*32,
res.at(i).toStdString().c_str(),
res.at(i).size());
}
//回复消息-----------------------------------------
this->write((char*)respdu,respdu->uiPDULen);
free(respdu);
respdu = NULL;
break;
}
case ENUM_MSG_TYPE_SEARCH_USER_REQUEST: //搜索用户类型
{
char caname[32] = {'\0'};
strncpy(caname,pdu->cadata,32);
PDU *respdu = mkPDU(0);
respdu->uiMsgType = ENUM_MSG_TYPE_SEARCH_USER_RESPOND;
int ret = OpeDB::getInstance().handle_searchuser(caname);
if(ret == 0)
{
strcpy(respdu->cadata,OFFLINE);
}
else if (ret == 1)
{
strcpy(respdu->cadata,ONLINE);
}
else
{
//QString data = QString("%1,is not searched").arg(caname);
strcpy(respdu->cadata,NO_PEOPLE);
}
//回复消息-----------------------------------------
this->write((char*)respdu,respdu->uiPDULen);
free(respdu);
respdu = NULL;
break;
}
case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST: //添加好友类型
{
char addname[32] = {'\0'};
char myname[32] = {'\0'};
strncpy(addname,pdu->cadata,32);
strncpy(myname,pdu->cadata+32,32);
int ret = OpeDB::getInstance().handle_addfriend(addname,myname);
//构建respdu包
PDU *respdu = mkPDU(0);
respdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
if(ret != 1)
{
if(ret == 0)
{
strcpy(respdu->cadata,EXIST_FRIEND);
}
else if(ret == 2)
{
strcpy(respdu->cadata,ADD_FRIEND_OFFLINE);
}
else if(ret == 3)
{
strcpy(respdu->cadata,ADD_FRIEND_NO_EXIST);
}
else
{
strcpy(respdu->cadata,UNKONW_ERROR);
}
//回复消息-----------------------------------------
this->write((char*)respdu,respdu->uiPDULen);
free(respdu);
respdu = NULL;
}
if(ret == 1)
{
//在线,发送添加好友请求-------------------------
myTcpServer::getInstance().resend(addname,pdu);
}
break;
}
case ENUM_MSG_TYPE_ADD_FRIEND_AGREE: //添加好友同意
{
char addname[32] = {'\0'};
char myname[32] = {'\0'};
strncpy(addname,pdu->cadata,32);
strncpy(myname,pdu->cadata+32,32);
//还有一个数据库操作,将其添加为好友------------------------
int ret = OpeDB::getInstance().handle_addfriend_if_agreeconst(addname,myname);
if(ret != true)
{
pdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_REFUSE;
}
//转发-------------------------------------------------
myTcpServer::getInstance().resend(myname,pdu);
break;
}
case ENUM_MSG_TYPE_ADD_FRIEND_REFUSE: //添加好友拒绝
{
char myname[32] = {'\0'};
strncpy(myname,pdu->cadata+32,32);
//转发-------------------------------------------------
myTcpServer::getInstance().resend(myname,pdu);
break;
}
case ENUM_MSG_TYPE_FLUSH_FRIENDS_REQUEST: //刷新好友请求
{
char strname[32];
strncpy(strname,pdu->cadata,32);
//获取所有在线用户信息------------------------------
QStringList res = OpeDB::getInstance().handle_flush_friends(strname);
//制作PDU包----------------------------------------
uint uimsglen = res.size()*32;
PDU *respdu = mkPDU(uimsglen);
respdu->uiMsgType = ENUM_MSG_TYPE_FLUSH_FRIENDS_RESPOND;
for(int i = 0;i<res.size();i++)
{
memcpy((char*)(respdu->caMsg)+i*32,
res.at(i).toStdString().c_str(),
res.at(i).size());
}
//回复消息-----------------------------------------
this->write((char*)respdu,respdu->uiPDULen);
free(respdu);
respdu = NULL;
break;
}
case ENUM_MSG_TYPE_FLUSH_ALLFRIENDS_REQUEST://刷新所有好友
{
char strname[32];
strncpy(strname,pdu->cadata,32);
//获取所有在线用户信息------------------------------
QStringList res = OpeDB::getInstance().handle_flush_ALLfriends(strname);
//制作PDU包----------------------------------------
uint uimsglen = res.size()*32;
PDU *respdu = mkPDU(uimsglen);
respdu->uiMsgType = ENUM_MSG_TYPE_FLUSH_ALLFRIENDS_RESPOND;
for(int i = 0;i<res.size();i++)
{
memcpy((char*)(respdu->caMsg)+i*32,
res.at(i).toStdString().c_str(),
res.at(i).size());
}
//回复消息-----------------------------------------
this->write((char*)respdu,respdu->uiPDULen);
free(respdu);
respdu = NULL;
break;
}
case ENUM_MSG_TYPE_delete_FRIENDS_REQUEST: //删除好友请求
{
char delname[32] = {'\0'};
char myname[32] = {'\0'};
strncpy(delname,pdu->cadata,32);
strncpy(myname,pdu->cadata+32,32);
//数据库删除操作--------------------------------
bool ret = OpeDB::getInstance().handle_delefriend(delname,myname);
//发送respdu包-------------------------------
PDU *respdu = mkPDU(0);
respdu->uiMsgType = ENUM_MSG_TYPE_delete_FRIENDS_RESPOND;
if(ret == true)
{
strcpy(respdu->cadata,DELETE_SUCCESS);
}
else
{
strcpy(respdu->cadata,DELETE_FALURE);
}
//回复消息-----------------------------------------
this->write((char*)respdu,respdu->uiPDULen);
//释放respdu包-------------------------------
free(respdu);
respdu = NULL;
break;
}
case ENUM_MSG_TYPE_PRIVATE_CHAT_REQUEST: //发送私聊请求
{
char pcname[32] = {'\0'};
memcpy(pcname,pdu->cadata,32);
qDebug()<<pcname<<(char*)(pdu->cadata+32);
myTcpServer::getInstance().resend(pcname,pdu);
break;
}
default:
{
break;
}
}
//---------------------------------------------------------------
free(pdu);
pdu = NULL;
}
void MyTcpSocket::clientoffline()
{
//改数据库
OpeDB::getInstance().handle_offline(m_strname.toStdString().c_str());
//改socketlist
emit offline(this); //this指代当前socket
}
3.opedb.cpp
#include "opedb.h"
#include<QMessageBox>
#include<QDebug>
OpeDB::OpeDB(QObject *parent)
: QObject{parent}
{
m_db = QSqlDatabase::addDatabase("QMYSQL");
}
OpeDB &OpeDB::getInstance()
{
static OpeDB instance;
return instance;
}
void OpeDB::init()
{
m_db.setHostName("127.0.0.1"); //设置连接数据库的地此
m_db.setPort(3306);
m_db.setDatabaseName("my_online_disk"); //设置要操作的数据库
m_db.setUserName("root"); //root用户
m_db.setPassword("123456"); //密码
if(!m_db.open())
{
QMessageBox::critical(NULL,"打开数据库","打开数据库失败");
}
}
bool OpeDB::handle_enroll(const char *name, const char *pwd)
{
if(!name||!pwd)
{
return false;
}
QString data = QString("insert into userinfo(name,passward) values(\'%1\',\'%2\')").arg(name).arg(pwd);
QSqlQuery query;
return query.exec(data);
}
bool OpeDB::handle_login(const char *name, const char *pwd)
{
if(!name||!pwd)
{
return false;
}
QString data = QString("select * from userinfo where name = '%1' and passward = '%2' and online = 0 ").arg(name).arg(pwd);
QSqlQuery query;
query.exec(data);
if(query.next())
{
data = QString("update userinfo set online = 1 where name = '%1' and passward = '%2' ").arg(name).arg(pwd);
QSqlQuery query1;
return query1.exec(data);
}
else
{
return false;
}
}
void OpeDB::handle_offline(const char *name)
{
if(!name)
{
qDebug()<<"name is null";
}
QString data = QString("update userinfo set online = 0 where name = '%1'").arg(name);
QSqlQuery query;
query.exec(data);
}
QStringList OpeDB::handle_alline()
{
QString data = QString("select name from userinfo where online = 1");
QSqlQuery query;
query.exec(data);
QStringList result;
result.clear();
while(query.next())
{
result.append(query.value(0).toString());
}
return result;
}
int OpeDB::handle_searchuser(const char *name)
{
if(name == NULL)
{
return -1;
}
QString data = QString("select online from userinfo where name = '%1'").arg(name);
QSqlQuery query;
query.exec(data);
if(query.next())
{
if(query.value(0).toInt())
{
return 1; //在线
}
else
{
return 0; //不在线
}
}
return -1;
}
int OpeDB::handle_addfriend(const char *addname, const char *myname)
{
if(addname == NULL || myname == NULL || myname == addname)
{
return -1;
}
QString data = QString("select * from friendinfo where "
"(id = (select id from userinfo where name = '%1') and "
"friendid = (select id from userinfo where name = '%2')) "
"or "
"(id = (select id from userinfo where name = '%3') and "
"friendid = (select id from userinfo where name = '%4'))").arg(addname).arg(myname).arg(myname).arg(addname);
QSqlQuery query;
query.exec(data);
qDebug ()<< data;
if(query.next())
{
return 0;//已经是好友了
}
else
{
int ret = handle_searchuser(addname);
if(ret == 1)
{
return 1;//在线
}
else if (ret == 0)
{
return 2;//不在线
}
else
{
return 3;//不存在这个人
}
}
}
bool OpeDB::handle_addfriend_if_agreeconst(char *addname, const char *myname)
{
if(addname == NULL || myname == NULL || myname == addname)
{
return false;
}
else
{
QString data = QString("insert into friendinfo values"
"((select id from userinfo where name = '%1'),(select id from userinfo where name = '%2')),"
"((select id from userinfo where name = '%3'),(select id from userinfo where name = '%4'))").arg(addname).arg(myname).arg(myname).arg(addname);
QSqlQuery query;
query.exec(data);
return true;
}
return false;
}
QStringList OpeDB::handle_flush_friends(const char *name)
{
QStringList strfriendlist;
strfriendlist.clear();
if(name == NULL)
{
return strfriendlist;
}
QString data = QString("select name from userinfo where (id) in "
"(select friendid from friendinfo where id = "
"(select id from userinfo where name = '%1')) and online = 1").arg(name);
QSqlQuery query;
query.exec(data);
while(query.next())
{
strfriendlist.append(query.value(0).toString());
}
return strfriendlist;
}
QStringList OpeDB::handle_flush_ALLfriends(const char *name)
{
QStringList strfriendlist;
strfriendlist.clear();
if(name == NULL)
{
return strfriendlist;
}
QString data = QString("select name from userinfo where (id) in "
"(select friendid from friendinfo where id = "
"(select id from userinfo where name = '%1'))").arg(name);
QSqlQuery query;
query.exec(data);
while(query.next())
{
strfriendlist.append(query.value(0).toString());
}
return strfriendlist;
}
bool OpeDB::handle_delefriend(char *delefriend, const char *myname)
{
if(delefriend == NULL || myname == NULL || myname == delefriend)
{
return false;
}
else
{
QString data = QString("delete from friendinfo where id = "
"(select id from userinfo where name = '%1') and "
"friendid = (select id from userinfo where name = '%2')").arg(myname).arg(delefriend);
QSqlQuery query;
bool reta = query.exec(data);
data = QString("delete from friendinfo where id = "
"(select id from userinfo where name = '%1') and "
"friendid = (select id from userinfo where name = '%2')").arg(delefriend).arg(myname);
bool retb = query.exec(data);
if(reta && retb )
{
return true;
}
}
return false;
}
4.tcpservice.cpp
#include "tcpservice.h"
#include "ui_tcpservice.h"
#include "mytcpserver.h"
#include <QByteArray>
//#include <QDebug>
#include <QMessageBox>
#include <QHostAddress>
tcpservice::tcpservice(QWidget *parent)
: QWidget(parent)
, ui(new Ui::tcpservice)
{
ui->setupUi(this);
//---------------------------------------------
loadconfig();
myTcpServer::getInstance().listen(QHostAddress(m_strIP),us_port);
}
tcpservice::~tcpservice()
{
delete ui;
}
void tcpservice::loadconfig()
{
QFile file(":/service.config"); //选取文件路径
if(file.open(QIODevice::ReadOnly)) //bool类型,只读打开,成功返true
{
QByteArray badata = file.readAll(); //以字节形似读取所有数据出来
QString strdata = badata.toStdString().c_str(); //将badata转化为字符串类型
file.close(); //关闭文件
strdata.replace("\r\n"," "); //将/r/n替换成空格
QStringList strlist = strdata.split(" "); //以空格为准,将strdata里的数据进行分割后放入strlist
m_strIP = strlist.at(0);
us_port = strlist.at(1).toUShort();
}
else
{
QMessageBox::critical(this,"open config","open config failed");
}
}
5.main.cpp
#include "tcpservice.h"
#include "opedb.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//------------------------------
OpeDB::getInstance().init();
//------------------------------
tcpservice w;
w.show();
return a.exec();
}
mysql数据库部分
1.userinfo
create table userInfo(
id int primary key auto_increment,
name varchar(32) unique,
passward varchar(32),
online int default 0
)comment'用户表';
2.friendinfo
create table friendInfo(
id int,
friendid int,
primary key(id, friendid)
)comment'好友表';
效果展示
1.登录
2.用户操作界面
3.与好友聊天
4.搜索
做的不是很完美,还有很多可以改进的地方,
后面有空会添加文件系统,上传文件。