23TCP通信

.pro 文件中加入:QT+=network

 

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

1.创建监听套接字,QTcpServer

2.将监听套接字设置为监听模式, listen

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

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

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

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

 

监听套接字和通信套接字的区别:

在服务端包含两种套接字QTcpServer,QTcpSocket. QTcpServer用于listen()监听模式,监听哪个IP,从哪个端口接入。QTcpSocket用于两者之间的真正通信,当两者完成连接后,各个都拥有一个QTcpSocket,如:sock1,sock1,那么这两个通信套接字等同于各自的手机号码,用于通信使用。

 

客户端通信流程:

1.创建套接字

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

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

如图:

解析:当服务端处于监听模式时(listen),客户端通过connectToHost请求连接,此时服务端就是触发信号newConnection(系统给出,非自拟),调用对应的槽函数(可自拟,或直接使用Lambda表达式)。服务端连通后,客户端就会立即触发信号connected.说明两者之间已完成连接,彼此可以利用write发出信息,利用read,readAll接受信息。

 

 

服务器

TcpSever.h

#ifndef TCPSEVER_H

#define TCPSEVER_H

 

#include <QWidget>

#include <QTcpServer>

#include <QTcpSocket>

 

namespace Ui {

class Widget;

}

 

class Widget : public QWidget

{

    Q_OBJECT

 

public:

    explicit Widget(QWidget *parent = 0);

    ~Widget();

 

private slots:

    void on_pushButton_clicked();       //发送按钮  

    void on_pushButton_2_clicked();     //关闭通信

 

private:

    Ui::Widget *ui;

    QTcpServer *m_server;           //监听套接字

    QTcpSocket *m_ServerSock;       //通信套接字

 

 

};

 

#endif // TCPSEVER_H

 

 

TcpSever.cpp

#include "TcpSever.h"

#include "ui_widget.h"

#include <QTime>

#include <QDebug>

 

Widget::Widget(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::Widget)

{

    ui->setupUi(this);

   

    //监听套接字,指定父对象,让其自动回收空间

    m_server=new QTcpServer(this);

    m_ServerSock=NULL;

   

    this->setWindowTitle("服务器端口:888");

   

    //监听IP地址,指定端口

    m_server->listen(QHostAddress::Any,888);

   

    //客户端接入触发

    connect(m_server,&QTcpServer::newConnection,

            [=]()   mutable

            {              

                if(m_ServerSock==NULL)

                {

                    //取出建立好的连接的套接字

                    m_ServerSock=m_server->nextPendingConnection();

                    //获取对方的IP,端口号

                    QString strIP=m_ServerSock->peerAddress().toString();

                    quint16 uPort=m_ServerSock->peerPort();

                   

                    //newConnection信号被触发后,显示有客户端接入

                    //m_ServerSock->write("连接成功!!!");

                    ui->edit_Recv->setText(QString("[%1,%2]接入成功").arg(strIP).arg(uPort));

                  

                    //通信

                    connect(m_ServerSock,&QTcpSocket::readyRead,

                            [=]()   mutable

                            {

                                 //接受对方发来的信息

                                 QByteArray byteBuf=m_ServerSock->readAll();

                                 //获取本地时间

                                 QTime time=QTime::currentTime();

                                 //显示在消息框,append不断追加

                                 QString strTemp=time.toString()+QString("::")+QString(byteBuf);

                                 ui->edit_Recv->append(QString(strTemp));

                            }

                            );

                }

 

            }

            );

}

 

Widget::~Widget()

{

    delete ui;

   

    delete m_server;

    m_server=NULL;

    m_ServerSock=NULL;

}

 

void Widget::on_pushButton_clicked()

{

    if(m_ServerSock!=NULL)

    {

        //获取要发送的信息

        QString strSend=ui->edit_Send->toPlainText();

        //发送

        m_ServerSock->write(strSend.toUtf8().data());

        //清空发送框的内容

        //ui->edit_Send->clear();

    }

 

}

 

void Widget::on_pushButton_2_clicked()

{

    if(m_ServerSock!=NULL)

    {

        //断开连接

        m_ServerSock->disconnectFromHost();

        m_ServerSock->close();

        m_server->close();

    }

 

}

 

同一程序添加两个窗口,且有设计器。新建一个文件,但不是C++类文件,而是QT且带有界面类的,最后在main中使用show()直接显示。如下图:

 

 

 

客户端

tcpclient.h

#ifndef TCPCLIENT_H

#define TCPCLIENT_H

 

#include <QWidget>

#include <QTcpSocket>

#include <QHostAddress>

 

namespace Ui {

class TcpClient;

}

 

class TcpClient : public QWidget

{

    Q_OBJECT

 

public:

    explicit TcpClient(QWidget *parent = 0);

    ~TcpClient();

 

private slots:

    void on_connect_clicked();          //请求服务器连接

    void on_send_clicked();             //发送信息

    void on_close_clicked();            //关闭通信

 

private:

    Ui::TcpClient *ui;

 

    QTcpSocket *m_ClientSock;           //通信套接字

 

};

 

#endif // TCPCLIENT_H

 

 

tcpclient.cpp

#include "tcpclient.h"

#include "ui_tcpclient.h"

#include <QDebug>

#include <QTime>

 

TcpClient::TcpClient(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::TcpClient)

{

    ui->setupUi(this);

   

    this->setWindowTitle("客户端");

   

    //便于调试

    //ui->IP->setText("127.0.0.1");

    //ui->Port->setText("888");

   

    //分配空间,指定父对象

    m_ClientSock=new QTcpSocket(this);

   

    //与服务器连接好触发

    connect(m_ClientSock,&QTcpSocket::connected,

            [=]() mutable

            {

                ui->clientRecv->setText("成功连接!!!");

                //通信

                connect(m_ClientSock,&QTcpSocket::readyRead,

                        [=]()

                        {

                           //获取对方发来的信息

                           QByteArray byteBuf=m_ClientSock->readAll();

                           //获取本地时间

                           QTime time=QTime::currentTime();

                           //显示在消息框,append不断追加

                           QString strTemp=time.toString()+QString("::")+QString(byteBuf);

                           ui->clientRecv->append(strTemp);

                        }

                        );

            }

     );

    //    connect(m_ClientSock,QTcpSocket::disconnected(),

    //            []()

    //            {

    //                m_ClientSock->disconnectFromHost();

    //                m_ClientSock->close();

    //            }

    //    )

}

 

TcpClient::~TcpClient()

{

    delete ui;

   

    delete m_ClientSock;

    m_ClientSock=NULL;

}

 

void TcpClient::on_connect_clicked()

{

    //设置对方的IP,端口

    QString strIP=ui->IP->text();

    qint16 uPort=ui->Port->text().toInt();

    //请求服务器连接

    m_ClientSock->connectToHost(QHostAddress(strIP),uPort);

}

 

void TcpClient::on_send_clicked()

{

    //获取要发送的信息

    QString strSend=ui->clientSend->toPlainText();

    //发送

    m_ClientSock->write(strSend.toUtf8().data());

    //清空

    //ui->clientSend->clear();

}

 

void TcpClient::on_close_clicked()

{

    //断开连接

    m_ClientSock->disconnectFromHost();

    m_ClientSock->close();

}

 

 

main.cpp

#include "TcpSever.h"

#include <QApplication>

#include "tcpclient.h"

 

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    Widget w;

    w.show();

 

    TcpClient c;

    c.show();

 

    return a.exec();

}

 

程序结果图:

 

posted @ 2018-06-22 22:53  gd_沐辰  阅读(342)  评论(0编辑  收藏  举报