Python socket Select 模块显示它收到了读取请求,而它只收到了一个。为什么?
Python socket Select module showing it received to read requests, when it only received one. Why?
我正在创建一个程序,客户端在其中输入包含图像的文件的名称。然后它被转换成一个 numpy 数组,pickle 并发送到服务器。服务器使用 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()
谢谢!
I have noticed that the select function adds the socket twice to the read list for some reason.
没有。 select
returns 只要套接字上有可以使用 recv
检索的信息,套接字就是可读的。当您处理 recv
returns 实际数据的情况时,您不会处理 recv
returns 空缓冲区(即 ''
)的情况如果对等方关闭连接。换句话说:问题不在于 select
,而是您对 select
和 recv
工作方式的假设。
我正在创建一个程序,客户端在其中输入包含图像的文件的名称。然后它被转换成一个 numpy 数组,pickle 并发送到服务器。服务器使用 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()
谢谢!
I have noticed that the select function adds the socket twice to the read list for some reason.
没有。 select
returns 只要套接字上有可以使用 recv
检索的信息,套接字就是可读的。当您处理 recv
returns 实际数据的情况时,您不会处理 recv
returns 空缓冲区(即 ''
)的情况如果对等方关闭连接。换句话说:问题不在于 select
,而是您对 select
和 recv
工作方式的假设。