您的位置:首页 > 编程语言 > Qt开发

QT 聊天程序

2015-06-29 22:31 459 查看
一.聊天程序

QT实现的界面

网络的数据通信

服务器端

建立用户UI

建立服务器socket

接受客户连接

为每个各户建立线程处理客户数据

分析设计的一般规律:

1.用例

2.事件流

3.找对象,并且抽象类

4.设计类本身

5.设计类关系(泛化关系,关联关系)

6.设计模式优化设计

设计界面

QMainWindow增加:菜单,工具条,状态条。

菜单:

QMenuBar

addMenu

QMenu

addAction

QMenuItem/QAction

构造器

菜单的响应

状态条

QStatusBar

服务器设计图



ServerSocket.h

<span style="font-size:18px;">#ifndef SERVER_SOCKET_H
#define SERVER_SOCKET_H
#include <QObject>
#include "ChatException.h"
class ServerSocket : public QObject
{
Q_OBJECT
public:
char ip[30];
short port;
int fd;
public:
void initSocket() throw (ChatException);  // 初始化Socket
int accept() throw (ChatException); // 返回客户的文件描述符
};
#endif
</span>


ServerSocket.cpp

<span style="font-size:18px;">#include "ServerSocket.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
void ServerSocket::initSocket()throw(ChatException)
{
struct sockaddr_in addr;
int r;
fd=socket(AF_INET,SOCK_STREAM,0);
if(fd==-1) throw ChatException("socket错误");

addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(ip);
addr.sin_port=htons(port);
r=bind(fd,(struct sockaddr*)&addr,sizeof(addr));
if(r==-1) {
close(fd);
throw ChatException("bind错误");
}

r=listen(fd,10);
if(r==-1){
close(fd);
throw ChatException("listen错误");
}
}
int ServerSocket::accept()throw(ChatException)
{
int cfd;
cfd=::accept(fd,NULL,0);  // 表明是全局函数
if(cfd==-1) throw ChatException("accept错误");
return cfd;
}
</span>


ThAccept.h

<span style="font-size:18px;">#ifndef TH_ACCEPT_H
#define TH_ACCEPT_H
#include <QThread>
#include "ChatException.h"
#include "ServerSocket.h"
#include <QTextEdit>
class ThAccept : public QThread
{
Q_OBJECT
public:
QTextEdit *info;
private:
ServerSocket server;
public:
void init()throw(ChatException);
void run();//在线程中接收客户连接
public: signals:
void sigInfo(const QString &);	 // 和append函数保持一致
};
#endif</span>


ThAccept.cpp

<span style="font-size:18px;">#include "ThAccept.h"
#include <cstdio>
#include "ThClient.h"
#include "ServerWindow.h"
using namespace std;
void ThAccept::init()throw(ChatException)
{
sprintf(server.ip,"%s","192.168.180.92");
server.port=8888;
try{
server.initSocket();
}
catch(ChatException e)
{
throw e;
}
}
void ThAccept::run()//在线程中接收客户连接
{
while(true)
{
try	{
int fd=server.accept();
//发出信号
emit sigInfo(tr("有人连接!"));
//??建立子线程监听对应的客户
ThClient *th=new ThClient;
th->fd=fd;
ServerWindow::allusers.push_back(th);
connect(th,SIGNAL(sigInfo(const QString&)),
info,SLOT(append(const QString&)));
th->start();
}
catch(ChatException e)
{
//发出信号
emit sigInfo("服务器崩溃!");
break;
}
}

}
</span>


ThClient.h

<span style="font-size:18px;">#ifndef TH_CLIENT_H
#define TH_CLIENT_H
#include <QThread>
class ThClient : public QThread
{
Q_OBJECT
public:
int fd;
public:
void run(); //接收客户数据,广播
public: signals:
void sigInfo(const QString&);
};
#endif
</span>


ThClient.cpp

