简体   繁体   English

无法从TCP套接字读取

[英]Cannot read from TCP socket

I have a C++ client using QT and a JAVA server and I have successfully written from the client to the server but I cannot write from the server to the client. 我有一个使用QT和JAVA服务器的C ++客户端,并且已成功从客户端写入服务器,但是无法从服务器写入客户端。 My code: 我的代码:

QString
Client::readTCP ( )
{
    socketTCP->waitForReadyRead();

    QTextStream in (socketTCP);

    return in.readAll() ;
}

// Later on

qDebug() << Client::readTCP();

But no matter what method I choose I can't get a response from the server. 但是,无论我选择哪种方法,都无法从服务器获得响应。 The server code is as follows: 服务器代码如下:

DataOutputStream  output = new DataOutputStream (SOCKET.getOutputStream());

output.writeBytes ( "myString" );

ANSWER: 回答:

It works either because I changed in.readAll() to in.readLine() or it is because I waited a couple seconds after the server started before sending a message. 之所以起作用,是因为我将in.readAll()更改为in.readLine() ,还是因为我在服务器启动后等待了几秒钟才发送消息。

The QTextStream::readAll function attempts to read the entire contents of the stream. QTextStream::readAll函数尝试读取流的全部内容。 Either this message is or isn't the entire contents of the stream. 此消息是否是流的全部内容。

If this message isn't the entire contents of the stream, then it should not return. 如果此消息不是流的全部内容,则不应返回。 It would be a serious error if readAll returned only a part of the contents of the stream despite the fact that it's specified to return all the contents. 如果readAll只指定了返回所有内容的事实,则readAll仅返回流的一部分内容将是一个严重的错误。

If this is the entire contents of the stream, then the server is broken. 如果这是流的全部内容,则服务器损坏。 If it doesn't close the socket, how can the client know it's received the entire contents? 如果它没有关闭套接字,客户端如何知道它已收到全部内容? Unless there's some other way to indicate end of message, it has to be indicated by closing the stream, and you don't show the server closing the stream. 除非有其他指示消息结束的方法,否则必须通过关闭流来指示它,并且您不会显示服务器正在关闭流。

I'll repeat the advice I always give when I see problems like this -- do not ever implement a network protocol until you specify that protocol in a protocol specification. 当我遇到这样的问题时,我将重复我始终给出的建议-永远不要实施网络协议,除非在协议规范中指定该协议。 Otherwise, it's not possible to fix problems where the server and client disagree because there's no way to know which end is right. 否则,不可能解决服务器和客户端不同意的问题,因为无法知道哪一端是正确的。 Here, the server and client disagree over how the end of a message is to be marked, and without a protocol specification to refer to, there's no way to know which end to fix. 在这里,服务器和客户端在如何标记消息的末尾上存在分歧,并且没有协议规范可供参考,因此无法知道要修复的末尾。

If you had a protocol specification, you could just look at the section that explains how the ends of messages are marked and detected. 如果您有协议规范,则只需查看解释如何标记和检测消息结尾的部分即可。 Then you could fix whichever end doesn't follow the specification. 然后,您可以修复不符合规范的任何一端。 (Or, if the specification doesn't say how, then fix the specification! Clearly, this has to happen somehow and it's the specification's job to explain how.) (或者,如果规范没有说明如何,那么请修订该规范!显然,这必须以某种方式发生,而规范的工作就是解释如何做。)

In Java, after sending data to buffer, flush it. 在Java中,将数据发送到缓冲区后,刷新它。 Output streams have flush() method which forces any data left in stream to be written/sent. 输出流具有flush()方法,该方法强制将流中剩余的任何数据写入/发送。 Try that if using readAll() on client side. 如果在客户端使用readAll(),请尝试该操作。

Also, readLine() is advised if you know how much data will be sent. 另外,如果您知道将发送多少数据,则建议使用readLine()。 You can loop trough in.readLine() until it gets null. 您可以循环通过in.readLine()直到其为空。 Also readLine() will remove any \\n or \\r\\n. 同样,readLine()将删除任何\\ n或\\ r \\ n。

I have no experience with Qt so I cannot say if you are reading correctly from the socket, but with Java I use PrintStream 's method println when sending text, and a VS C++ Client receives it just fine using recv . 我没有使用Qt的经验,所以我不能说您是否从套接字正确读取消息,但是使用Java时,我在发送文本时使用PrintStream的方法println ,而VS C ++ Client可以使用recv很好地接收它。

Also, you may want to check if the packet is actually sent over the socket using Wireshark. 另外,您可能想检查数据包是否实际上是使用Wireshark通过套接字发送的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM