QTcpSocket::readAll() is empty
QTcpSocket::readAll() is empty
我是Qt的新手,有点挣扎。我正在尝试使用 QTcpSocket 将字符串从客户端发送到服务器。
客户端:
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << name;
tSock->connectToHost(ipAddress, portNumb.toInt());
tSock->waitForConnected();
tSock->write(block); // block is not empty
tSock->flush();
服务器端:
void Server::readyRead()
{
QByteArray block;
QDataStream out(&block, QIODevice::ReadOnly);
out << tcpSocket->readAll();
QString name(block); // block is empty
players.insert(name, tcpSocket);
std::cout << "name: " << name.toStdString(); // TODO remove
}
在服务器端,程序在接收数据时输入readyRead()
,但块为空,尽管在客户端调用tSock->write(block)
块时不为空...问题似乎出在哪里?我将不胜感激任何帮助。谢谢!
编辑:您的错误是您在只读模式下打开out
数据流,但尝试将收到的字节数组写入其中:
void Server::readyRead()
{
QByteArray block;
QDataStream out(&block, QIODevice::ReadOnly); // !mistake, WriteOnly mode is needed
out << tcpSocket->readAll(); // this is write operation
//...
}
另外:请注意,Qt数据类型的序列化机制在这种情况下很有用:
tSock->write(block); // this is write just a raw data of the block, not the "QByteArray"
您可以使用流操作将必要的 Qt 数据类型直接写入套接字,而无需转换为QByteArray
:
// Connect firstly
tSock->connectToHost(ipAddress, portNumb.toInt());
tSock->waitForConnected();
// Then open a data stream for the socket and write to it:
QDataStream out(tSock, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << name; // write string directly without a convertion to QByteArray
// Then you may
tSock->flush();
在客户端,然后在服务器端使用类似的流操作:
void Server::readyRead()
{
QString name;
QDataStream in(tcpSocket, QIODevice::ReadOnly /*or QIODevice::ReadWrite if necessary */);
in.setVersion(QDataStream::Qt_4_0);
in >> name; // read the string
//...
}
还可以在另一个Qt的I/O设备上读取/写入对象:QFile,QSerialPort,QProcess,QBuffer等。
编辑 2:不保证在readyRead
信号上您会收到发送的完整包裹。因此,请参阅下面的示例。
请注意,在实际情况下(当您在客户端-服务器通信中有几个不同的数据包,并且不知道您收到的几个可能的数据包是哪种时),通常会使用更复杂的算法,因为在通信中的readyRead事件上可能会出现以下情况:
- 收到完整的数据包
- 仅收到包裹的一部分
- 一起收到了几个包裹
算法的变体(Qt 4财富客户端示例):
void Client::readFortune() // on readyRead
{
QDataStream in(tcpSocket);
in.setVersion(QDataStream::Qt_4_0);
if (blockSize == 0) {
if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
return;
in >> blockSize;
}
if (tcpSocket->bytesAvailable() < blockSize)
return;
QString nextFortune;
in >> nextFortune;
//...
}
Qt 4.0是Qt的旧版本,因此另请参阅Qt 5.9财富客户端示例
您的服务器似乎没有足够的时间从客户端写入数据。 请尝试这个..
tcpsocket->waitForBytesWritten(1000);
readyRead
代码错误地填写了block
。您还假设您将读取足够的数据来传达整个字符串。这永远无法保证。当readyRead
触发它时,您知道至少有一个字节要读取。QDataStream
交易系统对此有所帮助。
这将是一个正确的实现:
class Server : public QObject {
Q_OBJECT
QPointer<QTcpSocket> m_socket;
QDataStream m_in{m_socket.data(), &QIODevice::ReadOnly};
void onReadyRead();
public:
Server(QTcpSocket * socket, QObject * parent = {}) :
QObject(parent),
m_socket(socket)
{
connect(socket, &QIODevice::readyRead, this, &Server::onReadyRead);
}
}
void onReadyRead() {
while (true) { // must keep reading as long as names are available
QString name;
in >> name;
if (in.commitTransaction()) {
qDebug << name;
players.insert(name, &m_socket.data());
} else
break;
}
};
相关文章:
- Why is UINT32_MAX + 1 = 0?
- C++错误:"error: int aaa::bbb is protected within this context"
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 使用 cmake 的 Linux 终端上的"Conversion to non-scalar type is requested"错误
- Is !NaN not a NaN?
- Directx 11 - CompileFromFile() is not compiling
- Centos7 g++ "to_string is not in a member of std"
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- Where is std::hardware_destructive_interference_size?
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- 为什么"(!v.empty())"比"(v.size() >0)"好?
- Qt3D:"Mesh is empty, nothing to load"消息
- QTcpSocket::readAll() is empty
- 如何在视觉C++中编写"if textbox is empty"
- Matlab's is empty for a std::vector ( C++)
- "except that a default constructed array is not empty"是什么意思?
- QTemporaryFile is empty
- "Fit data is empty" 当"TH1::SetDefaultSumw2"打开时
- CAS: Service Ticket/CAS-Server reply is empty
- Vector is returned empty