我想做的是:将图像从Java客户端发送到Python服务器。 Python服务器从图像中检测到一个对象,并向后发送检测框坐标。服务器必须保持连接状态。
问题1:接收数据的最佳方法是什么?
当我在Python中收到图像时,我将clientsocket.recv(1024)
与while循环一起使用,但是recv
正在阻塞并且没有中断循环。
像使用recv(400000)
那样一次接收数据,或者当len(data) != 1024
都可以中断时,但是我想知道是否还有其他方法可以中断循环或接收数据,因为您可能会得到比4000000
或数据更大的图像大小为1024
的倍数。
当我单击UI中的按钮时,Java正在发送图像。如果我使用settimeout
或setblocking`,Python服务器将不会等到我单击按钮进行图像发送后再发送。
问题2:如何在客户端关闭之前保持连接?
建立连接后,我将接收图像并在while循环中发送坐标,因此不必在每次发送图像时都重新连接。但是由于发送坐标是在while循环中,因此Java客户端将在while循环中断之前不会接收坐标。
Python服务器:
clientsocket, addr = s.accept()
while True:
f = open('image.jpg', 'wb')
while True:
data = clientsocket.recv(1024)
f.write(data)
if not data:
break
detectObject("image.jpg")
clientsocket.send(detection coordinates)
Java客户端:
try {
Socket socket = new Socket((host,port));
// when click a button, it sends an image
...
bufferedReader.readLine;
} catch (Exception e) {e.printStackTrace;}
// and some other codes
只要Python服务器处于活动状态,Java就会保持连接。只是想弄清楚如何修复python服务器代码,以便它在接收图像时保持连接并在客户端每次发送图像时发送回坐标。
到目前为止,我能做的最好的事情就是每次Python服务器发回坐标时都重新连接。但是我想避免每次发送图像进行对象检测时都重新连接。
最佳答案
如果您想为另一个请求重用套接字,则此代码将不起作用(也就是说,客户端不会在此请求之后关闭套接字),并且您不知道发送了多少消息。确实没有什么好方法可以知道数据的结尾在哪里。
最简单的解决方案是在发送图像之前先发送长度。然后,您可以从套接字读取正确数量的数据。因此您的代码可能如下所示:
clientsocket, addr = s.accept()
while True:
data = clientsocket.recv(4)
# ... turn 4 bytes in 'data' into integer 'count'
f = open('image.jpg', 'wb')
while count > 0:
data = clientsocket.recv(min(count, 1024))
count -= len(data)
f.write(data)
detectObject("image.jpg")
clientsocket.send(detection coordinates)
如果我正确理解您的问题,这将解决您的两个问题