Qt网络-TCP,实现服务器、客户端传递文本消息和文件(二)

客户端、服务器源码地址

原理接上篇:Qt网络-TCP,实现服务器、客户端传递文本消息和文件(一)

程序效果

在这里插入图片描述
1. 主要功能:TCP方式建立连接,实现服务器和客户端互发消息,文件传输只实现了单向传输,客户端向服务器传送文件,但是从服务器向客户端传文件原理也是一样的,代码都有,实现起来也简单,我这里就不实现了,这篇博客主要是了解传输原理和流程,了解如何传输数据,还可以增加是否接收文件等等很多功能,可以根据需要自己尝试实现,了解了传输过程,什么功能都可以做。
2. 程序里文本消息和文件传输分别用了两个socket,这样在传输大文件的时候依然可以发送文本消息,互不影响。

1. 服务器

(1)服务器头文件:

私有变量:

private:
    QLabel  *m_labListen; // 状态栏标签
    QLabel  *m_labSocketState; // 状态栏标签
    QTcpServer *m_tcpServer; // TCP 服务器
    
    QTcpSocket *m_tcpTextSocket; // 文本Socket
    QTcpSocket *m_tcpFileSocket; // 文件socket,使用两个socket,传输时互不影响
    
	// 传输文件时使用的变量
    qint64 m_totalBytes;  // 存放总大小信息
    qint64 m_bytesReceived;  // 已收到数据的大小
    qint64 m_fileNameSize;  // 文件名的大小信息
    QString m_fileName;   // 存放文件名
    QFile *m_localFile;   // 本地文件, 接收的文件存在程序运行路径
    QByteArray m_inBlock;

私有槽:

private slots:

    void    onNewConnection(); // QTcpServer的newConnection()信号

    void    onSocketStateChange(QAbstractSocket::SocketState socketState);
    void    onClientConnected(); // 文本消息Socket connected
    void    onClientDisconnected();// 文本Socket disconnected
    void    onSocketReadyRead();// 读取文本socket传入的数据

    void onFileClientConnected(); // 文件socket连接时触发此槽函数
    void onFileClientDisconnected(); // 文件socket断开连接时出发此槽函数

    void updateServerProgress();  //更新进度条,接收数据

    void displayError(QAbstractSocket::SocketError socketError); //显示错误

    void on_actStart_triggered(); // 开启监听

    void on_actStop_triggered(); // 停止监听

    void on_actClear_triggered(); // 清空文本框

    void on_btnSend_clicked(); // 发送消息

服务器源文件cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include    <QtNetwork>
#include <QMessageBox>

QString MainWindow::getLocalIP()
{//获取本机IPv4地址
    QString hostName = QHostInfo::localHostName();//本地主机名
    QHostInfo hostInfo = QHostInfo::fromName(hostName);
    QString localIP = "";

    QList<QHostAddress> addList = hostInfo.addresses();//

    if (!addList.isEmpty())
    {
        for (int i=0;i<addList.count();i++)
        {
            QHostAddress aHost = addList.at(i);
            if (QAbstractSocket::IPv4Protocol == aHost.protocol())
            {
                localIP = aHost.toString();
                break;
            }
        }
    }

    return localIP;
}

void MainWindow::closeEvent(QCloseEvent *event)
{//关闭窗口时停止监听
    if (m_tcpServer->isListening())
        m_tcpServer->close(); //停止网络监听
    event->accept();
}

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

    m_labListen=new QLabel("监听状态:");
    m_labListen->setMinimumWidth(150);
    ui->statusBar->addWidget(m_labListen);

    m_labSocketState=new QLabel("Socket状态:");//
    m_labSocketState->setMinimumWidth(200);
    ui->statusBar->addWidget(m_labSocketState);

    QString localIP=getLocalIP();//本机IP
    this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP);
    ui->comboIP->addItem(localIP);

    m_totalBytes = 0;
    m_bytesReceived = 0;
    m_fileNameSize = 0;

    m_tcpServer = new QTcpServer(this);
    connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));

    m_tcpTextSocket = new QTcpSocket(this);
    m_tcpFileSocket = new QTcpSocket(this);
}

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

void MainWindow::onNewConnection()
{
    if (m_tcpTextSocket->state() == QAbstractSocket::UnconnectedState)
    {
        m_tcpTextSocket = m_tcpServer->nextPendingConnection(); // 创建socket

        connect(m_tcpTextSocket, SIGNAL(connected()),
                this, SLOT(onClientConnected()));
        onClientConnected();//

        connect(m_tcpTextSocket, SIGNAL(disconnected()),
                this, SLOT(onClientDisconnected()));

        connect(m_tcpTextSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
        onSocketStateChange(m_tcpTextSocket->state());

        connect(m_tcpTextSocket,SIGNAL(readyRead()),
                this,SLOT(onSocketReadyRead()));
        return;
    }

    if (m_tcpFileSocket->state() == QAbstractSocket::UnconnectedState)
    {
        m_tcpFileSocket = m_tcpServer->nextPendingConnection(); // 创建socket
        connect(m_tcpFileSocket, SIGNAL(connected()),
                this, SLOT(onFileClientConnected()));
        onFileClientConnected();//m_tcpFileSocket->deleteLater();

        connect(m_tcpFileSocket, SIGNAL(disconnected()),
                this, SLOT(onFileClientDisconnected()));

        connect(m_tcpFileSocket, SIGNAL(readyRead()), this, SLOT(updateServerProgress()));
        connect(m_tcpFileSocket, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(displayError(QAbstractSocket::SocketError)));
    }


}

void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{//socket状态变化时
    switch(socketState)
    {
    case QAbstractSocket::UnconnectedState:
        m_labSocketState->setText("scoket状态:UnconnectedState");
        break;
    case QAbstractSocket::HostLookupState:
        m_labSocketState->setText("scoket状态:HostLookupState");
        break;
    case QAbstractSocket::ConnectingState:
        m_labSocketState->setText("scoket状态:ConnectingState");
        break;

    case QAbstractSocket::ConnectedState:
        m_labSocketState->setText("scoket状态:ConnectedState");
        break;

    case QAbstractSocket::BoundState:
        m_labSocketState->setText("scoket状态:BoundState");
        break;

    case QAbstractSocket::ClosingState:
        m_labSocketState->setText("scoket状态:ClosingState");
        break;

    case QAbstractSocket::ListeningState:
        m_labSocketState->setText("scoket状态:ListeningState");
    }
}

void MainWindow::onClientConnected()
{//客户端接入时
    ui->plainTextEdit->appendPlainText("**client socket connected");
    ui->plainTextEdit->appendPlainText("**peer address:"+
                                   m_tcpTextSocket->peerAddress().toString());
    ui->plainTextEdit->appendPlainText("**peer port:"+
                                   QString::number(m_tcpTextSocket->peerPort()));
}

void MainWindow::onFileClientConnected()
{
    ui->plainTextEdit_file->appendPlainText("**client socket connected");
    ui->plainTextEdit_file->appendPlainText("**peer address:"+
                                   m_tcpFileSocket->peerAddress().toString());
    ui->plainTextEdit_file->appendPlainText("**peer port:"+
                                   QString::number(m_tcpFileSocket->peerPort()));
}

void MainWindow::onClientDisconnected()
{//客户端断开连接时
    ui->plainTextEdit->appendPlainText("**client socket disconnected");
    m_tcpTextSocket->close();
}

void MainWindow::onFileClientDisconnected()
{
    ui->plainTextEdit_file->appendPlainText("**client socket disconnected");
    m_tcpFileSocket->close();
}

void MainWindow::onSocketReadyRead()
{//读取缓冲区行文本
//    QStringList   lines;
    while(m_tcpTextSocket->canReadLine())
        ui->plainTextEdit->appendPlainText("[in] "+m_tcpTextSocket->readLine());
}

void MainWindow::on_actStart_triggered()
{//开始监听
    QString IP = ui->comboIP->currentText();//IP地址
    quint16 port = ui->spinPort->value();//端口
    QHostAddress addr(IP);

    // text
    m_tcpServer->listen(addr, port);//
//    m_tcpServer->listen(QHostAddress::LocalHost,port);// Equivalent to QHostAddress("127.0.0.1").
    ui->plainTextEdit->appendPlainText("**开始监听...");
    ui->plainTextEdit->appendPlainText("**服务器地址:"
                       +m_tcpServer->serverAddress().toString());
    ui->plainTextEdit->appendPlainText("**服务器端口:"
                       +QString::number(m_tcpServer->serverPort()));

    // file
    ui->plainTextEdit_file->appendPlainText("**开始监听...");
    ui->plainTextEdit_file->appendPlainText("**服务器地址:"
                       + m_tcpServer->serverAddress().toString());
    ui->plainTextEdit_file->appendPlainText("**服务器端口:"
                       + QString::number(m_tcpServer->serverPort()));

    ui->actStart->setEnabled(false);
    ui->actStop->setEnabled(true);

    m_labListen->setText("监听状态:正在监听");
}

void MainWindow::on_actStop_triggered()
{//停止监听
    if (m_tcpServer->isListening()) // m_tcpServer正在监听
    {
        m_tcpServer->close(); // 停止监听
        ui->actStart->setEnabled(true);
        ui->actStop->setEnabled(false);
        m_labListen->setText("监听状态:已停止监听");
    }
}

void MainWindow::on_actClear_triggered()
{
    ui->plainTextEdit->clear();
    ui->plainTextEdit_file->clear();
}

void MainWindow::on_btnSend_clicked()
{//发送一行字符串,以换行符结束
    QString  msg=ui->editMsg->text();

    if (msg.isEmpty())
    {
        QMessageBox::information(this, "提示", "发送的消息不能为空!");
        return;
    }

    ui->plainTextEdit->appendPlainText("[out] "+msg);
    ui->editMsg->clear();
    ui->editMsg->setFocus();

    QByteArray  str=msg.toUtf8();
    str.append('\n');//添加一个换行符
    m_tcpTextSocket->write(str);
}

void MainWindow::updateServerProgress()  //更新进度条,接收数据
{
   QDataStream in(m_tcpFileSocket);
   in.setVersion(QDataStream::Qt_5_9);
   if (m_bytesReceived <= sizeof(qint64)*2)
   { //如果接收到的数据小于16个字节,那么是刚开始接收数据,我们保存接收到的的头文件信息
       if((m_tcpFileSocket->bytesAvailable() >= sizeof(qint64)*2) && (m_fileNameSize == 0))
       { //接收数据总大小信息和文件名大小信息
           in >> m_totalBytes >> m_fileNameSize;
           m_bytesReceived += sizeof(qint64) * 2;
       }
       if((m_tcpFileSocket->bytesAvailable() >= m_fileNameSize) && (m_fileNameSize != 0))
       {  //接收文件名,并建立文件
           in >> m_fileName;
           ui->plainTextEdit_file->appendPlainText(tr("接收文件 %1 ...").arg(m_fileName));
           m_bytesReceived += m_fileNameSize;
           m_localFile= new QFile(QApplication::applicationDirPath() + "\\" + m_fileName);
           if(!m_localFile->open(QFile::WriteOnly))
           {
                qDebug() << "open file error!";
                return;
           }
       }
       else
           return;
   }
   if(m_bytesReceived < m_totalBytes)
   {  // 如果接收的数据小于总数据,那么写入文件
      m_bytesReceived += m_tcpFileSocket->bytesAvailable();
      m_inBlock= m_tcpFileSocket->readAll();
      m_localFile->write(m_inBlock);
      m_inBlock.resize(0);
   }
    //更新进度条
   ui->progressBar->setMaximum(m_totalBytes);
   ui->progressBar->setValue(m_bytesReceived);

   if(m_bytesReceived == m_totalBytes)
   { //接收数据完成时
        m_totalBytes = 0;
        m_bytesReceived = 0;
        m_fileNameSize = 0;
        m_localFile->close();
        ui->plainTextEdit_file->appendPlainText(QString("接收文件 %1 成功!").arg(m_fileName));
   }
}

void MainWindow::displayError(QAbstractSocket::SocketError) //错误处理
{
    ui->plainTextEdit_file->appendPlainText(m_tcpFileSocket->errorString());
    m_tcpFileSocket->close();
    ui->progressBar->reset();
}

2. 客户端

头文件

private:
    QTcpSocket  *m_tcpTextClient;  //文本消息socket
    QLabel  *m_labSocketState;  //状态栏显示标签

    QFile *m_localFile;  //要发送的文件
    qint64 m_totalBytes;  //数据总大小
    qint64 m_bytesWritten;  //已经发送数据大小
    qint64 m_bytesToWrite;   //剩余数据大小
    qint64 m_loadSize;   //每次发送数据的大小
    QString m_fileName;  //保存文件路径
    QByteArray m_outBlock;  //数据缓冲区,即存放每次要发送的数据
    QTcpSocket  *m_tcpFileClient;  //文件消息socket


    QString getLocalIP();//获取本机IP地址
protected:
    void    closeEvent(QCloseEvent *event);


private slots:
    void    onConnected();
    void    onDisconnected();
    void    onSocketStateChange(QAbstractSocket::SocketState socketState);
    void    onSocketReadyRead();//读取socket传入的数据

    void    onFileConnected();
    void    onFileDisconnected();

    void startTransfer();  //发送文件大小等信息
    void updateClientProgress(qint64); //发送数据,更新进度条
    void displayError(QAbstractSocket::SocketError); //显示错误信息

    void on_actConnect_triggered();

    void on_actDisconnect_triggered();

    void on_actClear_triggered();

    void on_btnSend_clicked();

    void on_btnSelectFile_clicked();

    void on_btnSendFile_clicked();

客户端源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include    <QHostAddress>
#include    <QHostInfo>
#include <QMessageBox>
#include <QFileDialog>

QString MainWindow::getLocalIP()
{
    QString hostName=QHostInfo::localHostName();//本地主机名
    QHostInfo   hostInfo=QHostInfo::fromName(hostName);
    QString   localIP="";

    QList<QHostAddress> addList=hostInfo.addresses();//

    if (!addList.isEmpty())
    for (int i=0;i<addList.count();i++)
    {
        QHostAddress aHost=addList.at(i);
        if (QAbstractSocket::IPv4Protocol==aHost.protocol())
        {
            localIP=aHost.toString();
            break;
        }
    }
    return localIP;
}
void MainWindow::closeEvent(QCloseEvent *event)
{
    if (m_tcpTextClient->state()==QAbstractSocket::ConnectedState)
        m_tcpTextClient->disconnectFromHost();
    if (m_tcpFileClient->state()==QAbstractSocket::ConnectedState)
        m_tcpFileClient->disconnectFromHost();
    event->accept();
}

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

    m_loadSize = 4*1024; // 每次发送的文件数据大小
    m_totalBytes = 0;
    m_bytesWritten = 0;
    m_bytesToWrite = 0;

    m_tcpTextClient = new QTcpSocket(this); //创建socket变量
    m_tcpFileClient = new QTcpSocket(this);

    m_labSocketState = new QLabel("Socket状态:");//状态栏标签
    m_labSocketState->setMinimumWidth(250);
    ui->statusBar->addWidget(m_labSocketState);

    QString localIP = getLocalIP();//本机IP
    this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP);
    ui->comboServer->addItem(localIP);


    connect(m_tcpTextClient,SIGNAL(connected()),this,SLOT(onConnected()));
    connect(m_tcpTextClient,SIGNAL(disconnected()),this,SLOT(onDisconnected()));

    connect(m_tcpTextClient,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
    connect(m_tcpTextClient,SIGNAL(readyRead()),
            this,SLOT(onSocketReadyRead()));


    connect(m_tcpFileClient,SIGNAL(connected()),this,SLOT(onFileConnected()));
    connect(m_tcpFileClient,SIGNAL(disconnected()),this,SLOT(onFileDisconnected()));
    //当有数据发送成功时,更新进度条
    connect(m_tcpFileClient,SIGNAL(bytesWritten(qint64)),this,
           SLOT(updateClientProgress(qint64)));
    connect(m_tcpFileClient,SIGNAL(error(QAbstractSocket::SocketError)),this,
           SLOT(displayError(QAbstractSocket::SocketError)));

    ui->btnSendFile->setEnabled(false);
}

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

