Qt TCP服务端和客户端程序

1、服务端程序

利用QtCreator新建QMainWindow或QWidget工程,绘制UI如下所示。

mainwindow.h代码如下:

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QList>

#define MAXNUM  (9)

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    QTcpServer* myServer;
    QTcpSocket* myClient;
    QList<QTcpSocket*> arrayClient;

private slots:
    void on_pushButtonServerSet_clicked();

    void doProcessNewConnection();
    void doProcessDiconnected();
    void doProcessReadyRead();

    void on_pushButtonClientSend_clicked();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp代码如下:

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("TCP服务端程序");
    myServer = new QTcpServer(this);
    myClient = new QTcpSocket(this);
}

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

void MainWindow::on_pushButtonServerSet_clicked()
{
    QString myAddr;
    //手动设置ip
    myAddr = ui->lineEditServerIP->text();
    QString myPort = ui->lineEditServerPort->text();
    QString msg;
    bool ret = myServer->listen(QHostAddress(myAddr),myPort.toUInt());
    if(!ret) {
        msg = "绑定失败";
    } else {
        msg = "绑定成功";
        ui->pushButtonServerSet->setEnabled(false);
    }
    ui->textEditServer->append(msg);
    myServer->setMaxPendingConnections(MAXNUM);
    connect(myServer,SIGNAL(newConnection()),this,SLOT(doProcessNewConnection()));
    connect(myServer,SIGNAL(acceptError(QAbstractSocket::SocketError)),
            this,SLOT(doProcessAcceptError(QAbstractSocket::SocketError)));
}


void MainWindow::on_pushButtonClientSend_clicked()
{
    QString ip = ui->lineEditClientIP->text();
    QString port = ui->lineEditClientPort->text();
    //查找对应的客户
    for(int i=0;i<arrayClient.length();i++)
    {
        if(arrayClient.at(i)->peerAddress().toString()==ip)
        {
            if(arrayClient.at(i)->peerPort() == port.toUInt())
            {
                QString msg = ui->textEditClient->toPlainText();\
                    arrayClient.at(i)->write(msg.toUtf8());
                ui->textEditClient->clear();
                break;
            }
        }
    }
}

void MainWindow::doProcessNewConnection()
{
    myClient = myServer->nextPendingConnection();
    arrayClient.append(myClient);
    QString msg = QString("客户端[%1:%2] 连入!")
                      .arg(myClient->peerAddress().toString())
                      .arg(myClient->peerPort());
    ui->textEditServer->append(msg);
    //客户端断开
    connect(myClient,SIGNAL(diconnected()),this,SLOT(doProcessDiconnected()));
    //读取内容
    connect(myClient,SIGNAL(readyRead()),this,SLOT(doProcessReadyRead()));
}

void MainWindow::doProcessDiconnected()
{
    QTcpSocket *client = (QTcpSocket *)this->sender();

    QString msg = QString("客户端[%1:%2] 退出!")
                      .arg(client->peerAddress().toString())
                      .arg(client->peerPort());
    ui->textEditServer->append(msg);
    //删除对应客户端
    for(int i= 0;i<arrayClient.length();i++)
    {
        if(arrayClient.at(i)->peerAddress() == client->peerAddress())
        {
            if(arrayClient.at(i)->peerPort() == client->peerPort())
            {
                arrayClient.removeAt(i);
                break;
            }
        }
    }
}

void MainWindow::doProcessReadyRead()
{
    QTcpSocket *client = (QTcpSocket *)this->sender();
    QString str1 = QString(QString("客户端[%1:%2] 说:")
                               .arg(client->peerAddress().toString())
                               .arg(client->peerPort()));
    QString msg;
    QString str2;
    while (!client->atEnd())
    {
        msg.append(QString(client->readAll()));
    }
    str2 = QString("%1%2").arg(str1).arg(msg);
    ui->textEditServer->append(str2);
}

2、客户端程序

利用QtCreator新建QWidget或QMainWindow工程,绘制UI如下所示。

widget.h代码如下:

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    QTcpSocket* myClient;

private slots:
    void on_pushButtonConnect_clicked();

    void on_pushButtonSend_clicked();

    void dorProcessReadyRead();
    void doProcessConnected();
    void doProcessDisconnected();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp代码如下:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("TCP客户端程序");
    myClient = new QTcpSocket(this);
}

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

void Widget::on_pushButtonConnect_clicked()
{
    QString servIp = ui->lineEditIP->text();
    QString servPort = ui->lineEditPort->text();
    myClient->connectToHost(QHostAddress(servIp),servPort.toUInt());
    //myClient->connectToHost(servIp,servPort.toShort());
    connect(myClient,SIGNAL(connected()),this,SLOT(doProcessConnected()));
    connect(myClient,SIGNAL(readyRead()),this,SLOT(dorProcessReadyRead()));
    connect(myClient,SIGNAL(disconnected()),this,SLOT(doProcessDisconnected()));
    // connect(myClient,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(doProcessError(QAbstractSocket::SocketError)));
}


void Widget::on_pushButtonSend_clicked()
{
    QString msg = ui->textEdit_2->toPlainText();
    int ret = myClient->write(msg.toUtf8());
    if(ret<=0)
        return;
    ui->textEdit_2->clear();
}
void Widget::doProcessConnected()
{
    ui->textEdit->append("服务器连接成功!");
}
void Widget::doProcessDisconnected()
{
    ui->textEdit->append("服务器断开连接!");
}
void Widget::dorProcessReadyRead()
{
    QString msg,str1,str2;
    str1 = QString(" 服务器[%1:%2] 说:")
               .arg(myClient->peerAddress().toString())
               .arg(myClient->peerPort());
    while(!myClient->atEnd())
    {
        str2.append(QString(myClient->readAll()));
    }
    msg = QString("%1%2").arg(str1).arg(str2);
    ui->textEdit->append(msg);
}

3、运行示例

先后编译运行服务端和客户端。

在服务端中输入IP和端口号然后点击绑定按钮,绑定成功后,在客户端输入服务端的IP和端口后点击连接按钮。连接成功,在客服端发送信息,服务端收到后,可填入客户端的IP和Port回复信息给客户端。

运行示意图如下。

相关推荐
Brandon汐9 分钟前
Linux文件传输:让数据飞起来!
linux·运维·网络
计算机鬼才~9 分钟前
网络安全·第二天·ARP协议安全分析
网络·安全·web安全·arp
昊昊该干饭了3 小时前
玩转代理 IP :实战爬虫案例
运维·服务器·爬虫·网络协议·tcp/ip·网络爬虫
菌菌巧乐兹3 小时前
电脑知识 | TCP通俗易懂详解 <一>
服务器·网络·tcp/ip
无名之逆4 小时前
[特殊字符] 超轻高性能的 Rust HTTP 服务器 —— Hyperlane [特殊字符][特殊字符]
java·服务器·开发语言·前端·网络·http·rust
稳联技术4 小时前
玻璃厂退火炉“温度智囊”:Profinet转ModbusRTU网关
运维·服务器·网络
"_rainbow_"5 小时前
Qt中的鼠标事件
开发语言·qt
小王努力学编程5 小时前
【Linux网络编程】UDP Echo Server的实现
linux·运维·服务器·网络·c++·学习·udp
独行侠1@tcl5 小时前
3.BGP路由黑洞
网络·智能路由器
Dklau-c6 小时前
『Linux_网络』 第一章 网络基础概念
linux·服务器·网络