sockets - TCP 连接和客户端和服务器的不同缓冲区大小
问题描述
如果我要在客户端和服务器之间建立连接,并为它们中的每一个配置不同的缓冲区大小,会发生什么。
这是我客户的代码:
import socket,sys
TCP_IP = sys.argv[1]
TCP_PORT = int(sys.argv[2])
BUFFER_SIZE = 1024
MESSAGE = "World! Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()
print "received data:", data
服务器的代码:
import socket,sys
TCP_IP = '0.0.0.0'
TCP_PORT = int(sys.argv[1])
BUFFER_SIZE = 5
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
while True:
conn, addr = s.accept()
print 'New connection from:', addr
while True:
data = conn.recv(BUFFER_SIZE)
if not data: break
print "received:", data
conn.send(data.upper())
conn.close()
这意味着我将被限制为只有 5 个字节?这意味着我将无法接收完整的数据包并且会丢失 1024-5 个数据包?我或者这是否意味着我只能获得 5 个字节的数据包,这意味着当客户端发送它时,我必须将 1024 除以 5 并获得 204.8 个数据包(?),而不是接收一个 1024 字节的数据包。听起来不可能。
该代码中一般发生了什么?
谢谢。
解决方案
您的论点是基于 singlesend
应该匹配 single的假设recv
。但这种情况并非如此。TCP 是字节流,而不是基于消息的协议。这意味着所有重要的是传输的字节。recv
对于读取 50 个字节是否需要1 个或 10 个字节无关紧要,这无关紧要。
除此之外,send
也不保证发送完整的缓冲区。它可能只发送缓冲区的一部分,即发送者实际上需要检查返回码,以了解现在实际发送了多少给定缓冲区,以及以后需要重试多少发送。
请注意,底层的“数据包”又是另一回事。如果有send
2000 字节,则通常需要发送多个数据包(取决于底层数据链路层的最大传输单元)。但这并不意味着一个也需要多个recv
。如果所有 2000 字节都已传输到接收方的操作系统级接收缓冲区,那么即使它们以多个数据包的形式传输,也可以立即读取它们。
推荐阅读
- javascript - 从 component.ts 访问 *ngFor 的元素
- javascript - Hyperledger Composer REST 服务器注销
- sql - LEFT JOIN 不匹配
- angular - Angular 5 材料日期选择器不适用于时刻日期适配器和目标 es2015
- javascript - 提取道具中的对象
- python - 我的 Python Set() 中的某些元素最终变成了十六进制
- javascript - Gatsby.js - 自定义 css 模块不产生任何效果
- python - 在没有管理员权限的 Windows 上安装 python 模块
- selenium-webdriver - 根据 xpath 索引检索链接计数
- ruby-on-rails - 将两条记录分组并通过 ActiveRecord 中的 HABTM 关联组 | 导轨