精华内容
下载资源
问答
  • 最近又遇到tcp问题,发现知识不用忘得好快!于是做了一个简单的demo。 先看下运行效果: 代码我已经上传到CSDN: http://download.csdn.net/detail/u014597198/9689618 Github地址: ...

    最近又遇到tcp问题,发现知识不用忘得好快!于是做了一个简单的demo。

     

    先看下运行效果:

     

    代码我已经上传到CSDN:

    http://download.csdn.net/detail/u014597198/9689618

    Github地址:

    https://github.com/ShaShiDiZhuanLan/Demo_TcpSocket_Qt

    码云地址:

    https://gitee.com/ShaShiDiZhuanLan/TCP_Demo

    今天做了个类似的项目,发现服务端获取局域网IP这里不准确,我们是要获取192.168.*.*的IP地址,

    代码改为如下:

    QString TcpSever::getIPAddress()
    {
        //获取局域网IP地址192.168.*.*
        QString localHostName = QHostInfo::localHostName();
        QHostInfo info = QHostInfo::fromName(localHostName);
        foreach(QHostAddress address, info.addresses()) {
            if (address.protocol() == QAbstractSocket::IPv4Protocol) {
                return address.toString();
            }
        }
    }

    或者:

    QString ip = QHostInfo::fromName(QHostInfo::localHostName()).addresses().last().toString();

    获取本机外网地址修改:

    //返回外网IP
    QString TcpSever::returnOutIP()
    {
        QString tmp = GetHtml("https://ip.cn/");
        qDebug() << "returnOutIP" << tmp;
        return GetNetIP(tmp);
    }
    
    QString TcpSever::GetHtml(QString url)
    {
        QNetworkAccessManager *manager = new QNetworkAccessManager();
        QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
        QByteArray responseData;
        QEventLoop eventLoop;
        QObject::connect(manager, SIGNAL(finished(QNetworkReply *)), &eventLoop, SLOT(quit()));
        eventLoop.exec();
        responseData = reply->readAll();
        return QString(responseData);
    }
    
    QString TcpSever::GetNetIP(QString webCode)
    {
        QString tmp = webCode.split("IP: ").last();
        return tmp.split("\n<br").first();
    }

     

    展开全文
  • 先看一下效果: ...发图片、大文件与发短字符不大一样。...1、文件和图片通过TCP可能一次发不过去,...1、tcp客户端与服务端的代码这里就不贴了,以前贴过,可以看我以前的帖子。这里贴一下思路代码: 发送图片端:

    先看一下效果:



    思路:

    发图片、大文件与发短字符不大一样。

    1、文件和图片通过TCP可能一次发不过去,可能要发很多次。所以我们在发送文件、数据、以及文字最好带上文件的大小。

    2、图片转换成文件流的形式,这个Demo是转成base64加密流


    核心代码:

    1、tcp客户端与服务端的代码这里就不贴了,以前贴过,可以看我以前的帖子。这里贴一下思路代码:

    发送图片端:

            QByteArray byte = "P" + QByteArray::number(m_base64.length()) + "P";
            m_tcpClient->sendMessageB(byte);
            qDebug() << "len" << byte;
            m_tcpClient->sendMessageB(m_base64);
    这里的“P”只是一个分隔符,可以自定义。m_base64是图片转换成的QByteArray。

    看一下接收图片端:

        QByteArray tmp = m_socket->readAll();
        if(m_dataLength != 0) {
            m_byte.append(tmp);
            m_dataLength = m_dataLength - tmp.length();
            qDebug() << "m_dataLength " << m_dataLength;
            if(m_dataLength == 0) {
                emit alreadyRead();
            }
        } else {
            int len;
            if(tmp.contains("P")) {
                m_type = "P";
                len = tmp.split('P').at(1).toInt();
            } else if(tmp.contains("T")){
                m_type = "T";
                len = tmp.split('T').at(1).toInt();
            }
            int preNum = 2 + QString::number(len).count();
            m_dataLength = len + preNum - tmp.length();
            m_byte.clear();
            m_byte = tmp.mid(preNum, tmp.count() - preNum);
        }

    2、图片转换成文字流的代码:

    #ifndef SBASE64TOIMAGE_H
    #define SBASE64TOIMAGE_H
    
    #include <QByteArray>
    #include <QBuffer>
    #include <QImage>
    #include <QPixmap>
    
    class SBase64ToImage : public QObject
    {
        Q_OBJECT
    public:
        static QByteArray Image_To_Base64(QString ImgPath) {
            QImage image(ImgPath);
            QByteArray ba;
            QBuffer buf(&ba);
            image.save(&buf,"PNG",20);
            QByteArray hexed = ba.toBase64();
            buf.close();
            return hexed;
        }
        static QPixmap Base64_To_Image(QByteArray bytearray) {
            QByteArray Ret_bytearray = QByteArray::fromBase64(bytearray);
            QBuffer buffer(&Ret_bytearray);
            buffer.open(QIODevice::WriteOnly);
            QPixmap imageresult;
            imageresult.loadFromData(Ret_bytearray);
            return imageresult;
        }
    };
    #endif // SBASE64TOIMAGE_H
    


    展开全文
  • 编程环境:VS2015, QT5.6.1QT 客户端通信会自动连接两次,如下图:代码很简单,但是不知道为什么会自动连接两次,消息也会重复发送两次。经过一番思考,觉得应该是这两句话的原因,注释掉之后果然问题就解决了。为...

    编程环境:VS2015, QT5.6.1

    QT 客户端通信会自动连接两次,如下图:


    代码很简单,但是不知道为什么会自动连接两次,消息也会重复发送两次。



    经过一番思考,觉得应该是这两句话的原因,注释掉之后果然问题就解决了。为什么呢?

    个人觉得,槽函数在使用了显示声明之后,再使用这两行代码,相当于重复将按钮信号与槽函数关联了一次。与关联的按钮,单击之后,会重复执行两次。可参考博客,有详细的介绍:

    https://www.cnblogs.com/lxmwb/p/6220733.html


    *******************************************************************

    才疏学浅,欢迎指正交流~

    展开全文
  • 使用Qt编写TCP客户端时,需要完成自动重连服务器,实际使用中开启了一个线程用于断线重连操作和其他自动发送任务等。 初始化: m_tcpClient = new QTcpSocket(this); m_tcpClient->abort();//取消原有连接 ...

    1.头文件

    #ifndef TCPTOOL_H
    #define TCPTOOL_H
    
    #include <QObject>
    #include <QTcpSocket>
    #include <QHostAddress>
    
    class TCPTool : public QObject
    {
        Q_OBJECT
        //单例模式
    private:
        TCPTool();
    public:
        static TCPTool * GetInstance()
        {
            static TCPTool instance;
            return &instance;
        }
        ~TCPTool();
    
    	//变量
    private:
        bool m_exitThread;
        QTcpSocket * m_tcpClient;
        bool m_isConnected;
    
        //函数
    public:
    	bool SendLargeData(QByteArray & block);
    	
    private:
        void ProcessThread();
        bool Connect(const QString & address,int port);
    
    signals:
        void TryConnectSignal();
    
    public slots:
        void Disconnected();
        void ReadMessage();
        void TryConnectSlot();
    };
    
    #endif // TCPTOOL_H
    
    

    2.源代码

    #include "tcptool.h"
    #include <thread>
    #include "setting.h"//设置头文件
    
    TCPTool::TCPTool()
    {
        m_tcpClient = new QTcpSocket(this);
        m_tcpClient->abort();//取消原有连接
    
        connect(this,SIGNAL(TryConnectSignal()),this,SLOT(TryConnectSlot()));
        connect(m_tcpClient,SIGNAL(readyRead()),this,SLOT(ReadMessage()));
        connect(m_tcpClient,SIGNAL(disconnected()),this,SLOT(Disconnected()));
    
        m_isConnected = false;
        m_exitThread = false;
    
        std::thread sendThread(&TCPTool::ProcessThread,this);
        sendThread.detach();
    }
    
    TCPTool::~TCPTool()
    {
        Disconnected();
        m_exitThread = true;
    }
    
    bool TCPTool::SendLargeData(QByteArray & block)
    {
    	if(!m_isConnected)
    		return false;
        //分包发送
        const int PayloadSize = 64*1024;//一个帧数据包大小
        int totalSize = block.size();
        int bytesWritten = 0;
        int bytesToWrite = totalSize;
        while(bytesWritten<totalSize)
        {
            int startIdx = bytesWritten;
            int length = std::min(PayloadSize,bytesToWrite);
            if(startIdx+length>totalSize)
                return false;
    
            QByteArray smallBlock = block.mid(startIdx,length);
            qint64 written = m_tcpClient->write(smallBlock);
            bool success = m_tcpClient->waitForBytesWritten();
    
            if(!success)//发送失败包时,停止发送
                return false;
    
            bytesWritten+=written;
            bytesToWrite-=written;
        }
        m_tcpClient->flush();
    
        return true;
    }
    
    void TCPTool::ProcessThread()
    {
        while(m_exitThread==false)
        {
        	//重连尝试
            if(!m_isConnected)
            {
                emit TryConnectSignal();
                usleep(200000);//等待连接尝试
    
                if(!m_isConnected)
                {
                    usleep(5000000);//等待5秒重连
                    continue;
                }
            }
    
    		//执行发送(未展开,思路:大块数据从队列读出,然后在线程中执行同步发送)
    		//SendLargeData(data);
    		
            usleep(1000000);//等待1s
        }
    }
    
    bool TCPTool::Connect(const QString & address, int port)
    {
        if(!m_tcpClient)
        {
            m_isConnected = false;
            return false;
        }
    
        //直接读取状态,如果连接正常,则直接返回
        if(m_tcpClient->state()== QAbstractSocket::ConnectedState)
        {
            if(m_tcpClient->isValid())
            {
                m_isConnected = true;
                return true;
            }
            else
            {
                m_isConnected = false;
                return false;
            }
        }
    
        //尝试连接
        m_tcpClient->abort();//取消原有连接
        m_tcpClient->connectToHost(address,port);
        if(m_tcpClient->waitForConnected(1000))
        {
            m_isConnected = true;
        }
        else
            m_isConnected = false;
        return m_isConnected;
    }
    
    void TCPTool::Disconnected()
    {
        m_isConnected = false;
        if(!m_tcpClient)
            return;
    
        if(m_tcpClient->state()== QAbstractSocket::UnconnectedState||m_tcpClient->waitForDisconnected(1000))
            return;
    }
    
    void TCPTool::ReadMessage()
    {
        QByteArray buf = m_tcpClient->readAll();//读取数据
    }
    
    void TCPTool::TryConnectSlot()
    {
        Connect(Setting_Server_IPAddress,Setting_Server_IPPort);
    }
    
    

    3.说明

    3.1.自动重连

    使用waitForConnected时会有等待时间,如果放在主线程中,会造成卡顿。定时器也不能执行等待(一般情况定时器运行在主线程),因此选择在线程中执行重复连接。

    注意:如果在线程中执行Connect函数时,会引起:

    QObject: Cannot create children for a parent that is in a different thread. (Parent is QTcpSocket(0x142f1860), parent’s thread is QThread(0xbbac10), current thread is QThread(0x7fff18001040)
    QObject::startTimer: Timers can only be used with threads started with QThread QObject: Cannot create children for a parent that is in a different thread. (Parent is QTcpSocket(0x142f1860), parent’s thread is QThread(0xbbac10), current thread is QThread(0x7fff18001040)

    经测试,在线程中调用connectToHost会引起如上问题。使得发送、接收信号都停留在子线程中,只有当子线程exec()之后才释放信号,从而引起接收不到信息(未触发readyRead)和发送不出去信息(write后没有立即发送出去)
    因此代码中使用信号、槽执行重新连接尝试。发送信号后,等待片刻读取执行结果。详见代码中示例。

    3.2.发送大数据包

    执行write()时,只能发送一个小的数据包(与系统相关),大的数据包需要进行拆分才能进行发送。本文中在线程中使用同步方式发送大数据包,在线程中write()waitForBytesWritten()配合即可完成同步方式发送。

    以上代码经测试基本功能完善,仅供参考。

    展开全文
  • QTcpSocket实现客户端

    2021-03-04 13:51:45
    QTcpSocket> /********************************************** * 作者:wujianhua * 时间:2021/02/25 * 类介绍:socket tcp客户端通信类 * ***********************************************/ class T.
  • QTcpSocket客户端/服务器模式

    千次阅读 2013-05-30 22:02:52
    TCP即Transmission Control Protocol,传输控制协议。与UDP不同,它是面向...TCP协议的程序使用的是客户端/服务器模式,在Qt中提供了QTcpSocket类来编写客户端程序,使用QTcpServer类编写服务器端程序。我们在服务器
  • VS2008+Qt4.7 QTcpSocket客户端实例实例源码main.cpptcpsocket.htcpsocket.cpp实现结果如下 实例源码 需要在pro文件中添加 QT += core gui network 若原本没有生成pro文件,右键点击解决方案的名字,选择Create basic ...
  • 在socket中,客户端socket并不是必须调用bind函数来指定端口号。而是在连接成功之后会给客户端socket自动分配一个可用的端口号。 解决办法 在QTcpSocket调用了connectToHost函数成功连接服务端之后。会触发一个 ...
  • 使用qtcpsocket创建TCP客户端,怎么指定客户端的端口?
  • 文章目录前言客户端项目新建与服务端建立连接与TCPServer的数据收发交互动态演示总结 前言     上一章主要讲述了服务端的程序设计,本章主要...    客户端程序TCPClient只需要使用一个 QTcpSocket 对象,就可以和服
  • TcpSocket = new QTcpSocket(this); connect(ui->ConnectBtn,SIGNAL(clicked()),this,SLOT(Connect())); connect(ui->StopBtn,SIGNAL(clicked()),this,SLOT(Stop())); connect(ui->ClearReceiveBtn,...
  • QTcpSocket *client = new QTcpSocket(this); Login login; //连接服务器 client->connectToHost(QHostAddress("192.168.3.17"), 1234); client->open(QIODevice::ReadWrite); connect(ui->Login_...
  • 简 述: 了解TCP通信之QTcpServer和QTcpSocket,服务器和客户端通讯,书写一个简单地例子;然后写了一个小的 Qt例子,用来实现和验证它的空间的一些属性和功能的用法。 文章目录相关博文:系统环境:Tcp通信概述:...
  • m_pClientConnection = new QTcpSocket(this); if (!m_pClientConnection->setSocketDescriptor(m_nSocketDescriptor)) { return; } connect(m_pClientConnection, SIGNAL(readyRead()), this, SLOT...
  • QTcpServer提供了newConnection...函数获取连接的QTcpSocket * ;也可以继承QTcpServer派生, 复写虚函数incomingConnection(在连接上时, 会自动触发该函数,传参handle); virtual void incomingConnectio...
  • 客户端抽象类封装 #ifndef VSIPC_H #define VSIPC_H #include <QObject> class VSIPCClient { public: VSIPCClient() {} ~VSIPCClient() {} protected: virtual void initConnect()=0; ....
  • 首先说明,测试不一定严谨,只是为了记录测试过程 为了能有对比性,这里采用了asio...创建qtcpsocket 客户端,使用信号槽方式接收数据,发送数据,打印接收数据与发送数据间的时间差(微秒级) 结果如下 asio tcp client: qtc

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 473
精华内容 189
关键字:

qtcpsocket客户端