如何处理Perl TCP套接字中的消息碎片?
我在 Perl 客户端和 C++ 服务器之间有一个套接字通信。
Perl 代码:
if (!socket(SERVER, AF_INET, SOCK_STREAM, getprotobyname('tcp'))) {
die "Can't allocate socket\n";
} elsif (!connect(SERVER,sockaddr_in($PORT, $tcp_addr))) {
die "Can't connect to server at $tcp_addr port $PORT...\n";
}
SERVER -> autoflush(1);
print SERVER "$line";
如果 $line
太长,它就会被分段,并且在 C++ 服务器端我必须多次调用 recv
(甚至不知道实际的预期长度) !)。
处理它的最佳方法是什么?
我想了一些办法:
- 也许有一些 Perl 模块可以处理它?
- 也许我可以关闭碎片,但这不会导致更多的传输失败吗?
- 我可以将消息长度添加到发送的消息中,然后调用
recv
直到收到整个消息,但这不是很丑吗? - 还要别的吗?
最好的解决方案是什么?
I have a socket comminucation between Perl client and C++ server.
Perl code:
if (!socket(SERVER, AF_INET, SOCK_STREAM, getprotobyname('tcp'))) {
die "Can't allocate socket\n";
} elsif (!connect(SERVER,sockaddr_in($PORT, $tcp_addr))) {
die "Can't connect to server at $tcp_addr port $PORT...\n";
}
SERVER -> autoflush(1);
print SERVER "$line";
If $line
was too long, it is being fragmented, and on the C++ server side I have to call recv
several times (without even knowing the actual expected length!).
What are the best ways to deal with it?
I thought of some ways:
- Maybe there is some Perl module that deals with it?
- Maybe I can just turn off fragmentation, but wouldn't it cause more transmission fails?
- I can just add the message length to the sent message, and I will call
recv
until I receive the whole message, but isn't it just ugly? - Anything else?
What would the best solution be?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
将消息长度作为 4 字节标头添加到消息中。这并不难看,但正如“专业人士”所做的那样。 TCP/IP 是一种面向流的协议。您很幸运,在一次接收呼叫中收到了消息。可以获得任意数量的字节,只有一半消息、一个半消息等,因为 tcp/ip 正在传输连续的字节流,而没有该级别的任何数据包概念。
这样做的好处是,您可以在用户空间中缓冲消息,并且可以将任意数量的字节读入该缓冲区,并且从该缓冲区处理多个消息,而不是重复调用 recv()
Add the message length as a 4byte header to the message. This is not ugly, but just as the "pros" do it. TCP/IP is a stream oriented protocol. You were just lucky that you got your messages in one recv call. It is possible to get any number of bytes, only half a message, one and a half message etc. as tcp/ip is transferring a continuous stream of bytes without any notion of packets at that level.
The good side of this is that you can buffer your messages in userspace and can read as many bytes as you want into that buffer, and the process multiple messages out of this buffer isntead of repeatedly calling recv()
最好的解决方案是继续调用“recv”,直到收到完整的消息。如果需要确定何时拥有完整消息,请在消息前面加上消息长度或在消息后面添加终止符。我不知道你为什么认为那很丑。
The best solution is to keep calling 'recv' until you have the whole message. If necessary to determine when you have the whole message, either prefix the message with its length or put a terminator after it. I'm not sure why you think that's ugly.