void MainWindow::onConnected()
{ //connected()信号槽函数
    ui->plainTextEdit->appendPlainText("**已连接到服务器");
    ui->plainTextEdit->appendPlainText("**peer address:"+
                                   m_tcpTextClient->peerAddress().toString());
    ui->plainTextEdit->appendPlainText("**peer port:"+
                                   QString::number(m_tcpTextClient->peerPort()));
    ui->actConnect->setEnabled(false);
    ui->actDisconnect->setEnabled(true);
}

void MainWindow::onDisconnected()
{//disConnected()信号槽函数
    ui->plainTextEdit->appendPlainText("**已断开与服务器的连接");
    ui->actConnect->setEnabled(true);
    ui->actDisconnect->setEnabled(false);
}

void MainWindow::onFileConnected()
{ //connected()信号槽函数
    ui->plainTextEdit_file->appendPlainText("**已连接到服务器");
    ui->plainTextEdit_file->appendPlainText("**peer address:"+
                                   m_tcpFileClient->peerAddress().toString());
    ui->plainTextEdit_file->appendPlainText("**peer port:"+
                                   QString::number(m_tcpFileClient->peerPort()));
}

void MainWindow::onFileDisconnected()
{//disConnected()信号槽函数
    ui->plainTextEdit_file->appendPlainText("**已断开与服务器的连接");
}

