【发布时间】:2015-05-06 15:00:12
【问题描述】:
我正在编写一个简单的 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";
}
}`
【问题讨论】:
-
首先,虽然我不认为这是您要问的问题(尽管可能是),但它是您需要解决的问题:@987654321 @。一个
recv可能得到半个send,或者三个sends 合并到一个缓冲区中。 -
更仔细地查看您的代码,这绝对是可能的问题。客户端向您发送用户名和密码。你的第一个
recv得到了两者。你的第二个recv永远等待更多数据,但客户端不再发送,因为你已经得到了一切。 -
要诊断此问题,请尝试
printusername;如果是用户名和密码挤在一起,那就是整个问题。 (同样,即使这不是问题的全部,它仍然是你必须解决的问题。) -
附带说明,这显然是 Python 3。这意味着
recv给你的是bytes,而不是str;你必须decode它做任何有用的事情。即使只是print也会给你b'Franky'而不是你想要的Franky。 -
我知道 tcp 套接字是字节流。在我的客户上,我没有收到任何东西。要停止程序,我必须按两次 ctrl+c 而不是一次。在我停止程序后,我会在 android 客户端上收到欢迎消息。