我正在编写一个简单的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客户端)接收答案时,程序会自行阻止(我认为{{ 1}}正在等待消息)。我知道我必须设置超时,但它并没有解决我的问题。我想先发送消息然后收到一些消息。为什么recv()
阻止recv()
?
Android监听器功能:
sendall()
答案 0 :(得分:2)
在Python服务器上,您发送:
data="#1111#Welcome on Server!"
sock.sendall(data.encode('ascii'))
在Java客户端上,您可以这样阅读:
inp = in.readLine();
readLine
继续阅读,直到找到换行符。但是你永远不会发送换行符。所以它一直在阅读。
您还有其他需要解决的问题。
例如,您的Python代码假定TCP套接字是they're actually byte streams时的消息流,因此您的username = sock.recv(1024)
可能同时获得用户名和密码,导致下一个recv
永久阻止,或者它可能会获得一半的用户名并导致虚假的登录失败,或者您可以想象的任何其他内容。 (当然,Android代码甚至不发送其中任何一个这一事实是一个更大的问题,但我认为你知道这一点,并且还没有编写那些代码。)
这个问题实际上指的是解决此问题的一种方法:如果不允许任何消息包含换行符,则可以使用换行符作为消息的终止符。你已经在Java方面这样做了;您只需要记住在发送时添加\n
。在Python方面,套接字上的makefile
方法为您提供了一个类似文件的对象,与您在Java中使用的方法非常相似,它具有readline
方法,因此您可以执行相同的操作在另一个方向。