void MainWindow::onSocketReadyRead()
{//readyRead()信号槽函数
    while(m_tcpTextClient->canReadLine())
        ui->plainTextEdit->appendPlainText("[in] "+m_tcpTextClient->readLine());
}

void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{//stateChange()信号槽函数
    switch(socketState)
    {
    case QAbstractSocket::UnconnectedState:
        m_labSocketState->setText("scoket状态:UnconnectedState");
        break;
    case QAbstractSocket::HostLookupState:
        m_labSocketState->setText("scoket状态:HostLookupState");
        break;
    case QAbstractSocket::ConnectingState:
        m_labSocketState->setText("scoket状态:ConnectingState");
        break;

    case QAbstractSocket::ConnectedState:
        m_labSocketState->setText("scoket状态:ConnectedState");
        break;

    case QAbstractSocket::BoundState:
        m_labSocketState->setText("scoket状态:BoundState");
        break;

    case QAbstractSocket::ClosingState:
        m_labSocketState->setText("scoket状态:ClosingState");
        break;

    case QAbstractSocket::ListeningState:
        m_labSocketState->setText("scoket状态:ListeningState");
    }
}

void MainWindow::on_actConnect_triggered()
{//连接到服务器
    QString addr = ui->comboServer->currentText();
    quint16 port = ui->spinPort->value();
    m_tcpTextClient->connectToHost(addr, port);

    m_bytesWritten = 0; // 初始化已发送字节为0
    m_tcpFileClient->connectToHost(addr, port);
}

