QTcpSocket readyRead() 信号发出两次
QTcpSocket readyRead() Signal emitted twice
我有QTcpServer。我想从客户端发送大数据以及如何在服务器接收到所有数据时捕获信号?
"while (socket->bytesavailable)" 无效。
例如:
当客户端发送的qbytearray大小为9000时,在服务器端为4000或5000...
例二:
在这种情况下,readyRead() 信号发出 8 次。
void Client::SendMessage(std::vector<QString>)
{
MyClass _Send;
_Send.Age = 22;
_Send.School = 14;
_Send.Name = "Taz";
QVector<MyClass2> vv;
for (int i = 0; i < 15000; i++) {
vv.push_back(MyClass2(24, "leri"));
vv.push_back(MyClass2(22, "tazo"));
}
_Send.vctr = vv;
QByteArray bytes;
QDataStream stream(&bytes, QIODevice::WriteOnly);
int FunctionUID = 331;
int ij, ik = ij = 169;
MyClass2 faf(-31, "15");
stream << FunctionUID << _Send << faf << ij << ik;
socket->write(bytes);
}
void Server::ImReady()
{
QByteArray buf;
buf = socket->readAll();
QDataStream stream(&buf, QIODevice::ReadOnly);
int FunctionUID, ij, ik;
MyClass vv;
MyClass2 vv1;
stream >> FunctionUID >> vv >> vv1 >> ij >> ik;
qDebug() << vv.vctr.size() << "faf";
}
void Server::incomingConnection(qintptr val)
{
qDebug() << "Client Connected" << val;
socket = new QTcpSocket;
socket->setSocketDescriptor(val);
if (!socket) {
return;
}
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
connect(socket, SIGNAL(readyRead()), this, SLOT(ImReady()));
}
TCP不发送消息,它是数据流。这意味着您不能只读取那里的所有数据,然后考虑这一条消息。相反,通常发送 header,其中包含消息大小,然后接收方知道要读取多少才能获得整个消息(并且只是这个,而不是读入下一个)。
这意味着您的槽会做这样的事情
void Server::ImReady()
{
uint32 size;
socket->read(&size, 4);
uint32 readTotal = 0;
do {
readTotal += socket->read(buffer, size-readTotal);
} while (readTotal < size);
}
你可以这样写一行
if (socket->bytesAvailable() == 0)
return;
在插槽的开头,然后您根本不会在意每条消息是否发出多次信号。
请注意,上面的代码需要额外的错误处理,例如您必须确保第一个 read
读取所有 4 个字节,并且始终处理 return 值 -1。
我有QTcpServer。我想从客户端发送大数据以及如何在服务器接收到所有数据时捕获信号? "while (socket->bytesavailable)" 无效。
例如:
当客户端发送的qbytearray大小为9000时,在服务器端为4000或5000...
例二:
在这种情况下,readyRead() 信号发出 8 次。
void Client::SendMessage(std::vector<QString>)
{
MyClass _Send;
_Send.Age = 22;
_Send.School = 14;
_Send.Name = "Taz";
QVector<MyClass2> vv;
for (int i = 0; i < 15000; i++) {
vv.push_back(MyClass2(24, "leri"));
vv.push_back(MyClass2(22, "tazo"));
}
_Send.vctr = vv;
QByteArray bytes;
QDataStream stream(&bytes, QIODevice::WriteOnly);
int FunctionUID = 331;
int ij, ik = ij = 169;
MyClass2 faf(-31, "15");
stream << FunctionUID << _Send << faf << ij << ik;
socket->write(bytes);
}
void Server::ImReady()
{
QByteArray buf;
buf = socket->readAll();
QDataStream stream(&buf, QIODevice::ReadOnly);
int FunctionUID, ij, ik;
MyClass vv;
MyClass2 vv1;
stream >> FunctionUID >> vv >> vv1 >> ij >> ik;
qDebug() << vv.vctr.size() << "faf";
}
void Server::incomingConnection(qintptr val)
{
qDebug() << "Client Connected" << val;
socket = new QTcpSocket;
socket->setSocketDescriptor(val);
if (!socket) {
return;
}
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
connect(socket, SIGNAL(readyRead()), this, SLOT(ImReady()));
}
TCP不发送消息,它是数据流。这意味着您不能只读取那里的所有数据,然后考虑这一条消息。相反,通常发送 header,其中包含消息大小,然后接收方知道要读取多少才能获得整个消息(并且只是这个,而不是读入下一个)。
这意味着您的槽会做这样的事情
void Server::ImReady()
{
uint32 size;
socket->read(&size, 4);
uint32 readTotal = 0;
do {
readTotal += socket->read(buffer, size-readTotal);
} while (readTotal < size);
}
你可以这样写一行
if (socket->bytesAvailable() == 0)
return;
在插槽的开头,然后您根本不会在意每条消息是否发出多次信号。
请注意,上面的代码需要额外的错误处理,例如您必须确保第一个 read
读取所有 4 个字节,并且始终处理 return 值 -1。