首先说明一下问题,因为在使用recv和sendall接受和发送的时候
1.接收方如何确信息已经全部接收
2.如果发送方发送信息的字节长度超过接收方设置的缓存长度时会发生什么
假定使用客户端向服务端发送信息,进行验证
#===========发送端============
from socket import *
clientSocket = socket(AF_INET,SOCK_STREAM)
port = 9000
addr = "127.0.0.1" #本机地址
str1 = b"abc"
print(len(str1)) #字节数为3
str2 = b"jkl"
str3 = b"zxc"
clientSocket.connect((addr,port))
clientSocket.sendall(str1)
clientSocket.sendall(str2)
clientSocket.sendall(str3)
clientSocket.close()
#=============接收端======================
from socket import *
serverSocket = socket(AF_INET,SOCK_STREAM)
port = 9000
addr = ''
serverSocket.bind((addr,port))
serverSocket.listen(1)
while True:
connectionSocket, addr = serverSocket.accept()
message1 = connectionSocket.recv(1024).decode()
message2 = connectionSocket.recv(1024).decode()
message3 = connectionSocket.recv(1024).decode()
print(message1) #打印结果为 abc
print(message2) #打印结果为 jkl
print(message3) #打印结果为 zxc
connectionSocket.close()
一般在发送端发送的信息长度小于接收端缓存长度的情况下,sendall 与 recv是一 一对应的,
但一般情况下发送端是不知道接收端设置的缓存长度的,接收端也不知道发送端发送的信息长度,所以当发送端发送的信息超过接收端的缓存长度时的情况如下
#===========发送端============
from socket import *
clientSocket = socket(AF_INET,SOCK_STREAM)
port = 9000
addr = "127.0.0.1" #本机地址
str1 = b"abc"
print(len(str1)) #字节数为3
clientSocket.connect((addr,port))
clientSocket.sendall(str1)
clientSocket.close()
#=============接收端======================
from socket import *
serverSocket = socket(AF_INET,SOCK_STREAM)
port = 9000
addr = ''
serverSocket.bind((addr,port))
serverSocket.listen(1)
while True:
connectionSocket, addr = serverSocket.accept()
message1 = connectionSocket.recv(2).decode() #设置2字节的缓存
print(message1) #打印结果为 ab
connectionSocket.close()
由打印的结果可知,接收端只接受了2字节的数据,那么剩余的数据怎么办?如下
#=============接收端======================
from socket import *
serverSocket = socket(AF_INET,SOCK_STREAM)
port = 9000
addr = ''
serverSocket.bind((addr,port))
serverSocket.listen(1)
while True:
connectionSocket, addr = serverSocket.accept()
message1 = connectionSocket.recv(2).decode() #设置2字节的缓存
message2 = connectionSocket.recv(2).decode()
print(message1) #打印结果为 ab
print(message2) #打印结果为 c
connectionSocket.close()
剩余的数据通过再次调用recv得到,那么如何做到发送端发送任意长度的信息,接收端都可以完整的接收信息?如下
#=============接收端======================
from socket import *
serverSocket = socket(AF_INET,SOCK_STREAM)
port = 9000
addr = ''
serverSocket.bind((addr,port))
serverSocket.listen(1)
while True:
connectionSocket, addr = serverSocket.accept()
buf = ''
while True
message1 = connectionSocket.recv(2).decode() #设置2字节的缓存
buf += message1
print(message1)
#打印结果依次是
# ab
# c
# ''
if not message1:
break
print(buf) #打印结果为 abc
connectionSocket.close()
通过使用while循环来接受数据,依次接收到 ab , c , 然后已近接收完数据后会在下一次循环后再次调用recv,但数据已经接受完了,到达recv时会发生阻塞。当发送端发送信息结束时调clientSocket.close()后,接收端recv将结束阻塞并返回空字符串' ',所以判断字符串为空字符串后将break 结束while循环。
总结
1.接收方如何确信息已经全部接收
一般在接收端缓存大于发送端发送的信息长度的情况下,sendall与recv一 一对应,即发送端调用一次sendall, 接收端将返回一次recv的结果。
在接收端缓存小于发送端发送信息的长度时,sendall与recv是一对多的关系,即发送端调用一次sendall 发送901字节, 接收端接收缓存为100,则需要调用10次recv进行接收,当然可以使用while循环,在使用while循环时要判断若为空字符串则break跳出循环。
2.如果发送方发送信息的字节长度超过接收方设置的缓存长度时会发生什么
什么都不会发生,接收端的接收缓存小于发送端的信息的长度时,接收端只会接收缓存大小的信息,并不会报错
最后
send与sendall的差别,看别的文章
空字符串的判断
str1 = ""
if str1:
print("true")
else:
print("false")
#打印结果为 false
#空字符串在条件判断在将作为false