QT学习——Tcp客户端通信(本地回环)

1.Linux下Tcp通信

2.Qt下Tcp通信

    1)Tcp框架——简图

下面的文本框是写入文本,上面的是显示发送后接收到的信息。这里发送的消息并不会立刻显示到界面上,而是要通过 readyRead() 的函数读取,即是做接受处理。然后才会显示发送的内容。
3.代码如下(ui界面直接拖控件实现)
1)第一部分
Tcp-socket.pro

QT += core gui network      //要用到网络,所以在 .pro文件里加入network。

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Tcp-socket
TEMPLATE = app


SOURCES += main.cpp\
serverwidget.cpp \
clientwidget.cpp

HEADERS += serverwidget.h \
clientwidget.h

FORMS += serverwidget.ui \
clientwidget.ui

CONFIG += C++11       //利用 lamda 表达式要加上这个
2)第二部分(服务器窗口代码)
serverwidget.h  (头文件)

#ifndef SERVERWIDGET_H
#define SERVERWIDGET_H

#include <QWidget>
#include <QTcpServer> //监听套接字          只有服务器部分是需要两个套接字的
#include <QTcpSocket> //通信套接字

namespace Ui
{
    class ServerWidget;
}

class ServerWidget : public QWidget
{
    Q_OBJECT

    public:
    explicit ServerWidget(QWidget *parent = 0);
    ~ServerWidget();

    private slots:
    void on_ButtonSend_clicked();

    void on_ButtonClose_clicked();

    private:
    Ui::ServerWidget *ui;

    QTcpServer *tcpServer; //监听套接字                          
    QTcpSocket *tcpSocket; //通信套接字
};

#endif // SERVERWIDGET_H

serverwidget.cpp (源文件)

#include "serverwidget.h"
#include "ui_serverwidget.h"

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

    tcpServer = NULL;            //防止在未输入之前点击按键导致服务器没有收到数据而出现程序异常
    tcpSocket = NULL;

    setWindowTitle("服务器:8888");

    //监听套接字,动态分配空间。指定父对象,让其自动回收空间
    tcpServer = new QTcpServer(this);   
    tcpServer->listen(QHostAddress::Any,                    8888);
                             主机地址         绑定网卡所有IP        端口 
    connect(tcpServer, &QTcpServer::newConnection,
    [=]()
    {                                                                                                                                                                          lamda表达式
        //取出建立好的套接字
        tcpSocket = tcpServer->nextPendingConnection();
        //获取对方的IP地址和端口
        QString ip = tcpSocket->peerAddress().toString();
                                            获取对方的IP地址,并将对方的地址转换成字符串
        qint16 port = tcpSocket->peerPort();
        端口号是int整型                    获取对方的端口号                      
        QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);    //IP、端口的显示的形式
        ui->textEditread->setText(temp);    //显示IP、端口
        connect(tcpSocket, &QTcpSocket::readyRead, //这个槽函数要放在这里,读取上面的内容。若放在外面,先执行构造函数QTcpSocket *tcpSocket 但是这个时候Tcpsocket还没有动态分配空间,指针
            [=]()                                                              //是野指针,没有内容,程序异常结束
            {                                                                                                                                                                                  
            //从通信套接字中取出内容
            QByteArray array = tcpSocket->readAll();
            ui->textEditread->append(array);   //确定将内容赋值给输入框
            }
            );
    }
    );
}

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

void ServerWidget::on_ButtonSend_clicked()
{
    if(NULL == tcpSocket)        //防止在未输入之前点击按键导致服务器没有收到数据而出现程序异常
    {
        return;
    }
    //获取编辑区的内容
    QString str = ui->textEditwrite->toPlainText();
    //给对方发送数据,使用套接字tcpSocket
    tcpSocket->write(str.toUtf8().data());
}

void ServerWidget::on_ButtonClose_clicked()
{
    if(NULL == tcpSocket)   
    {
        return;
    }
//主动和客户端端口断开
    tcpSocket->disconnectFromHost();
    tcpSocket->close();
    ui->textEditread->setText("和客户端断开连接");
    tcpSocket = NULL;
}

3)第三部分(客户端)
clientwidget.h  (头文件)

#ifndef CLIENTWIDGET_H
#define CLIENTWIDGET_H

#include <QWidget>
#include <QTcpSocket>      //客户端只需要一个通信套接字

namespace Ui 
{
    class ClientWidget;
}

class ClientWidget : public QWidget
{
    Q_OBJECT

    public:
        explicit ClientWidget(QWidget *parent = 0);
        ~ClientWidget();

    private slots:
    void on_connect_clicked();

    void on_send_clicked();

    void on_close_clicked();

    private:
    Ui::ClientWidget *ui;
    QTcpSocket *tcpSocket;
};

#endif // CLIENTWIDGET_H


clientwidget.h (源文件)

#include "clientwidget.h"
#include "ui_clientwidget.h"
#include <QHostAddress>

ClientWidget::ClientWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ClientWidget)
{
    ui->setupUi(this);
    setWindowTitle("客户端");

    tcpSocket = NULL;

    tcpSocket = new QTcpSocket(this);
    connect(tcpSocket, &QTcpSocket::connected,
        [=]()
        {
            ui->textEditRead->setText("成功和服务器连接");
        }
        );
    connect(tcpSocket, &QTcpSocket::readyRead,
        [=]()
        {
            //获取对方发送的内容
            QByteArray array = tcpSocket -> readAll();
            //在编辑区中显示
            ui -> textEditRead -> append(array);
        }
        );
}

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

void ClientWidget::on_connect_clicked()
{
    //获取服务器IP和端口
    QString ip = ui->lineEditIP->text();   //获取IP内容
    qint16 port = ui -> lineEditPort->text(). toInt();      //获取的端口号是字符串,转换成整型

    //主动和服务器建立连接
    tcpSocket -> connectToHost ( QHostAddress(ip), port );
                               主机IP            端口
}

void ClientWidget::on_send_clicked()
{
    //获取编辑内容
    QString str = ui -> textEditWrite->toPlainText();
    //发送数据
    tcpSocket -> write(str.toUtf8().data());
}

void ClientWidget::on_close_clicked()
{
    //主动和对方断开连接
    tcpSocket->disconnectFromHost();
    ui->textEditRead->setText("和服务器断开连接");
}

运行结果




猜你喜欢

转载自blog.csdn.net/buhuiguowang/article/details/80954531
今日推荐