【qt】 TCP编程小项目

话不多说,先一睹芳颜
在这里插入图片描述

一.服务端

1.界面设计

在这里插入图片描述

2.服务端获取主机地址

在这里插入图片描述

将主机地址放在了一个容器中.
在这里插入图片描述

3.初始化服务端

在这里插入图片描述
当有新的客户端请求连接时,会发出newConnection()的信号.

4.服务端开启监听

在这里插入图片描述
注意listen函数的参数类型,要转换一下.

5.套接字socket

当有客户端请求连接后,我们需要套接字来作为服务端和客户端的接口.
在这里插入图片描述

6.服务端的读写

当有信息可以读的时候,我们就可以来读信息.
在这里插入图片描述
在这里插入图片描述
发送信息用write,注意要用utf8编码.
在这里插入图片描述

7.socket的其他信号的槽函数

在这里插入图片描述

8.服务端关闭监听

在这里插入图片描述

9.完整代码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostInfo>
#include <QHostAddress>
#include <QLabel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_pushButtonOpen_clicked();

    void on_pushButtonClose_clicked();

    void onNewConnection();

    void onReadyRead();

    void onConnected();

    void onDisconnected();

    void onStateChanged(QAbstractSocket::SocketState socketState);

private:
    Ui::MainWindow *ui;

    QTcpServer *tcpServer;
    QTcpSocket *tcpSocket;
    QStringList addrs;
    QLabel *labelState;


    void initTCPServer();
    void getHostAddress();
    void sendMsg(const QString&str);
    void initLabel();
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

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

    initTCPServer();
    initLabel();

}

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


void MainWindow::on_pushButtonOpen_clicked()
{
    getHostAddress();
    int i=rand()%addrs.count();
    QString addr=addrs.at(i);
    ui->labelIP->setText("服务器地址:"+addr);
    quint16 port=rand()%9000+8000;
    ui->labelPort->setText("服务器端口:"+QString::number(port));
    QHostAddress IP(addr);
    tcpServer->listen(IP,port);

    ui->pushButtonOpen->setEnabled(false);
    ui->pushButtonClose->setEnabled(true);
    ui->labelIP->show();
    ui->labelPort->show();
}

void MainWindow::on_pushButtonClose_clicked()
{
    if(tcpServer->isListening())
    {
        tcpServer->close();
        ui->pushButtonOpen->setEnabled(true);
        ui->pushButtonClose->setEnabled(false);
        ui->labelIP->hide();
        ui->labelPort->hide();
    }
}

void MainWindow::onNewConnection()
{
    tcpSocket=tcpServer->nextPendingConnection();
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
    connect(tcpSocket,SIGNAL(connected()),this,SLOT(onConnected()));
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState socketState)),
            this,SLOT(onStateChanged(QAbstractSocket::SocketState)));
    onStateChanged(tcpSocket->state());
}


void MainWindow::onReadyRead()
{
    QString str;
    while(tcpSocket->canReadLine())
    {
        QString read=tcpSocket->readLine();
        //qDebug()<<tcpSocket->readLine()<<endl;
        if(read=="人有悲欢离合\n")
        {
            str="月有阴晴圆缺";
            sendMsg(str);
        }
        else if(read=="此情可待成追忆\n")
        {
            str="只是当时已惘然";
            sendMsg(str);
        }
        else if(read=="宁教我负天下人\n")
        {
            str="休教天下人负我";
            sendMsg(str);
        }
        else
        {
            str="喂喂喂!你在说啥?";
            sendMsg(str);
        }
    }
}

void MainWindow::onConnected()
{
    labelState->setText("连接状态: 已连接");
}

void MainWindow::onDisconnected()
{
    labelState->setText("连接状态: 已断开连接");
    tcpSocket->deleteLater();//之后删
}

void MainWindow::onStateChanged(QAbstractSocket::SocketState socketState)
{
    switch (socketState) {
    case QAbstractSocket::UnconnectedState:
        labelState->setText("连接状态: 已断开连接");
        break;
    case QAbstractSocket::ConnectedState:
        labelState->setText("连接状态: 已连接");
        break;
    }
}

void MainWindow::initTCPServer()
{
    tcpServer=new QTcpServer(this);
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
}

void MainWindow::getHostAddress()
{
    QHostInfo hostInfo =QHostInfo::fromName(QHostInfo::localHostName());
    QList<QHostAddress> lists=hostInfo.addresses();
    for(int i=0;i<lists.count();i++)
    {
        QHostAddress address=lists[i];
        if(address.protocol()==QAbstractSocket::IPv4Protocol)
        {
            addrs.append(address.toString());
        }
    }
}

void MainWindow::sendMsg(const QString &str)
{
    QByteArray msg= str.toUtf8();
    msg.append('\n');
    tcpSocket->write(msg);
}

void MainWindow::initLabel()
{
    labelState=new QLabel("连接状态: 未连接");
    ui->statusbar->addWidget(labelState);
    ui->labelIP->hide();
    ui->labelPort->hide();

    QLinearGradient gradient(0,0,ui->label->width(),ui->label->height());
    gradient.setColorAt(0,Qt::green);
    gradient.setColorAt(1,Qt::blue);

    QPalette palette;
    palette.setBrush(QPalette::WindowText,QBrush(gradient));
    ui->label->setPalette(palette);
}

二.客户端

1.界面设计

在这里插入图片描述

2.套接字的初始化

在这里插入图片描述

3.连接服务器

在这里插入图片描述
如果连接成功,就弹出我们的发送框.
在这里插入图片描述

这里的tcpSocketGet是在对话框中获取到套接字的,然后可以来发送信息.
在这里插入图片描述

4.界面设计师类

在这里插入图片描述
在这里插入图片描述

5.客户端的读写

在这里插入图片描述
读到的信息添加到对话框中.
在这里插入图片描述
发送信息:
在这里插入图片描述
发送的信息都添加了一个换行符,因为这样可以判断一行,然后对方进行读取.

6.客户端关闭连接

在这里插入图片描述

7.完整代码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QHostAddress>
#include <QLabel>
#include <dialog.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_pushButtonConnect_clicked();

    void on_pushButtonDisConnect_clicked();

    void onConnected();

    void onDisconnected();

    void onReadyRead();

private:
    Ui::MainWindow *ui;

    QTcpSocket*tcpSocket;

    QLabel* labState;
    QLabel* labIP;
    QLabel* labPort;
    Dialog* chat;


    void initTCPSocket();
    void intitLabel();
};
#endif // MAINWINDOW_H

mainwindow.cpp

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

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

    initTCPSocket();
    intitLabel();
}

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

void MainWindow::initTCPSocket()
{
    tcpSocket=new QTcpSocket(this);
    connect(tcpSocket,SIGNAL(connected()),this,SLOT(onConnected()));
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onReadyRead()));

}

void MainWindow::intitLabel()
{
    labState=new QLabel(this);
    labState->setMinimumWidth(100);
    labPort=new QLabel(this);
    labPort->setMinimumWidth(100);
    labIP=new QLabel(this);
    this->statusBar()->addWidget(labState);
    this->statusBar()->addWidget(labPort);
    this->statusBar()->addWidget(labIP);
}


void MainWindow::on_pushButtonConnect_clicked()
{
    QString addr=ui->lineEditAddr->text();
    QString port=ui->lineEditProt->text();
    if(addr==NULL||port==NULL)return;
    QHostAddress IP(addr);
    tcpSocket->connectToHost(IP,port.toInt());
}

void MainWindow::on_pushButtonDisConnect_clicked()
{
    if(tcpSocket->state()==QAbstractSocket::ConnectedState)
    {
        tcpSocket->disconnectFromHost();
        chat->close();
    }
}

void MainWindow::onConnected()
{
    labState->setText("连接状态: 已连接");
    labPort->setText("服务器端口: "+QString::number(tcpSocket->peerPort()));
    labIP->setText("服务器IP: "+tcpSocket->peerAddress().toString());
    chat=new Dialog(this);
    //this->hide();
    chat->tcpSocketGet(tcpSocket);
    chat->show();
}

void MainWindow::onDisconnected()
{
    labState->setText("连接状态: 已断开连接");
    labState->clear();
    labIP->clear();
    labPort->clear();
}


void MainWindow::onReadyRead()
{
    while(tcpSocket->canReadLine())
    {
        QString str=tcpSocket->readLine();
        chat->setMsg(str);
    }
}

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QTcpSocket>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

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

    void setMsg(const QString&str);
    void tcpSocketGet(QTcpSocket *tcpSocket);

private slots:
    void on_pushButton_clicked();

private:
    Ui::Dialog *ui;
    QTcpSocket*tcpSocket;


protected:
    void closeEvent(QCloseEvent*event);

};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include <QDebug>
#include <QHostAddress>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    ui->plainTextEdit->setReadOnly(true);
}

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

void Dialog::setMsg(const QString &str)
{
    ui->plainTextEdit->appendPlainText("服务器: "+str);
}

void Dialog::tcpSocketGet(QTcpSocket *tcpSocket)
{
    this->tcpSocket=tcpSocket;
    //qDebug()<<this->tcpSocket->peerAddress();
}

void Dialog::on_pushButton_clicked()
{
    QString str=ui->lineEdit->text();
    QByteArray msg=str.toUtf8();
    msg.append('\n');
    tcpSocket->write(msg);
    ui->plainTextEdit->appendPlainText("客户: "+str);
    ui->lineEdit->clear();
    ui->lineEdit->setFocus();
}

void Dialog::closeEvent(QCloseEvent *event)
{
    if(tcpSocket->state()==QAbstractSocket::ConnectedState)
    {
        tcpSocket->disconnectFromHost();
    }

    event->accept();
}

三.结语

当然我这里只是稍微的演示一下,你也可以自己在服务端做手脚,自己发送信息也可以.

念头通达,现在应该算是炼气期1层.

  • 34
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Qt中,可以使用QTcpSocket类来编写TCP客户端程序发送中文。 首先,需要在项目文件中引入QTcpSocket头文件和Qt网络模块: ``` #include <QTcpSocket> #include <QtNetwork> ``` 然后,可以创建一个QTcpSocket对象,并连接到服务器: ``` QTcpSocket* socket = new QTcpSocket(this); socket->connectToHost("服务器IP地址", 端口号); ``` 接下来,我们可以通过socket对象的write()函数来发送中文数据。由于中文字符是Unicode编码,需要将QString转换为QByteArray,并使用UTF-8编码发送: ``` QString chineseStr = "中文内容"; QByteArray data = chineseStr.toUtf8(); socket->write(data); ``` 最后,可以通过调用socket对象的flush()函数来确保数据已经发送: ``` socket->flush(); ``` 需要注意的是,通过socket发送中文数据时,接收方也必须使用相应的解码方式(如UTF-8)来正确解析接收到的数据。 ### 回答2: 在Qt中编写TCP客户端程序发送中文需要进行以下几个步骤: 1. 创建TCP客户端对象:使用`QTcpSocket`类或者`QSslSocket`类创建一个TCP客户端对象。 2. 连接到服务器:使用`connectToHost()`函数将客户端连接到指定的服务器的IP地址和端口号。 3. 发送数据:在连接成功后,可以使用`write()`函数发送数据。对于中文字符,需要将其转换为字节流发送,可以使用`toUtf8()`函数将中文字符转换为UTF-8编码的字节流再发送。 以下是一个简单的例子: ```cpp #include <QtNetwork> int main() { QTcpSocket client; client.connectToHost("127.0.0.1", 1234); if (client.waitForConnected(3000)) // 等待连接建立 { QByteArray data; QString chineseText = "你好世界"; data = chineseText.toUtf8(); // 将中文字符转换为UTF-8编码的字节流 client.write(data); // 发送中文字符数据 client.waitForBytesWritten(3000); // 等待数据发送完成 client.close(); // 关闭连接 } } ``` 以上是一个简单的示例,连接建立成功后,将中文字符“你好世界”转换为UTF-8编码的字节流发送给服务器端。在实际的开发中,可能需要添加错误处理、数据读取和接收的逻辑等。 ### 回答3: 在Qt中编写TCP客户端程序发送中文,可以按照以下步骤进行: 1. 首先,在Qt项目中添加Qt网络模块,在.pro文件中添加`QT += network`语句。 2. 创建一个TCP客户端类,继承自QTcpSocket或者QTcpSocket的子类,用于建立与服务器的连接和发送数据。 3. 在客户端类中,使用`connectToHost()`函数连接到服务器的IP地址和端口号。 4. 记得在连接建立后,使用`waitForConnected()`函数等待连接成功。 5. 使用`write()`函数向服务器发送数据,将要发送的中文数据转换为字节流格式。可以使用QString的toUtf8()函数进行转换。 例如: ```cpp // TCPClient类中的发送函数 void TCPClient::sendData(const QString& data) { QByteArray byteData = data.toUtf8(); // 将中文转换为字节流 if (this->state() == QAbstractSocket::ConnectedState) { this->write(byteData); this->waitForBytesWritten(); } } ``` 6. 关闭连接时,可以使用`disconnectFromHost()`函数断开与服务器的连接。 请注意,发送和接收中文数据时,需要确保服务器和客户端使用相同的字符编码,例如UTF-8。 以上是一个简单的示例,可以根据具体的应用场景来进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值