同一个 TCP 连接中的两个发送者之间是否完全隔离? [英] Is there complete isolation between two sendalls in the same TCP connection?

查看:31
本文介绍了同一个 TCP 连接中的两个发送者之间是否完全隔离?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个TCP的问题困扰我很久了,但是因为在本地实验环境下很难模拟丢包(本地网速太快了,丢包很难),所以一直没有能够找到答案.

This TCP problem has been bothering me for a long time, but because it is difficult to simulate package loss in the local experimental environment(the local network speed is so fast that it is difficult to lose packages), I have not been able to find the answer.

我的问题是我想基于TCP协议在两个进程之间实现一个RPC.最有效的方法是建立一次连接,然后这个连接可以反复使用,这样我就不必重复三次握手和四次分手的过程.但是在我的实现过程中,服务器端收到的包经常混杂着多个请求,并且没有被隔离,给我的设计带来了问题.

My problem is that I want to implement an RPC between two processes based on the TCP protocol. The most efficient way is to establish a connection once and then this connection can be used again and again, so I don't have to repeat the process of three times handshakes and four times breakups. However, during my implementation, the packages received by the server were often mixed with multiple requests and they were not isolated, which caused problems for my design.

众所周知,在建立连接后,如果我的客户端调用socket.sendall(A),其中我们假设A是一个长度为40KB的包,其中包含以下内容的详细信息请求.由于包内容太长,我们假设内核自动将这个包拆分为10个包,分10次发送出去.我们都知道,由于 TCP 连接的可靠行为,如果十个包中的第九个在传输过程中碰巧丢失(假设客户端程序恰好在所有包发送后就死了,那么重新发送不是可能),那么服务器端的应用层只会读取前八个包的内容,即使正确审核也不会得到第十个包.

As we all know, after a connection has been established, if my client calls socket.sendall(A), in which we assume that A is a package of 40KB in length containing the details of the request. Because the package content is too long, let's assume that the kernel automatically splits this package into 10 packages and sends them out in 10 times. We all know that due to the reliable behavior of TCP connections, if the ninth of the ten packages happens to be missing during transmission (and assume the client program happens to be dead right after all package were sent, so that re-send is not possible), then the application layer of the server side will only read the contents of the first eight packages and will not get the tenth package even if it was properly revieved.

我的问题是,如果客户端依次发送两个请求

My question is, if the client sends two requests in sequence

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST, PORT))
client.sendall(A)
client.sendall(B)
client.close()

并假设在传输过程中丢失了请求 A 的第九个包,所有其他包都已正确接收.我们的服务器端使用 socket.recv(4) 首先读取包 1 并了解到接下来的 40KB 内容属于请求 A,但是请求 A 的可靠包只有 8 个,在这种情况下,如果服务端应用层继续调用socket.recv(),会不会和请求B的内容混读?

and assume the ninth package of request A is missing during transmission, all other packages were properly recieved. Our server side use socket.recv(4) first reads package 1 and learns that the next 40KB of content belongs to request A, but there's only 8 reliable packages of request A, in this perticularly situation, if the application layer of server side continues to call socket.recv(), will it get a mix reads with the contents of request B?

如果我想保证两个RPC请求互不干扰,是不是每次请求都要建立不同的TCP连接,而不是在同一个连接中多次传递请求内容?

If I want to ensure that the two RPC requests do not interfere with each other, do I have to establish a different TCP connection for each request, instead of passing the request content multiple times in the same connection?

谢谢!

推荐答案

TCP 保证数据按顺序没有任何间隙传送,即如果数据包丢失丢失后的数据只有在丢失的数据恢复(即重新提交和接收)并交付给应用程序后才会交付给应用程序.

TCP guarantees that data are delivered in order and without any gaps, i.e. if packets get lost the data following the loss will only be delivered to the application once the lost data got recovered (i.e. resubmitted and received) and delivered to the application.

TCP 是一个字节流.边界"在两个连续的 sendsendall 之间不是这个字节流的一部分,只是有效载荷本身.这意味着 sendsendall 可能与另一端的 recv 不完全匹配 - 这是一个经常但错误的假设.如果需要某种消息语义(即诸如请求"、响应"之类的东西),则该消息语义需要明确地成为数据的一部分,并且不能从希望单个 recv 将始终匹配单个 send.实现此目的的典型方法是为消息添加长度前缀或使用特殊字节序列作为消息分隔符.

TCP is a byte stream though. The "borders" between two consecutive send or sendall are not part of this byte stream, only the payload itself. This means that a send or sendall might not exactly match a recv at the other side - which is an assumption often but wrongly made. If some kind of message semantic is needed (i.e. something like "request", "response") this message semantic needs to be explicitly be part of the data and can not be derived from hoping that a single recv will always match a single send. Typical ways to achieve this are prefixing a message with a length or having a special byte sequence as message separater.

这篇关于同一个 TCP 连接中的两个发送者之间是否完全隔离?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