tmaolein 2016-05-31 09:03 采纳率: 20%
浏览 4151

qt 线程中接收socket数据

#ifndef TCP_THREAD_H
#define TCP_THREAD_H

#include
#include
#include

#define MAX_SEND_MSG_LEN 68

struct _loop_buf {
int num_of_unit; // Number of data units
int unit_size;
int rhead; // Head for read
int whead; // Head for write
void *buf_head;
};

class TcpThread : public QThread
{
Q_OBJECT

private:
QTcpServer *tcpServer;
QTcpSocket *socket;
QString ipAddress;
quint16 destinationPort;
int Flag;
bool quit;
struct _loop_buf loop_buf;

void run() Q_DECL_OVERRIDE;
void processMessage(char *msg);

int init_loop_buf(struct _loop_buf *loop_buf, int num_of_unit, int unit_size);
void reset_loop_buf(struct _loop_buf *loop_buf);
void release_loop_buf(struct _loop_buf *loop_buf);
int read_data_from_loop_buf(struct _loop_buf *loop_buf, void *data_unit);    

QByteArray bytes;
QByteArray byteGet;

public:
TcpThread(QString ipAddress, quint16 destinationPort, QObject *parent = 0);
~TcpThread();
int addMessage(void *data_unit);

signals:
void error(int socketError, const QString &message);

public slots:
void finishWork(void);
void newConnectionSlot();
void dataReceived();
};

#endif // TCP_THREAD_H
.h文件


#if defined(_MSC_VER) && (_MSC_VER >= 1600)
#pragma execution_character_set("utf-8")
#endif

//#define MAX_SEND_MSG_LEN = 68
#include "TcpThread.h"
#include "widget.h"
#include <QDebug>


TcpThread::TcpThread(QString ipAddress, quint16 destinationPort, QObject *parent)
    : QThread(parent), quit(false)
{
    this->ipAddress = ipAddress;
    this->destinationPort = destinationPort;

    // Initialize loop buffer
    // Max length of messages to be sent is 68 bytes.
    if (init_loop_buf(&loop_buf, 128000, MAX_SEND_MSG_LEN) != 0) {
        qDebug() << "Can't initialize loop buffer.";
        return;
    }
}

TcpThread::~TcpThread()
{
    // Wait for the end of the thread.
    quit = true;
    wait();
}

void TcpThread::run()
{
    //
    // At here, it is in the execution context of newly created thread.
    // So, it is better to define or create objects here.
    // Or, following error may occurred:
    //     QObject: Cannot create children for a parent that is in a different thread
    //
    char *msg;//, *sendMsg;
    int conn_timeout = 30000;
    int read_timeout = 5000;
    int write_timeout = 5000;

    int bytesToRead, readBytes;
    int bytesToWrite, writeBytes;
    int ret;
    int gotMessageHead = 0;
    int toGetNewMessage = 0;

    //msg = (char *)calloc(65536 + 128, 1);
    msg = (char *)calloc(MAX_SEND_MSG_LEN, 1);
    if (msg == NULL) {
        qDebug() << "Can't allocate memory.";
        return;
    }

    tcpServer = new QTcpServer();
    socket = new QTcpSocket();
    //connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnectionSlot()), Qt::DirectConnection);


    if (!tcpServer->isListening())
    {
        qDebug() << ipAddress;
        //if (tcpServer->listen(QHostAddress::QHostAddress(ipAddress), 16512))
        if (tcpServer->listen(QHostAddress::Any, 16512))
        {
            //m_pEdt_Info->append(QObject::tr("打开监听端口成功!111"));
            qDebug()<< QObject::tr("打开监听端口成功!111");
            socket = tcpServer->nextPendingConnection();
//            //connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
            connect(socket, SIGNAL(readyRead()),this, SLOT(dataReceived()));

        }
        else
        {
            //m_pEdt_Info->append(QObject::tr("打开监听端口失败!"));
            qDebug()<< QObject::tr("打开监听端口失败!11");
        }
    }
    else
    {
        //m_pEdt_Info->append(QObject::tr("正在监听中...!"));
        qDebug()<< QObject::tr("正在监听中...!");

    }


        qDebug() << "Connected to" << ipAddress;


        // reset read variables
        readBytes = 0;
        bytesToRead = 4;
        gotMessageHead = 0;

        // reset write variables
        writeBytes = 0;
        toGetNewMessage = 1;


}

void TcpThread::processMessage(char *msg)
{
    qDebug() << "Receive message:" << *(unsigned short *)msg <<
            ". Length:" << *(unsigned short *)(msg + 2);
}

void TcpThread::finishWork(void)
{
    quit = true;
}

