情况: 我有用Python制作的tcp客户端和用Qt制作的tcp服务器。我尝试用我的客户端发送字节但我无法让Qt服务器读取这些字节。
使用Python制作的客户端和服务器,一切正常。此外,我可以让我的Python客户端使用C#服务器,没有任何问题。
Python客户端代码:
import socket
import sys
HOST = 'localhost'
PORT = 50505
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as msg:
sys.stderr.write("[ERROR] %s\n" % msg)
sys.exit(1)
try:
sock.connect((HOST, PORT))
except socket.error as msg:
sys.stderr.write("[ERROR] %s\n" % msg)
sys.exit(2)
sock.send(b'Hello World!\r\n')
我已经尝试过e.q fortuneserver / fortuneclient代码示例,但它们没有用。 Bytesavailable()始终为0.
所以问题是如何在我的Qt应用程序中读到“Hello World!”线?我只需要在服务器发出newConnection()信号时启动的那个函数。
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(startRead()));
更新:
Qt服务器的部分代码:
void Server::startRead()
{
QDataStream in(tcpSocket);
in.setVersion(QDataStream::Qt_4_0);
QString ipAddress;
if (blockSize == 0) {
if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
return;
in >> blockSize;
}
if (tcpSocket->bytesAvailable() < blockSize)
return;
QString nextFortune;
in >> nextFortune;
statusLabel->setText(nextFortune);
ABOVE IS FROM FORTUNE CLIENT EXAMPLE.
BELOW IS FROM ANOTHER EXAMPLE.
/*
char buffer[128] = {0};
QTcpSocket *client = tcpServer->nextPendingConnection();
qDebug() << client->bytesAvailable();
for (int i=0; i<100; i++)
{
client->read(buffer, client->bytesAvailable());
qDebug() << buffer;
std::string sString(buffer);
QString qString(sString.c_str());
statusLabel->setText(qString);
}
*/
}
最后一部分相当糟糕。我试图制作一些东西,但我不知道我在用Qt做什么:)
答案 0 :(得分:1)
当有可用数据时,您需要安排代码读取。根据您的描述,当startRead()运行时,还没有可用的数据。
我假设你打电话QTcpServer::nextPendingConnection
让tcpSocket
进入startRead()
?如果没有,你需要这样做。
只需将readyRead
或tcpSocket
的{{1}}信号连接到client
广告位,然后查看doRead()
并阅读该广告位。
每当有新数据到达时,都会调用此插槽。
您可能还对来自TCP套接字的bytesAvailable()
信号感兴趣,以了解它何时完成发送数据。
答案 1 :(得分:0)
您附加的服务器代码以这种方式工作:每个“数据包”(逻辑1)都由size
字段组成,并跟随size
个数据。
基本上它是这样的:
quint16
足够的字节要读,等待
更多。quint16
阅读,等到我们有
至少quint16
的金额
待阅读。在我们理解之后,即使您像服务器期望的那样编写数据包长度,您尝试做的仍然无效。这是因为服务器从套接字读取QString
的方式。客户端正在写一个原始的python字符串,我猜它只是在套接字上写一个普通的旧ASCII。服务器使用QDataStream
从套接字读取(这是在Qt中序列化的标准方法)。如果你看一下QString
的运算符&lt;&lt;的实现here,它不仅仅是读取ASCII字符串。
如果您无法更改服务器,请更改您的客户端。您可以在PyQt附带的示例中看到fortune客户端的实现。