python - socket.send 和 socket.sendall() 的区别
问题描述
我编写了两个程序来测试服务器端的 p23_server.py 和客户端的 p23_client.py :
p23_server.py
#p23_server.py
import socket
HOST = '10.0.2.15'
PORT = 12345
server = socket.socket()
server.bind((HOST,PORT))
server.listen(1)
(client,addr) = server.accept()
while True:
data = client.recv(32)
if not data:
break
print(data.decode('utf-8'))
server.close()
p23_client.py
#p23_client.py
import socket
import sys
HOST = '10.0.2.15'
PORT = 12345
string = sys.argv[1]
data_to_send = string.encode('utf-8')
s = socket.socket()
s.connect((HOST,PORT))
#s.sendall(data_to_send)
s.send(data_to_send)
s.close()
我运行 p23_server.py 然后执行命令:
wahalez@wahalez:~/dev/python$ python p23_client.py $(python -c 'for i in range(1024): print("a",end="")')
运行客户端并查看服务器输出的内容。
我用 socket.send() 和 socket.sendall() 函数执行了一次。结果是一样的。问题是为什么?不应该只发送一次数据,然后服务器收到 32 个字节,就是这样?
与 send() 不同,此方法继续从字节发送数据,直到所有数据都已发送或发生错误。成功时不返回任何内容。出错时会引发异常,并且无法确定成功发送了多少数据(如果有)。
为什么这两个函数产生相同的结果?
解决方案
仅仅因为 99% 的时间 send() 将设法一次性发送所有数据。从理论上讲,当您使用 send() 时,您可能看不到服务器上的所有数据。
为了强调区别,sendall 的示例伪实现:
def sendall(data):
already_sent = 0
while already_sent < len(data):
already_sent += send(data[already_sent:])
推荐阅读
- amazon-web-services - 为什么创建 S3 目录会创建一个不可见的文件?
- python - 如何在我的层中找到不可微分的操作?
- ruby-on-rails - Ruby 使用循环中的索引来查找 JSONB
- python-3.x - 为什么我的 if 语句没有打破 for 循环,尽管条件得到满足?
- python - 是否可以将 '\vdots' 放在 sympy.Matrix 中?
- gdb - 如何检查断点是否按特定顺序命中?
- php - 我应该使用哪个?Project::select("*") 或 new Project()
- maven - 如何解决我的 BOM 的dependencyManagement 依赖项?
- regex - 使用正则表达式获取特定的连字符字母数字组合
- python - 一种更有效的顺序格式化字符串的方法?