用Qt5做一个TCP server和client

首先,在.pro中添加network

QT       += core gui svg opengl network

创建一个TcpServer类,继续于QObject

TcpServer.h

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QObject>

#include <QTcpServer>
#include <QTcpSocket>
#include <QVector>
#include <QDebug>

class TcpServer : public QObject
{
    Q_OBJECT
public:
    explicit TcpServer(QObject *parent = nullptr);

    //
    void startServer();
    void sendMessageToClient(QString message);

signals:

public slots:
    void newClientConnection();
    void socketDisconnected();
    void socketReadReady();
    void socketStateChanged(QAbstractSocket::SocketState state);
private:
    QTcpServer* chatServer;
    QVector<QTcpSocket*>* allClients;

};

#endif // TCPSERVER_H

TcpServer.cpp

#include "tcpserver.h"

TcpServer::TcpServer(QObject *parent) : QObject(parent)
{

}

void TcpServer::startServer()
{
    allClients = new QVector<QTcpSocket*>;
    chatServer = new QTcpServer();
    chatServer->setMaxPendingConnections(10);
    connect(chatServer, &QTcpServer::newConnection, this, &TcpServer::newClientConnection);
    if(chatServer->listen(QHostAddress::Any, 8001))
        qDebug() << "Server has started. Listening to port 8001";
    else
        qDebug() << "Server failed to start. Error: " + chatServer->errorString();
}

void TcpServer::sendMessageToClient(QString message)
{
    if(allClients->size() > 0)
        for(int i=0; i<allClients->size(); i++)
        {
            if(allClients->at(i)->isOpen() && allClients->at(i)->isWritable())
            {
                allClients->at(i)->write(message.toUtf8());
            }
        }
}

void TcpServer::newClientConnection()
{
    QTcpSocket* client = chatServer->nextPendingConnection();
    QString ipAddress = client->peerAddress().toString();
    int port = client->peerPort();
    connect(client, &QTcpSocket::disconnected, this, &TcpServer::socketDisconnected);
    connect(client, &QTcpSocket::readyRead, this, &TcpServer::socketReadReady);
    connect(client, &QTcpSocket::stateChanged, this, &TcpServer::socketStateChanged);
    allClients->push_back(client);
    qDebug() << "Socket connected from " + ipAddress + ":" + QString::number(port);
}

void TcpServer::socketDisconnected()
{
    QTcpSocket* client = qobject_cast<QTcpSocket*>(QObject::sender());
    QString socketIpAddress = client->peerAddress().toString();
    int port = client->peerPort();
    qDebug() << "Socket disconnected from " + socketIpAddress + ":" + QString::number(port);
}

void TcpServer::socketReadReady()
{
    QTcpSocket* client = qobject_cast<QTcpSocket*>(QObject::sender());
    QString socketIpAddress = client->peerAddress().toString();
    int port = client->peerPort();
    QString data = QString(client->readAll());
    qDebug() << "Message: " + data + " (" + socketIpAddress + ":" + QString::number(port) + ")";
    sendMessageToClient(data);
}

void TcpServer::socketStateChanged(QAbstractSocket::SocketState state)
{
    QString desc;
    if(state == QAbstractSocket::UnconnectedState)
        desc = "The socket is not connected.";
    else if(state == QAbstractSocket::HostLookupState)
        desc = "The socket is performing a host name lookup.";
    else if(state == QAbstractSocket::ConnectingState)
        desc = "The socket has started establishing a connection";
    else if(state == QAbstractSocket::ConnectedState)
        desc = "A connection is established";
    else if(state == QAbstractSocket::BoundState)
        desc = "The socket is bound to an address and port";
    else if(state == QAbstractSocket::ClosingState)
        desc = "The socket is about to close";
    else if(state == QAbstractSocket::ListeningState)
        desc = "For internal use only";
    QTcpSocket* client = qobject_cast<QTcpSocket*>(QObject::sender());
    QString socketIpAddress = client->peerAddress().toString();
    int port = client->peerPort();
    qDebug() << "Socket State changed (" + socketIpAddress + ":" + QString::number(port) + ")";
}

TcpClientDialog.h

#ifndef TCPCLIENTDIALOG_H
#define TCPCLIENTDIALOG_H

#include <QDialog>

#include <QDebug>
#include <QTcpSocket>

namespace Ui {
class TcpClientDialog;
}

class TcpClientDialog : public QDialog
{
    Q_OBJECT

public:
    explicit TcpClientDialog(QWidget *parent = nullptr);
    ~TcpClientDialog();

    void printMessage(QString message);

private:
    Ui::TcpClientDialog *ui;

    bool connectedToHost;
    QTcpSocket* socket;

private slots:
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
    void socketConnected();
    void socketDisconnected();
    void socketReadyRead();
};

#endif // TCPCLIENTDIALOG_H

TcpClientDialog.cpp

#include "tcpclientdialog.h"
#include "ui_tcpclientdialog.h"

TcpClientDialog::TcpClientDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::TcpClientDialog)
{
    ui->setupUi(this);

    connectedToHost = false;
    setWindowTitle("TCP client");
}

TcpClientDialog::~TcpClientDialog()
{
    delete ui;
}

void TcpClientDialog::printMessage(QString message)
{
    ui->textBrowser->append(message);
}

void TcpClientDialog::on_pushButton_clicked()
{
    qDebug() << "start connect";
    if(!connectedToHost)
    {
        socket = new QTcpSocket();
        connect(socket, &QTcpSocket::connected, this, &TcpClientDialog::socketConnected);
        connect(socket, &QTcpSocket::disconnected, this, &TcpClientDialog::socketDisconnected);
        connect(socket, &QTcpSocket::readyRead, this, &TcpClientDialog::socketReadyRead);
        qDebug() << "start connecting 127.0.0.1";
        socket->connectToHost("127.0.0.1", 8001);
    }
    else
    {
        QString name = ui->lineEdit->text();
        socket->write("<font color=\"Orange\">" + name.toUtf8() + " has left the chat room.</font>");
        socket->disconnectFromHost();
    }
}

void TcpClientDialog::on_pushButton_2_clicked()
{
    QString name = ui->lineEdit->text();
    QString message = ui->lineEdit_2->text();
    socket->write("<font color=\"Blue\">" + name.toUtf8() + "</font>: " + message.toUtf8());
    ui->lineEdit_2->clear();
}

void TcpClientDialog::socketConnected()
{
    qDebug() << "Connected to server.";
    printMessage("<font color=\"Green\">Connected to server.</font>");
    QString name = ui->lineEdit_2->text();
    socket->write("<font color=\"Purple\">" + name.toUtf8() + " has joined the chat room.</font>");
    ui->pushButton->setText("Disconnect");
    connectedToHost = true;
}

void TcpClientDialog::socketDisconnected()
{
    qDebug() << "Disconnected from server.";
    printMessage("<font color=\"Red\">Disconnected from server.</font>");
    ui->pushButton->setText("Connect");
    connectedToHost = false;
}

void TcpClientDialog::socketReadyRead()
{
    printMessage(socket->readAll());
}

运行结果如下:

多谢,亲爱的美美。

猜你喜欢

转载自blog.csdn.net/islinyoubiao/article/details/113770296