【发布时间】:2015-06-26 06:56:20
【问题描述】:
假设我有这个 Python 代码:
read=true;
i=0;
while (read){
data =sock.recv(100);
i+=1;
print data;
}
现在我在另一端输入 101 个字符的套接字。在接收结束时i 的值将是 2,因为所有提要都不会在 100 个字符的缓冲区中结束 - 一个剩余的字符将进入另一个迭代。这是可以理解的:缓冲区填满,信息被刷新到变量data。
但是如果我只给套接字提供 10 个字符会发生什么?缓冲区没有填满,那么sock 到底是如何知道在收到 10 个字符后将不再有流来的,是时候刷新缓冲区并将消息返回给“数据”了?
实际复制粘贴示例:
服务器:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.bind("/tmp/somesfile")
s.accept(1)
s.listen()
conn, addr = s.accept()
i=0
read=True
while read:
conn.recv(10)
i = i + 1
print i
客户:
c = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
c.connect("/tmp/somesfile")
发送数据(客户端上的控制台)
>>> c.send("aaaaa")
5
>>> c.send("a")
1
>>> c.send("a")
1
>>> c.send("a")
1
>>> c.send("a")
1
>>>
接收数据(服务器上的控制台)
'aaaaa'
1
'a'
2
'a'
3
'a'
4
'a'
5
服务器为接收到的数据准备了 10 字节的缓冲区。在第一次突发时,它收到 5 个字符 - 所有 5 个字符都存储到同一个缓冲区并被刷新。在进一步的 4 次突发中,服务器以接收之间的时间间隔一一发送 4 个分片。所有这些字符都以相同的模式刷新,即一个接一个。在任何情况下,缓冲区都没有填满。我的问题是:除了溢出之外,是什么导致服务器套接字刷新缓冲区?现在下一个字节不来怎么办?
字符串是以空字符结尾的字节模式。套接字流是否已终止?
【问题讨论】:
-
我不确定你在问什么。
recv的工作方式,你得到缓冲区中的任何东西,直到你要求的数量(这意味着:可能少于你要求的)。因此,如果只有 10 个字节,您将获得 10 个字节。操作系统必须处理的特殊问题是什么? -
如果你要 10 个字节但只有 5 个?它会阻塞流程,直到有人再提供 5 个字节并填充缓冲区?我可能被 python 宠坏了..那里的一切都过于简单了....
-
我不记得它在 C 中是如何的,但是在 Python 中,如果我 recv(100) 并将套接字以 100 个字节一个接一个地馈送到另一端(比如之间有 1 秒的延迟) feeds)该过程将解锁 100 次。如果我一次给它 100 个字节 - recv() 只会解除阻塞一次。这意味着即使缓冲区未满,recv() 也会释放块。基本上我只是在不同的部分发送相同的数据,并且过程行为不同
-
这与 Python 或 C 无关,而是与底层的套接字 API 相关。只要接收缓冲区中至少有 1 个字节,
recv就会返回这个而不是阻塞。
标签: sockets