int TcpThread::init_loop_buf(struct _loop_buf *loop_buf, int num_of_unit, int unit_size)
{
    unsigned long long total_size;

    total_size = (unsigned long long)unit_size * (unsigned long long)num_of_unit;
    if (total_size > 0x7fffffff) {
        printf("Memory to be allocated is too large.\n");
        return -1;
    }

    if (num_of_unit > 0x7ffffff0) {
        printf("Buffer size can't exceed 0x7ffffff0.\n");
        return -1;
    }

    loop_buf->num_of_unit = num_of_unit;
    loop_buf->unit_size = unit_size;
    loop_buf->rhead = 0;
    loop_buf->whead = 0;
    loop_buf->buf_head = malloc(total_size);

    if (loop_buf->buf_head == NULL) {
        printf("Can't allocate memory for the loop buffer.\n");
        return -1;
    }

    return 0;
}

// Be careful to call this function. You must make sure that
// nobody is using the loop buffer pointed by 'loop_buf',
// or error may occur.
void TcpThread::reset_loop_buf(struct _loop_buf *loop_buf)
{
    loop_buf->rhead = 0;
    loop_buf->whead = 0;
}

void TcpThread::release_loop_buf(struct _loop_buf *loop_buf)
{
    free(loop_buf->buf_head);
}

//
// Return value:
//     0: Success.
//    -1: The loop buffer is NULL.
//
int TcpThread::read_data_from_loop_buf(struct _loop_buf *loop_buf, void *data_unit)
{
    if (loop_buf->rhead == loop_buf->whead) {
        // The buffer is null.
        return -1;
    }

    //
    // Do your work here, you can read data from the loop buffer.
    // Following is just an example.
    //
    // Note:
    //     Must copy the data out, or the content of the data unit may be
    //     overwritten.
    //
    memcpy(data_unit, (char *)loop_buf->buf_head + loop_buf->rhead * loop_buf->unit_size, (size_t)loop_buf->unit_size);

    if (loop_buf->rhead == (loop_buf->num_of_unit - 1)) {
        loop_buf->rhead = 0;
    } else {
        loop_buf->rhead++;
    }

    return 0;
}

//
//     --- IMPORTANT ---
// There is no mutex to avoid race condition in the function's implementation.
// So, to call this function from only one code source.
//
//Return value:
//    0: Success.
//   -1: The loop buffer is full.
//
int TcpThread::addMessage(void *data_unit)
{
    int tmp_whead = 0;

    tmp_whead = loop_buf.whead + 1;
    if (tmp_whead >= loop_buf.num_of_unit) {
        tmp_whead = 0;
    }

    if (tmp_whead == loop_buf.rhead) {
        // The buffer is full.
        return -1;
    }

    //
    // Do your work here, you can write data to the loop buffer.
    // Following is just an example.
    //
    memcpy((char *)loop_buf.buf_head + loop_buf.whead * loop_buf.unit_size, data_unit, (size_t)loop_buf.unit_size);

    loop_buf.whead = tmp_whead;

    return 0;
}

void TcpThread::newConnectionSlot()
{
    //m_pEdt_Info->append(QObject::tr("有新客户端连接到服务器"));
    socket = tcpServer->nextPendingConnection();
    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
    connect(socket, SIGNAL(readyRead()),this, SLOT(dataReceived()));
}

void TcpThread::dataReceived()
{
    bytes = socket->readAll();
    qDebug() << bytes.length() << bytes.size();
    //if (bytes.size()=0) waitfo
    if (byteGet.size()!=0){
        byteGet.append(bytes.left(68-byteGet.size()));
        bytes.remove(0,68-byteGet.size());
        qDebug() << byteGet.length() << bytes.size();
    }
    for (;bytes.size()>=68;){
        byteGet = bytes.left(68);
        //m_pEdt_Info->append(byteGet.toHex());
        bytes.remove(0,68);
        qDebug() << byteGet.length() << bytes.size();
    }
    if (bytes.size()>0&&bytes.size()<68){
        byteGet = bytes;
        bytes.remove(0,byteGet.size());
        qDebug() << byteGet.toHex();
        qDebug() << byteGet.length() << bytes.size();
        //bytes = m_pSocket->readLine();
        //m_pServer->close();
    }
}

.cpp文件
线程中接收数据,使用信号机制可不可以啊?
我用connect(socket, SIGNAL(readyRead()),this, SLOT(dataReceived()));
发现Slot里面定义的接收数据并未调用到。为什么,是this的问题,还是不应该这样使用信号机制。或者还有别的什么好方法吗,麻烦各位大神热点,感激

  • 写回答

2条回答

  • 小灸舞 2016-05-31 09:08
    关注

    贴一下你的socket所属的类(包括.h和.cpp)

    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!