我正在创建一个程序,客户端在其中输入包含图像的文件名。然后将其转换为numpy数组,进行腌制并将其发送到服务器。服务器使用PIL ImageDraw在所述图像上方绘制红色X,然后将其发送回客户端。我注意到,出于某种原因,select函数将套接字两次添加到读取列表中。我知道这一点,因为客户端将图像取回,并且在发送过程结束时添加了一个打印功能,并且触发了一次,但是随后一个较早的打印语句又退出了,并返回了错误。这是服务器输出:
b'56925 '
sent
b''
Traceback (most recent call last):
File "server.py", line 31, in <module>
msglengthi = int(msglength)
ValueError: invalid literal for int() with base 10: ''
这是服务器代码:
import socket
import pickle
from PIL import ImageDraw
from PIL import Image
import select
import numpy
IP = socket.gethostbyname(socket.gethostname())
PORT = 4321
HEADERSIZE = 15
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((IP, PORT))
s.listen(5)
socketlist = [s]
readqueue = []
while True:
readqueue, write, exception = select.select(socketlist, [], [])
for socket in readqueue:
if socket == s:
clientsocket, clientaddress = s.accept()
socketlist.append(clientsocket)
print(f"Connection received from {clientaddress}")
clientsocket.send(bytes("Welcome to the server", "utf-8"))
else:
msglen = socket.recv(HEADERSIZE)
msglength = msglen.decode("utf-8")
print(msglen)
msglengthi = int(msglength)
fullmsg = []
x=0
while x<=msglengthi:
msgu = socket.recv(3000)
fullmsg.append(msgu)
x+=3000
fullmsg = b"".join(fullmsg)
msg = pickle.loads(fullmsg)
img = Image.fromarray(msg)
draw = ImageDraw.Draw(img)
width, height = img.size
draw.line((0, 0, width, height), fill="red", width=20)
draw.line((width, 0, 0, height), fill="red", width=20)
payload = pickle.dumps(numpy.array(img))
paylen = len(payload)
socket.send(bytes(f"{paylen:<{HEADERSIZE}}", "utf-8")+payload)
print("sent")
最后是客户端代码:
import socket
import pickle
from PIL import Image
import numpy
PORT = 4321
IP = socket.gethostbyname(socket.gethostname())
HEADERSIZE = 15
cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cs.connect((IP, PORT))
welcomemsg = cs.recv(21)
welcomemsg = welcomemsg.decode("utf-8")
print(welcomemsg)
img = input("Enter image file: ")
imgo = Image.open(img)
imga = numpy.array(imgo)
imgdump = pickle.dumps(imga)
msglen = len(imgdump)
print(msglen)
cs.send(bytes(f"{msglen:<{HEADERSIZE}}", "utf-8")+imgdump)
msglen = cs.recv(HEADERSIZE)
msglen = msglen.decode("utf-8").strip()
msglen = int(msglen)
x=0
fullmsg=[]
while x<=msglen:
msg = cs.recv(3000)
fullmsg.append(msg)
x+=3000
fullmsg = b"".join(fullmsg)
img = pickle.loads(fullmsg)
img = Image.fromarray(img)
img.show()
谢谢!
我注意到,出于某种原因,select函数将套接字两次添加到读取列表中。
没有。select
当套接字上有可以使用检索的信息时,返回该套接字可读recv
。当您处理recv
返回实际数据的情况时,当recv
返回一个空缓冲区(即''
)时,当对等方关闭连接时,它将不处理情况。换句话说:问题不select
只是您对工作方式select
和recv
工作方式的假设。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句