zoukankan      html  css  js  c++  java
  • QT 使用QTcpServer QTcpSocket 建立TCP服务器端 和 客户端

    1。  如图客户端连接server后,server发送“hello tcp“ 给客户端

    2. 实例代码

    -----------------------------------  server端 -----------------------------------------

    修改工程文件.pro, QT += network, 添加net模块

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QtNetwork>
    
    namespace Ui {
    class Widget;
    }
    class Widget : public QWidget
    {
        Q_OBJECT    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();    
    private:
        Ui::Widget *ui;
        QTcpServer *tcpServer;
    public slots:
        void sendMessages();
    };
    
    #endif // WIDGET_H

    widget.cpp

    #include "widget.h"
    #include "ui_widget.h"
    #include <QtGui>
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        tcpServer = new QTcpServer(this);
        if( !tcpServer->listen(QHostAddress::LocalHost, 13888) )
        {   //监听本地主机的13888端口,如果出错就输出错误信息,并关闭
            qDebug() << tcpServer->errorString();
            close();
        }
        //连接信号和相应槽函数
        connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendMessages()));
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::sendMessages()
    {
        QByteArray block;   //用于暂存我们要发送的数据
        QDataStream out(&block, QIODevice::WriteOnly);  //使用数据流写入数据
        out.setVersion(QDataStream::Qt_4_7);
        out << (quint16) 0;
        out << tr("hello tcp");
        out.device()->seek(0);
        out << (quint16) (block.size() - sizeof(quint16));
    
        //获取已经建立的连接的子套接字
        QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
        connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));
        /*clientConnection->disconnectFromHost();它表示当发送完成时就会断开连接,
         *这时就会发出disconnected()信号,
         *而最后调用deleteLater()函数保证在关闭连接后删除该套接字clientConnection。
        */
        clientConnection->write(block);
        clientConnection->disconnectFromHost();
        ui->statusLabel->setText("Send message successfil");
    }
    

    ---------------------------------------- Client 端 ----------------------------------

    clientwidget.h

    #ifndef CLIENTWIDGET_H
    #define CLIENTWIDGET_H
    
    #include <QWidget>
    #include <QtNetwork>
    #include <QtGui>
    
    namespace Ui {
    class clientWidget;
    }
    
    class clientWidget : public QWidget
    {
        Q_OBJECT
        
    public:
        explicit clientWidget(QWidget *parent = 0);
        ~clientWidget();   
    
    private slots:
        void newConnect();   //连接服务器
        void readMessage();  //接收数据
        void displayError(QAbstractSocket::SocketError); //显示错误
    
    private:
        Ui::clientWidget *ui;
        QTcpSocket *tcpSocket;
        QString message; //存放从服务器接收到的字符串
        quint16 blockSize; //存放文件的大小信息
    };
    
    #endif // CLIENTWIDGET_H
    

    clientwidget.cpp

    #include "clientwidget.h"
    #include "ui_clientwidget.h"
    #include <QtDebug>
    
    clientWidget::clientWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::clientWidget)
    {
        ui->setupUi(this);
    
        tcpSocket = new QTcpSocket(this);
        connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readMessage()));
        connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(displayError(QAbstractSocket::SocketError)));
        /*这里关联了tcpSocket的两个信号,
         *当有数据到来时发出readyRead()信号,我们执行读取数据的readMessage()函数。
         *当出现错误时发出error()信号,我们执行displayError()槽函数。
        */
        connect(ui->linkButton, SIGNAL(clicked()), this, SLOT(newConnect()));
    }
    
    clientWidget::~clientWidget()
    {
        delete ui;
    }
    
    void clientWidget::newConnect()
    {
        blockSize = 0;
        tcpSocket->abort(); //取消已有的连接
        tcpSocket->connectToHost(ui->hostLineEdit->text(),
                                 ui->portLineEdit->text().toInt());
         //连接到主机,这里从界面获取主机地址和端口号
    }
    
    void clientWidget::readMessage()
    {
        QDataStream in(tcpSocket);
        in.setVersion(QDataStream::Qt_4_7);
        if( blockSize == 0 )
        {
            //判断接收的数据是否有两字节,也就是文件的大小信息
            //如果有则保存到blockSize变量中,没有则返回,继续接收数据
            if( tcpSocket->bytesAvailable() < (int)sizeof(quint16) )
                return;
            in >> blockSize;
        }
        //如果没有得到全部的数据,则返回,继续接收数据
        if( tcpSocket->bytesAvailable() < blockSize )
            return;
        in >> message;  //将接收到的数据存放到变量中
        ui->messageLabel->setText(message);
    }
    
    void clientWidget::displayError(QAbstractSocket::SocketError)
    {
        qDebug() << tcpSocket->errorString();
    }
    





     

  • 相关阅读:
    MDL中捕获到损坏的页表页
    跟踪MmSt分页池使用情况
    了解NTFS压缩
    如何跟踪高CPU在用户模式应用程序-现场调试!
    如何与转储文件建立丰富多彩的关系
    Kernel Stack Overflows
    非分页池的消耗
    MBR反汇编
    LPC (Local procedure calls)(二)内核调试扩展
    LPC (Local procedure calls) (一)数据结构
  • 原文地址:https://www.cnblogs.com/xj626852095/p/3648130.html
Copyright © 2011-2022 走看看