首页 > 解决方案 > 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 字节的数据包。听起来不可能。

该代码中一般发生了什么?

谢谢。

标签: socketstcpbuffernetwork-protocols

解决方案


您的论点是基于 singlesend应该匹配 single的假设recv。但这种情况并非如此。TCP 是字节流,而不是基于消息的协议。这意味着所有重要的是传输的字节。recv对于读取 50 个字节是否需要1 个或 10 个字节无关紧要,这无关紧要。

除此之外,send也不保证发送完整的缓冲区。它可能只发送缓冲区的一部分,即发送者实际上需要检查返回码,以了解现在实际发送了多少给定缓冲区,以及以后需要重试多少发送。

请注意,底层的“数据包”又是另一回事。如果有send2000 字节,则通常需要发送多个数据包(取决于底层数据链路层的最大传输单元)。但这并不意味着一个也需要多个recv。如果所有 2000 字节都已传输到接收方的操作系统级接收缓冲区,那么即使它们以多个数据包的形式传输,也可以立即读取它们。


推荐阅读