<span style="font-size:18px;">#include "ThClient.h"
#include <sys/socket.h>
#include <list>
#include "ServerWindow.h"
#include <unistd.h>
using namespace std;
void ThClient::run()
{
int r;
char buf[1024];
while(true)
{
r=recv(fd,buf,sizeof(buf)-1,0);
if(r<=0)
{
emit sigInfo(tr("有客户退出"));
ServerWindow::allusers.remove(this);
close(fd);
//delete this;
break;
}
buf[r]=0;
//发送消息,把接收数据显示到服务器主窗体
emit sigInfo(tr(buf));
//广播
list<ThClient*>::iterator it=
ServerWindow::allusers.begin();
while(it!=ServerWindow::allusers.end())
{
send((*it)->fd,buf,strlen(buf),0);
it++;
}
}
}
</span>


ServerWindow.h

<span style="font-size:18px;">#ifndef SERVER_WINDOW_H
#define SERVER_WINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QTextEdit>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QStatusBar>
#include <QLabel>
#include "ThAccept.h"
#include <list>
#include "ThClient.h"
using namespace std;
class ServerWindow : public QMainWindow
{
Q_OBJECT
public:
static list<ThClient*>  allusers;
private:
QTextEdit *info;//显示聊天信息
//菜单
QMenuBar  *bar;
QMenu	  *mnuserver;
QAction	  *actstart;  // 创建服务器
QAction	  *actexit;   // 退出服务器
//状态条
QStatusBar *status;   //
QLabel 	   *lbltip;   // 操作提示
QLabel	   *lblresult;// 操作结果
QLabel	   *lbltime;	// 显示时间
//接收线程
ThAccept  thaccept;
public:
ServerWindow(QWidget*p=NULL);
public slots:
void onStart();
};
#endif
</span>


ServerWindow.cpp

<span style="font-size:18px;">#ifndef SERVER_WINDOW_H
#define SERVER_WINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QTextEdit>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QStatusBar>
#include <QLabel>
#include "ThAccept.h"
#include <list>
#include "ThClient.h"
using namespace std;
class ServerWindow : public QMainWindow
{
Q_OBJECT
public:
static list<ThClient*>  allusers;
private:
QTextEdit *info;//显示聊天信息
//菜单
QMenuBar  *bar;
QMenu	  *mnuserver;
QAction	  *actstart;  // 创建服务器
QAction	  *actexit;   // 退出服务器
//状态条
QStatusBar *status;   //
QLabel 	   *lbltip;   // 操作提示
QLabel	   *lblresult;// 操作结果
QLabel	   *lbltime;	// 显示时间
//接收线程
ThAccept  thaccept;
public:
ServerWindow(QWidget*p=NULL);
public slots:
void onStart();
};
#endif
</span>
ChatServer.h

<span style="font-size:18px;">#ifndef CHAT_EXCEPTION_H
#define CHAT_EXCEPTION_H
#include <exception>
using namespace std;
class ChatException : public exception
{
private:
char msg[50];
public:
ChatException();
ChatException(const char*);
const char* what() const throw();
};
#endif
</span>


ChatServer.cpp

<span style="font-size:18px;">#include "ChatException.h"
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
ChatException::ChatException(){
memset(msg,0,sizeof(msg));
sprintf(msg,"聊天异常!");
}
ChatException::ChatException(const char*m){
memset(msg,0,sizeof(msg));
sprintf(msg,"聊天异常:%s!",m);
}

const char* ChatException::what() const throw(){
return msg;
}
</span>


chatServer.cpp 主程序

<span style="font-size:18px;">#include <QApplication>
#include <QTextCodec>
#include "ServerWindow.h"
int main(int args,char**argv)
{
QApplication app(args,argv);
QTextCodec *codec=
QTextCodec::codecForName("gb2312");
QTextCodec::setCodecForTr(codec);
ServerWindow sw;
return app.exec();
}<span style="color:#ff0000;">
</span></span>


chatServer.pro

<span style="font-size:18px;">TEMPLATE=app
SOURCES=chatServer.cpp		\
ServerWindow.cpp	\
ChatException.cpp	\
ServerSocket.cpp	\
ThAccept.cpp		\
ThClient.cpp
HEADERS=ServerWindow.h		\
ChatException.h		\
ServerSocket.h		\
ThAccept.h			\
ThClient.h

CONFIG=release qt
QT=core gui
TARGET=server
</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: