Qt之 TCP/IP Socket通信


参考文章:qt socket通信

Socket通信

Qt中提供的所有的Socket类都是非阻塞的。

Qt中常用的用于socket通信的套接字类:

  • QTcpServer

    用于TCP/IP通信, 作为服务器端套接字使用

  • QTcpSocket

    用于TCP/IP通信,作为客户端套接字使用。

  • QUdpSocket

    用于UDP通信,服务器,客户端均使用此套接字。

 TCP/IP

在Qt中实现TCP/IP服务器端通信的流程:

  • 创建套接字
  • 将套接字设置为监听模式
  • 等待并接受客户端请求

    可以通过QTcpServer提供的void  newConnection()信号来检测是否有连接请求,如果有可以在对应的槽函数中调用nextPendingConnection函数获取到客户端的Socket信息(返回值为QTcpSocket*类型指针),通过此套接字与客户端之间进行通信。

  • 接收或者向客户端发送数据

    接收数据:使用read()或者readAll()函数

    发送数据:使用write()函数

客户端通信流程:

  • 创建套接字

  • 连接服务器

    可以使用QTcpSocket类的connectToHost()函数来连接服务器。

  • 向服务器发送或者接受数据

              

关于“套接字

server端:

#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
#include "serverwidget.h"
#include "ui_serverwidget.h"

#pragma execution_character_set("utf-8")

serverWidget::serverWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::serverWidget)
{
    ui->setupUi(this);
    tcpServer = NULL;
    tcpSocket = NULL;
    //监听套接字,指定父对象,让其自动回收空间
    tcpServer = new QTcpServer(this);
    //1.QTcpServer对象负责监听是否有客户端连接此服务器。它是通过这样一个函数监听的
    //第一个参数表示服务器监听的地址,如果后面是Any表示监听本机的所有网口的,第二个参数表示监听的网络端口
    tcpServer->listen(QHostAddress::Any, 8888);
    setWindowTitle("Sever");
    //2.如果服务器监听到有客户端和它进行连接,服务器就会触发newConnection这个信号。同时客户端一旦和服务器连接成功,
    //客户端会触发connected这个信号,表示已经成功和服务器连接。
    connect(tcpServer, &QTcpServer::newConnection,
            [=]()
            {
                //3.当服务器和客户端建立好连接之后,服务器需要返回一个QTcpSocket对象来和客户端进行通信,通常通过这个函数来返回一个建立好连接的套接字。
                //客户端和服务器各有一个通信套接字,可以看出,每一方的套接字都可以获得对方的相关信息
                //接着就可以通过两个的通信套接字来完成通信。
                //取出建立好连接的套接字
                tcpSocket = tcpServer->nextPendingConnection();
                //获取对方的IP和端口
                QString ip = tcpSocket->peerAddress().toString();
                qint16 port = tcpSocket->peerPort();
                QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);

                ui->textEditRead->setText(temp);
                //4.当一端发送成功之后,"接收方"会触发这么一个信号,readyRead,这样我们就能够读取套接字当中的内容了。
                connect(tcpSocket, &QTcpSocket::readyRead,
                        [=]()
                        {
                            //从通信套接字中取出内容
                           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();
     tcpSocket = NULL;
}

客户端:

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>//通信套接字

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_buttonConnect_clicked();

    void on_buttonSend_clicked();

    void on_buttonClose_clicked();

private:
    Ui::Widget *ui;
    QTcpSocket *tcpsocket;

};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
#pragma execution_character_set("utf-8")

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    tcpsocket = NULL;

    //0.分配空间,指定父对象
    tcpsocket = new QTcpSocket(this);

    setWindowTitle("客户端");
    //3.连接成功之后客户端会触发这样一个信号 connected
    connect(tcpsocket,&QTcpSocket::connected,
            [=]()
    {
        ui->textEditRead->setText("成功和服务器建立好链接");
    });
    connect(tcpsocket,&QTcpSocket::readyRead,
            [=]()
    {
        //获取对方发送的内容
        QByteArray array = tcpsocket->readAll();
        //追加到编辑区中
        ui->textEditRead->append(array);
    });
}

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

void Widget::on_buttonConnect_clicked()
{
    //1.获取服务器ip和端口
    QString ip = ui->lineEditIP->text();
    qint16 port = ui->lineEditPort->text().toInt();

    //2.主动和服务器建立链接
    tcpsocket->connectToHost(QHostAddress(ip),port);
}

void Widget::on_buttonSend_clicked()
{
    //获取编框内容
    QString str = ui->textEditWrite->toPlainText();
    //发送数据
    tcpsocket->write(str.toUtf8().data());
}
void Widget::on_buttonClose_clicked()
{
    //主动和对方断开连接
    tcpsocket->disconnectFromHost();
    tcpsocket->close();
}

参考:QT - 创建TCP Socket通信

黑马Qt笔记

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM