#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的问题,还是不应该这样使用信号机制。或者还有别的什么好方法吗,麻烦各位大神热点,感激