使用socket编程接收消息时的问题
首先,很抱歉我无法给您举一个最小的例子。代码开始变得非常复杂,我认为我无法再编写代码了。
但如果我简单地告诉你我在做什么,这段代码允许我通过套接字编程在我编写的应用程序和另一个外部应用程序之间进行通信。
我向该外部程序发送一个文件路径,并将该路径添加到其自己的设置中。
奇怪的是,如果我第一次发送消息(即文件路径),就没有问题。但是当我第二次发送它时,外部应用程序没有收到消息(并且我没有收到任何错误)。此时事情开始变得更加奇怪,因为如果我第三次发送消息,这次它会将我第二次发送的消息/文件路径获取到它自己的设置。
案例:
sent message: A
message received: A
sent message: B
message received: (message not received)
sent message: B
message received: B
sent message : C
message received: (message not received)
sent message: C
message received: (message not received)
sent message: C
message received: C
.
.
.
("message not received" keeps increasing)
我使用的功能:
def send_message(socket: QTcpSocket, message: str = "", message_type: str = "message"):
socket_stream = QDataStream(socket)
socket_stream.setVersion(QDataStream.Qt_5_10)
header_array = QByteArray()
message_size = len(message.encode("utf-8"))
header = f"messageType:{message_type},messageSize:{message_size},"
header_array.prepend(header.encode("utf-8"))
header_array.resize(128)
byte_array = QByteArray(message.encode("utf-8"))
byte_array.prepend(header_array)
socket_stream << byte_array
socket_stream.writeString(message)
def read_socket(self):
buffer = QByteArray()
socket_stream = QDataStream(self.socket)
socket_stream.setVersion(QDataStream.Qt_5_10)
socket_stream.startTransaction()
socket_stream >> buffer
header = buffer.mid(0, 128)
...
message = socket_stream.readString()
什么样的情况会导致这个问题?
First of all, I am sorry that I cannot give you a minimal example. The code started to become very complex and I don't think I can prepare one anymore.
but if I were to tell you simply what I'm doing, this code allows me to communicate between the application I wrote and another external application via socket programming.
I send a file path to this external program and it adds this path to its own settings.
The weird thing is that if I send a message (i.e. the file path) for the first time, there is no problem. But when I send it for the second time, the external application does not receive the message (and I don't get any errors). Things start to get even weirder at this point because if I send a message for the third time, this time it gets the message / file path I sent for the second time to its own settings.
Example case:
sent message: A
message received: A
sent message: B
message received: (message not received)
sent message: B
message received: B
sent message : C
message received: (message not received)
sent message: C
message received: (message not received)
sent message: C
message received: C
.
.
.
("message not received" keeps increasing)
The functions I used:
def send_message(socket: QTcpSocket, message: str = "", message_type: str = "message"):
socket_stream = QDataStream(socket)
socket_stream.setVersion(QDataStream.Qt_5_10)
header_array = QByteArray()
message_size = len(message.encode("utf-8"))
header = f"messageType:{message_type},messageSize:{message_size},"
header_array.prepend(header.encode("utf-8"))
header_array.resize(128)
byte_array = QByteArray(message.encode("utf-8"))
byte_array.prepend(header_array)
socket_stream << byte_array
socket_stream.writeString(message)
def read_socket(self):
buffer = QByteArray()
socket_stream = QDataStream(self.socket)
socket_stream.setVersion(QDataStream.Qt_5_10)
socket_stream.startTransaction()
socket_stream >> buffer
header = buffer.mid(0, 128)
...
message = socket_stream.readString()
What kind of situations can cause this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您必须记住 TCP 不是数据包协议——它是流协议。您将不会收到与发送时形状完全相同的数据包。如果您快速发送 40 字节和 80 字节,另一端可能会获得 120 字节的单次读取。或者,它可能会获取 20 个字节,然后是 60 个字节,然后是 40 个字节。没有任何保证。您必须能够在一次读取中处理多条消息,并且必须有一种方法来检测消息何时完成。
You MUST REMEMBER that TCP is not a packet protocol -- it is a streaming protocol. You will NOT get packets in exactly the same shape they were sent. If you send 40 bytes and 80 bytes quickly, the other end is probably going to get a single read of 120 bytes. Or, it might get 20 bytes then 60 bytes then 40 bytes. There are no guarantees. You MUST be able to handle multiple messages in a single read, and you MUST have a way to detect when your message is finished.