看看这个基本的Python小程序:
import socket
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind(("", 10000))
tcpsock.listen(10)
(sock, (ip, port)) = tcpsock.accept()
s = sock.recv(1024)
print(s)
Run Code Online (Sandbox Code Playgroud)
第二个程序:
import socket
import time
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 10000))
time.sleep(1)
sock.sendall(b'hello world')
Run Code Online (Sandbox Code Playgroud)
第一个程序是套接字服务器。它通过套接字接收消息并将其显示在控制台上。第二个程序是连接到服务器并向其发送消息的客户端。
如您所见,服务器读取最大长度为 1024 字节的消息。我的客户端发送了几个字节。我的问题是:服务器如何知道消息在“d”字符之后结束?
多年来我一直在使用套接字,并且我总是实现一种分隔符机制,以便知道消息何时停止。但它似乎自动工作。我的问题是:如何?我知道 TCP 汽车片段消息。那么,如果 paquet 在我的消息中间被截断,会发生什么?它是由操作系统管理的吗?
谢谢
服务器如何知道消息在“d”字符之后结束?
它不是。TCP中甚至没有消息的概念。recv只是返回现有的内容:如果没有可用数据,它会阻塞;如果有数据可用,则返回可以读取到给定大小的内容。“数据可用”意味着套接字接收缓冲区中有数据,这些数据是由操作系统内核放入其中的。换句话说:recv在返回请求的字节数之前不会阻塞,但当套接字接收缓冲区中至少有一个字节时它就会返回。
例如,如果客户端执行两次操作send或sendall在不久之后执行一次操作,则单个recv操作可能会同时返回两个“消息”。这可以通过推迟recv(在其之前添加一些睡眠)轻松触发,以便保证两条“消息”都到达客户端。