QT socket Tcp/IP通信

1、TCP/IP 通信有2种形式

1、client与server 通信,收发只有1个 端口;

2、client 与server通信,收发有2个 端口;(客户端里面起了一个server监听端口)

2、本文介绍第一种方式。

第一种方式,有2种方法实现。

a. 直接用SocketSend->readAll()

b. 配合使用 QT自带的SIGNAL readyRead()(注意线程问题) 

实现如下代码

1. 头文件

#ifndef HSPOSEXTSOCKET_H
#define HSPOSEXTSOCKET_H

#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QTcpServer>
#include <QThread>
#include <QMutex>
#define WAY2 0

class HSPOSEXTSOCKETSHARED_EXPORT HsPosExtSocket : public QTcpSocket
{
    Q_OBJECT
	QObject(parent);

public:
    HsPosExtSocket(QObject *parent = NULL);
    bool CallSocket(QString input,QString &outPut);   //socket发送(封装)
    bool Connect(QString serverip, int sendport, QString &ErrMsg); //socket连接(封装)

private:
 
    QString ReadBuf;  //读取数据保存
    QHostAddress* HostSend;
    QTcpSocket *SocketSend;
    bool SocketConnect(QString serverip, int sendport);   //TCP连接
    bool SendSocketData(QString inPutMsg , QString& outPutMsg);   //tcp发送数据,同一端口,返回
#if WAY2
    QMutex mutex; 
private slots:
    void ReadMessage();  //读取数据槽函数
#endif
};

#endif // HSPOSEXTSOCKET_H


2. 源文件

#include "HsPosExtSocket.h"
#include <QTextCodec>
#include <QThread>

/***
* Function: 初始化
* Return:
**/
HsPosExtSocket::HsPosExtSocket(QObject *parent) :QTcpSocket(parent)
{
    HostSend = new QHostAddress();
    SocketSend = new QTcpSocket();
    ReadBuf.clear();
#if WAY2
    /* 绑定 接收触发信号 */
    connect(SocketSend,SIGNAL(readyRead()),this,SLOT(ReadMessage()));
#endif
}


/***
* Function: SOCKET连接函数
* Return:
**/
bool HsPosExtSocket::Connect(QString serverip, int sendport, QString &ErrMsg)
{
    if(NULL == HsPosStaticVariable::PosData.DataPlugin)
    {
        //PosLog.log->error("DataPlugin is null");
        return false;
    }
    return SocketConnect(serverip , sendport);
}


/***
* Function: SOCKET连接请求函数
* Return:
**/
bool HsPosExtSocket::SocketConnect(QString serverip, int sendport)
{
    if(!HostSend->setAddress(serverip))
    {
        //PosLog.log->info("欧尚: socket send ip error!");
        return false;
    }

    SocketSend->connectToHost(*HostSend, sendport);
    if (SocketSend->waitForConnected())
    {
        //PosLog.log->info("欧尚: socket connect success!");
    }
    else
    {
        //PosLog.log->info("欧尚: socket connect timeout!");
        return false;
    }
    return true;
}


/***
* Function: SOCKET数据发送入口
* Return:
**/
bool HsPosExtSocket::CallSocket_2(QString input, QString &outPut)
{
	bool ret;
    if(SendSocketData(input, outPut))
	{
		ret = true;
	}
	else
	{
		ret = false;
	}
    return ret;
}

/***
* Function: SOCKET发送数据
* para:
* para:
* Return:
**/
bool HsPosExtSocket::SendSocketData(QString inPutMsg , QString& outPutMsg)
{
    bool Ret = false;
    outPutMsg.clear();

    /* 向服务器写入信息 */
    SocketSend->write(inPutMsg.toUtf8());
    SocketSend->waitForBytesWritten();

    /* 阻塞等待接受消息 */
    SocketSend->waitForReadyRead(60000);
    do
    {
        if(ReadBuf.length() > 1000)
        {
            /* 阻塞等待接收消息 */
            SocketSend->waitForReadyRead(1000);
        }
        ReadBuf.clear();

        ReadBuf = SocketSend->readAll();
        outPutMsg.append(ReadBuf);

    }while(ReadBuf.length() > 1000);

    return Ret;
}
#if WAY2
/***
* Function: SOCKET发送数据
* Return:
**/
bool HsPosExtSocket::SendSocketData(QString inPutMsg , QString& outPutMsg)
{
    outPutMsg.clear();

    /* 向服务器写入信息 */
    SocketSend->write(inPutMsg.toUtf8());
    SocketSend->waitForBytesWritten();

    /* 阻塞等待接受消息 */
    SocketSend->waitForReadyRead(60000);		//等待服务器返回,超时60s
    QThread::msleep(100);  //保证信号先触发eadMessage()
    mutex.lock();
    while(ReadBuf.length() > 1000)		//如果socket发送数据太多,可能分多次发过来
    {
        outPutMsg.append(ReadBuf);
        ReadBuf = "";

        /* 阻塞等待接收消息 */
        SocketSend->waitForReadyRead(1000);
    }
    outPutMsg.append(ReadBuf);
    ReadBuf.clear();
    mutex.unlock();

    return true;
}

/***
* Function: SOCKET读取服务器返回数据
* Return:
**/
void HsPosExtSocket::ReadMessage()
{
    mutex.lock();
    ////PosLog.log->info("enter ReadMessage");
    ReadBuf.clear();

    QByteArray RetData;
    if(SocketSend->bytesAvailable() > 0)
    {
        RetData = SocketSend->readAll();
    }

    ReadBuf = RetData;
    mutex.unlock();
}
#endif



猜你喜欢

转载自blog.csdn.net/sea_snow/article/details/77878094
今日推荐