我正在编写一个简单的TCP服务器程序。一切正常,但功能recv()
不正常。
import socket
import threading
def connectionHandler(sock):
data="#1111#Welcome on Server!"
sock.sendall(data.encode('ascii'))
username = sock.recv(1024)
password = sock.recv(1024)
print('{}, {}'.format(username, password))
conn.close()
HOST = socket.gethostname()
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(10)
while True:
conn, addr = s.accept()
print('Connected by', addr)
t = threading.Thread(target=connectionHandler, args=(conn,))
t.start()
conn.close()
当我注释对的所有调用时recv()
,程序正常运行,但是当我想从客户端(智能手机上的Android客户端)接收答案时,程序将自行阻止(我认为这recv()
是在等待消息)。我知道我必须设置超时,但这不能解决我的问题。我想先发送消息,然后再接收消息。为什么会recv()
阻塞sendall()
?
Android侦听器功能:
public String listener(Socket x) throws IOException{
try {
Log.d("Listener","Started");
String inp;
BufferedReader in = new BufferedReader(new InputStreamReader(x.getInputStream()));
inp = in.readLine();
Log.d("Listener","Ended");
return inp;
} catch (UnknownHostException e1) {
e1.printStackTrace();
return "ERROR";
} catch (IOException e1) {
e1.printStackTrace();
return "ERROR";
}
}`
在Python服务器上,发送以下命令:
data="#1111#Welcome on Server!"
sock.sendall(data.encode('ascii'))
在Java客户端上,您将读取如下内容:
inp = in.readLine();
这readLine
一直读取,直到找到一个换行符。但是您永远不会发送换行符。因此,它永远读下去。
您还有其他问题需要在这里解决。
例如,您的Python代码假设TCP套接字实际上是字节流时,它们是消息流,因此您username = sock.recv(1024)
可能会同时获得用户名和密码,从而导致下一个recv
永远被阻塞,或者可能会获得一半的用户名并导致虚假登录失败,或者您可以想象的其他任何事情。(当然,Android代码甚至都不会发送它们中的一个是一个更大的问题,但是我想您已经知道并且还没有编写该代码。)
这个问题实际上指向解决此问题的一种方法:如果您的邮件都不允许包含换行符,则可以仅使用换行符作为邮件的终止符。您已经在Java方面进行了此操作;您只需要记住\n
在发送时添加一个。在Python方面,makefile
套接字上的方法为您提供了一个类似于文件的对象,与您在Java中所做的非常相似,该对象具有一个readline
方法,因此您可以在另一个方向上做同样的事情。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句