void MainWindow::on_actDisconnect_triggered()
{//断开与服务器的连接
    if (m_tcpTextClient->state()==QAbstractSocket::ConnectedState)
        m_tcpTextClient->disconnectFromHost();
    if (m_tcpFileClient->state()==QAbstractSocket::ConnectedState)
        m_tcpFileClient->disconnectFromHost();
}

void MainWindow::on_actClear_triggered()
{
    ui->plainTextEdit->clear();
    ui->plainTextEdit_file->clear();
}

void MainWindow::on_btnSend_clicked()
{//发送数据
    QString  msg=ui->editMsg->text();

    if (msg.isEmpty())
    {
        QMessageBox::information(this, "提示", "发送的消息不能为空!");
        return;
    }

    ui->plainTextEdit->appendPlainText("[out] "+msg);
    ui->editMsg->clear();
    ui->editMsg->setFocus();

    QByteArray  str=msg.toUtf8();
    str.append('\n');
    m_tcpTextClient->write(str);
}

void MainWindow::on_btnSelectFile_clicked()
{
    m_fileName = QFileDialog::getOpenFileName(this, "选择文件");
    if (!m_fileName.isEmpty())
    {
        ui->plainTextEdit_file->appendPlainText(QString("打开文件 %1 成功!").arg(m_fileName));
        ui->btnSendFile->setEnabled(true);
    }

}

void MainWindow::startTransfer()  //实现文件大小等信息的发送
{
    m_localFile = new QFile(m_fileName);
    if(!m_localFile->open(QFile::ReadOnly))
    {
       qDebug() << "open file error!";
       return;
    }

    // 文件总大小
    m_totalBytes = m_localFile->size();

    QDataStream sendOut(&m_outBlock, QIODevice::WriteOnly);
    sendOut.setVersion(QDataStream::Qt_5_9);
    QString currentFileName = m_fileName.right(m_fileName.size() - m_fileName.lastIndexOf('/')-1);

    // 依次写入文件总大小信息空间,文件名大小信息空间,文件名
    sendOut << qint64(0) << qint64(0) << currentFileName;

    // 总大小是文件名大小等信息和实际文件大小的总和
    m_totalBytes += m_outBlock.size();

    sendOut.device()->seek(0);
    // 返回outBolock的开始,用实际的大小信息代替两个qint64(0)空间
    sendOut<<m_totalBytes<<qint64((m_outBlock.size() - sizeof(qint64)*2));

    // 发送完头数据后剩余数据的大小
    m_bytesToWrite = m_totalBytes - m_tcpFileClient->write(m_outBlock);

    m_outBlock.resize(0);
}

