我正在研究一个domotica程序(Extron),我有一个内存问题。因此,我想知道Python对TCP的响应做了什么,我没有放入变量。
我有以下代码行:
Matrix.SendAndWait(str(States.MatrixStatus[States.RecorderStatus['Recorder 2']]['Fullscreen Input'])+'*'+\
str(Collegerama['Recorder 2 Output'])+'%', 0.3, deliTag=b'\x0A')
SendAndWait命令通常用于将响应放入变量中,但我使用它来减慢编程速度,并确保设备已准备好接受下一个命令。
但不是说我有内存泄漏我想知道响应是否放在某处并且永远不会从内存中清除。
答案 0 :(得分:0)
只要信息不溢出,信息就会存储在接收缓冲区中。通过设置 TCP接收窗口大小(https://en.wikipedia.org/wiki/TCP_tuning#Window_size)来防止溢出。如果数据包具有最大大小,则接收缓冲区只能容纳一个数据包。
maximum packet size for a TCP connection
因此数据包最初存储在接收缓冲区中(这是OSI模型中的网络层)从这个接收缓冲区中,它们由OSI模型中的更高层提取,即TCP(OSI模型中的传输层),然后删除标头获取数据/有效负载......
如果未获取当前在接收缓冲区中的数据包,则它们将被新传入的数据包覆盖。因此,如果数据处理速度不够快,则信息丢失,任何新传入的数据包都会覆盖接收缓冲区中的旧数据包。
https://en.wikipedia.org/wiki/OSI_model
在https://www.cubrid.org/blog/understanding-tcp-ip-network-stack中对此进行了详细介绍
数据接收
现在,我们来看看如何接收数据。数据接收是一个 网络堆栈如何处理进入的数据包的过程 图3显示了网络堆栈如何处理收到的数据包。
首先,NIC将数据包写入其内存。它检查是否 数据包通过执行CRC校验有效,然后发送 数据包到主机的内存缓冲区。这个缓冲区是一个内存 驱动程序已经向内核请求并分配了 用于接收数据包。分配缓冲区后,驱动程序 告诉NIC的内存地址和大小。没有主持人的时候 即使NIC收到,驱动程序分配的内存缓冲区也是如此 数据包,NIC可能会丢弃数据包。
将数据包发送到主机内存缓冲区后,NIC会发送一个 中断到主机操作系统。
然后,驱动程序检查它是否可以处理新数据包。 到目前为止,驱动程序 - 网卡通信协议定义了 使用制造商。
当驱动程序应该将数据包发送到上层时,数据包 必须包装在操作系统用于操作系统的数据包结构中 了解数据包。例如,Linux的sk_buff,mbuf BSD系列内核和Microsoft Windows的NET_BUFFER_LIST是 相应OS的数据包结构。司机发送 包裹到上层。
以太网层检查数据包是否有效 解复用上层协议(网络协议)。在这个时候,它 使用以太网头的ethertype值。 IPv4 ethertype 值为0x0800。它删除以太网头,然后发送 数据包到IP层。
IP层还会检查数据包是否有效。换一种说法, 它检查IP头校验和。它在逻辑上决定了它 应该执行IP路由并使本地系统处理数据包, 或将数据包发送到其他系统。如果必须处理数据包 通过本地系统,IP层对上层协议进行解复用 (传输协议)通过引用IP头的原始值。 TCP proto值为6.它删除IP头,然后发送 数据包到TCP层。
与下层一样,TCP层会检查数据包是否存在 有效。它还检查TCP校验和。如前所述,自从 当前网络堆栈使用校验和卸载,TCP校验和是 由NIC计算,而不是由内核计算。
然后它搜索数据包连接的TCP控制块。 这时,
<source IP, source port, target IP, target port>
数据包用作标识符。搜索连接后,它 执行协议来处理数据包。如果收到新的 数据,它将数据添加到接收套接字缓冲区。根据 在TCP状态下,它可以发送新的TCP数据包(例如,ACK数据包)。 现在TCP / IP接收数据包处理已经完成。接收套接字缓冲区的大小是TCP接收窗口。到了 特别是,接收窗口时TCP吞吐量会增加 大。在过去,套接字缓冲区大小已经调整了 应用程序或操作系统配置。最新的网络堆栈有一个 用于调整接收套接字缓冲区大小的函数,即接收 窗口,自动。
当应用程序调用read系统调用时,该区域会更改 到内核区域并将套接字缓冲区中的数据复制到 用户区内存。复制的数据将从套接字中删除 缓冲。然后调用TCP。 TCP增加了接收 窗口,因为套接字缓冲区中有新的空间。然后发送一个 数据包根据协议状态。如果没有传输数据包, 系统调用终止。