QT网络编程Tcp下C/S架构的即时通信实例

先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面。

#ifndef TCPCLIENT_H

#define TCPCLIENT_H

#include <QDialog>

#include <QListWidget>

#include <QLineEdit>

#include <QPushButton>

#include <QLabel>

#include <QGridLayout>

#include <QtNetWork/QHostAddress>

#include <QtNetWork/QTcpSocket>

class TcpClient : public QDialog

{

Q_OBJECT

public:

TcpClient(QWidget *parent = 0,Qt::WindowFlags f=0);

~TcpClient();

private:

QListWidget *contentListWidget;

QLineEdit *sendLineEdit;

QPushButton *sendBtn;

QLabel *userNameLabel;

QLineEdit *userNameLineEdit;

QLabel *serverIPLabel;

QLineEdit *serverIPLineEdit;

QLabel *portLabel;

QLineEdit *portLineEdit;

QPushButton *enterBtn;

QGridLayout *mainLayout;

bool status;

int port;

QHostAddress *serverIP;

QString userName;

QTcpSocket *tcpSocket;

public slots:

void slotEnter();

void slotConnected();

void slotDisconnected();

void dataReceived();

void slotSend();

};

#endif // TCPCLIENT_H

有一个加入服务器的按钮,还有一个发送消息的按钮,在头文件,先定义两个函数。

#include "tcpclient.h"

#include <QMessageBox>

#include <QHostInfo>

TcpClient::TcpClient(QWidget *parent,Qt::WindowFlags f)

: QDialog(parent,f)

{

setWindowTitle(tr("TCP Client"));

contentListWidget = new QListWidget;

sendLineEdit = new QLineEdit;

sendBtn = new QPushButton(tr("send"));

userNameLabel = new QLabel(tr("name"));

userNameLineEdit = new QLineEdit;

serverIPLabel = new QLabel(tr("server"));

serverIPLineEdit = new QLineEdit;

portLabel = new QLabel(tr("port"));

portLineEdit = new QLineEdit;

enterBtn= new QPushButton(tr("join chat"));

mainLayout = new QGridLayout(this);

mainLayout->addWidget(contentListWidget,0,0,1,2);

mainLayout->addWidget(sendLineEdit,1,0);

mainLayout->addWidget(sendBtn,1,1);

mainLayout->addWidget(userNameLabel,2,0);

mainLayout->addWidget(userNameLineEdit,2,1);

mainLayout->addWidget(serverIPLabel,3,0);

mainLayout->addWidget(serverIPLineEdit,3,1);

mainLayout->addWidget(portLabel,4,0);

mainLayout->addWidget(portLineEdit,4,1);

mainLayout->addWidget(enterBtn,5,0,1,2);

status = false;

port = 8010;

portLineEdit->setText(QString::number(port));

serverIP =new QHostAddress();

connect(enterBtn,SIGNAL(clicked()),this,SLOT(slotEnter()));

connect(sendBtn,SIGNAL(clicked()),this,SLOT(slotSend()));

sendBtn->setEnabled(false);

}

TcpClient::~TcpClient()

{

}

void TcpClient::slotEnter()

{

if(!status)

{

QString ip = serverIPLineEdit->text();

if(!serverIP->setAddress(ip))

{

QMessageBox::information(this,tr("error"),tr("server ip address error!"));

return;

}

if(userNameLineEdit->text()=="")

{

QMessageBox::information(this,tr("error"),tr("User name error!"));

return;

}

userName=userNameLineEdit->text();

tcpSocket = new QTcpSocket(this);

connect(tcpSocket,SIGNAL(connected()),this,SLOT(slotConnected()));

connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));

connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));

tcpSocket->connectToHost(*serverIP,port);

status=true;

}

else

{

int length=0;

QString msg=userName+tr(":Leave Chat Room");

if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg. length())

{

return;

}

tcpSocket->disconnectFromHost();

status=false;

}

}

void TcpClient::slotConnected()

{

sendBtn->setEnabled(true);

enterBtn->setText(tr("离开"));

int length=0;

QString msg=userName+tr(":Enter Chat Room");

if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg.length())

{

return;

}

}

void TcpClient::slotSend()

{

if(sendLineEdit->text()=="")

{

return ;

}

QString msg=userName+":"+sendLineEdit->text();

tcpSocket->write(msg.toLatin1(),msg.length());

sendLineEdit->clear();

}

void TcpClient::slotDisconnected()

{

sendBtn->setEnabled(false);

enterBtn->setText(tr("join chat"));

}

void TcpClient::dataReceived()

{

while(tcpSocket->bytesAvailable()>0)

{

QByteArray datagram;

datagram.resize(tcpSocket->bytesAvailable());

tcpSocket->read(datagram.data(),datagram.size());

QString msg=datagram.data();

contentListWidget->addItem(msg.left(datagram.size()));

}

}

实现界面布局。在Enter槽函数中,确定加入还是离开的服务器的功能。如果加入了,就将消息,写到tcpsocket中,构造消。

服务端的头文件:

#ifndef TCPSERVER_H

#define TCPSERVER_H

#include <QDialog>

#include <QListWidget>

#include <QLabel>

#include <QLineEdit>

#include <QPushButton>

#include <QGridLayout>

#include "server.h"

class TcpServer : public QDialog

{

Q_OBJECT

public:

TcpServer(QWidget *parent = 0,Qt::WindowFlags f=0);

~TcpServer();

private:

QListWidget *ContentListWidget;

QLabel *PortLabel;

QLineEdit *PortLineEdit;

QPushButton *CreateBtn;

QGridLayout *mainLayout;

int port;

Server *server;

public slots:

void slotCreateServer();

void updateServer(QString,int);

};

#endif // TCPSERVER_H

这是服务端的界面的,把消息显示而已。实现这个布局。

#include "tcpserver.h"

TcpServer::TcpServer(QWidget *parent,Qt::WindowFlags f)

: QDialog(parent,f)

{

setWindowTitle(tr("TCP Server"));

ContentListWidget = new QListWidget;

PortLabel = new QLabel(tr(" port"));

PortLineEdit = new QLineEdit;

CreateBtn = new QPushButton(tr("create chat"));

mainLayout = new QGridLayout(this);

mainLayout->addWidget(ContentListWidget,0,0,1,2);

mainLayout->addWidget(PortLabel,1,0);

mainLayout->addWidget(PortLineEdit,1,1);

mainLayout->addWidget(CreateBtn,2,0,1,2);

port=8010;

PortLineEdit->setText(QString::number(port));

connect(CreateBtn,SIGNAL(clicked()),this,SLOT(slotCreateServer()));

}

TcpServer::~TcpServer()

{

}

void TcpServer::slotCreateServer()

{

server = new Server(this,port);

connect(server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));

CreateBtn->setEnabled(false);

}

void TcpServer::updateServer(QString msg,int length)

{

ContentListWidget->addItem(msg.left(length));

}

创建TCP的套接字,以便实现服务端和客户端的通信。

#ifndef TCPCLIENTSOCKET_H

#define TCPCLIENTSOCKET_H

#include <QtNetWork/QTcpSocket>

#include <QObject>

class TcpClientSocket : public QTcpSocket

{

Q_OBJECT

public:

TcpClientSocket();

signals:

void updateClients(QString,int);

void disconnected(int);

protected slots:

void dataReceived();

void slotDisconnected();

};

#endif // TCPCLIENTSOCKET_H

以上是头文件,具体的是:

#include "tcpclientsocket.h"

TcpClientSocket::TcpClientSocket()

{

connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));

connect(this,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));

}

void TcpClientSocket::dataReceived()

{

while(bytesAvailable()>0)

{

int length = bytesAvailable();

char buf[1024];

read(buf,length);

QString msg=buf;

emit updateClients(msg,length);

}

}

void TcpClientSocket::slotDisconnected()

{

emit disconnected(this->socketDescriptor());

}

实现服务器,头文件:

#ifndef SERVER_H

#define SERVER_H

#include <QtNetWork/QTcpServer>

#include <QObject>

#include "tcpclientsocket.h"

class Server : public QTcpServer

{

Q_OBJECT

public:

Server(QObject *parent=0,int port=0);

QList<TcpClientSocket*> tcpClientSocketList;

signals:

void updateServer(QString,int);

public slots:

void updateClients(QString,int);

void slotDisconnected(int);

protected:

void incomingConnection(int socketDescriptor);

};

#endif // SERVER_H

#include "server.h"

Server::Server(QObject *parent,int port)

:QTcpServer(parent)

{

listen(QHostAddress::Any,port);

}

void Server::incomingConnection(int socketDescriptor)

{

TcpClientSocket *tcpClientSocket = new TcpClientSocket;

connect(tcpClientSocket,SIGNAL(updateClients(QString,int)),this,SLOT(updateClients(QString,int)));

connect(tcpClientSocket,SIGNAL(disconnected(int)),this,SLOT(slotDisconnected(int)));

tcpClientSocket->setSocketDescriptor(socketDescriptor);

tcpClientSocketList.append(tcpClientSocket);

}

void Server::updateClients(QString msg,int length)

{

emit updateServer(msg,length);

for(int i=0;i<tcpClientSocketList.count();i++)

{

QTcpSocket *item = tcpClientSocketList.at(i);

if(item->write(msg.toLatin1(),length)!=length)

{

continue;

}

}

}

void Server::slotDisconnected(int descriptor)

{

for(int i=0;i<tcpClientSocketList.count();i++)

{

QTcpSocket *item = tcpClientSocketList.at(i);

if(item->socketDescriptor()==descriptor)

{

tcpClientSocketList.removeAt(i);

return;

}

}

return;

}

实现后的界面:

以上这篇QT网络编程Tcp下C/S架构的即时通信实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是 QT网络编程Tcp下C/S架构的即时通信实例 的全部内容, 来源链接: utcz.com/z/324727.html

回到顶部