// 更新进度条,实现文件的传送
void MainWindow::updateClientProgress(qint64 numBytes)
{
    // 已经发送数据的大小
    m_bytesWritten += (int)numBytes;

    if(m_bytesToWrite > 0) // 剩余数据大小
    {
        // 从文件中取出数据到发送缓冲区,每次发送loadSize大小的数据,这里设置为4KB,如果剩余的数据不足4KB,就发送剩余数据的大小
        m_outBlock = m_localFile->read(qMin(m_bytesToWrite, m_loadSize));

        // 从发送缓冲区发送数据,计算发送完一次数据后还剩余数据的大小
        m_bytesToWrite -= (int)m_tcpFileClient->write(m_outBlock);

        // 清空发送缓冲区
        m_outBlock.resize(0);

    } else
    {
        m_localFile->close(); // 没有数据待发送,则关闭文件
    }

    //更新进度条
    ui->progressBar->setMaximum(m_totalBytes);
    ui->progressBar->setValue(m_bytesWritten);

    if(m_bytesWritten == m_totalBytes) //发送完毕
    {
        ui->plainTextEdit_file->appendPlainText(QString("传送文件 %1 成功").arg(m_fileName));
        m_localFile->close();
    }
}

void MainWindow::on_btnSendFile_clicked()
{
    m_totalBytes = 0;
    m_bytesWritten = 0;
    m_bytesToWrite = 0;
    startTransfer();
}

void MainWindow::displayError(QAbstractSocket::SocketError) //显示错误
{
    ui->plainTextEdit_file->appendPlainText(m_tcpFileClient->errorString());
    m_tcpFileClient->close();
    ui->progressBar->reset();
}

以下是使用Qt制作TCP服务器客户端的基本步骤: 1. 创建Qt项目并添加网络模块 首先,在Qt Creator中创建一个新项目。在项目配置向导中,选择“Qt Widgets应用程序”模板。然后,打开.pro文件并添加以下行: ``` QT += network ``` 2. 创建TCP服务器Qt中,使用QTcpServer类来创建TCP服务器。在mainwindow.h文件中添加以下头文件: ``` #include <QTcpServer> ``` 然后,在MainWindow类中添加以下代码: ``` private: QTcpServer *server; ``` 在MainWindow类的构造函数中初始化server对象: ``` MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { server = new QTcpServer(this); connect(server, SIGNAL(newConnection()), this, SLOT(newConnection())); if(!server->listen(QHostAddress::Any, 1234)) { qDebug() << "Server could not start!"; } else { qDebug() << "Server started!"; } } ``` 这将创建一个TCP服务器,监听本地IP地址的1234端口。newConnection()函数是一个槽,当有新连接时会被调用。 在MainWindow类中添加newConnection()函数: ``` void MainWindow::newConnection() { QTcpSocket *socket = server->nextPendingConnection(); socket->write("Hello client!"); socket->flush(); socket->waitForBytesWritten(3000); socket->close(); } ``` 这个函数在有新连接时会被调用,然后向客户端发送一条消息并关闭连接。 3. 创建TCP客户端Qt中,使用QTcpSocket类来创建TCP客户端。在mainwindow.h文件中添加以下头文件: ``` #include <QTcpSocket> ``` 然后,在MainWindow类中添加以下代码: ``` private: QTcpSocket *socket; ``` 在MainWindow类的构造函数中初始化socket对象: ``` MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { socket = new QTcpSocket(this); connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); socket->connectToHost("127.0.0.1", 1234); } ``` 这将创建一个TCP客户端,并连接到本地IP地址的1234端口。readyRead()函数是一个槽,当有数据可读时会被调用。 在MainWindow类中添加readyRead()函数: ``` void MainWindow::readyRead() { QByteArray data = socket->readAll(); qDebug() << data; } ``` 这个函数在有数据可读时会被调用,并输出收到的数据。 这就是使用Qt制作TCP服务器客户端的基本步骤。可以根据实际需求对代码进行修改和扩展。
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VectorAL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值