TCP套接字函数recv()阻塞程序

TCP socket function recv() blocking program

我正在编写一个简单的 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 套接字在 they're actually byte streams 时是消息流,因此您的 username = sock.recv(1024) 可能会同时获得用户名和密码,从而导致下一个 recv 永远阻止,否则它可能会获得一半的用户名并导致虚假登录失败,或者您可以想象的任何其他事情。 (当然 Android 代码甚至不发送它们中的任何一个是一个更大的问题,但我假设您知道这一点并且还没有编写该代码。)

这个问题实际上指出了解决这个问题的一种方法:如果允许 none 的邮件包含换行符,您可以只使用换行符作为邮件的终止符。您已经在 Java 方面这样做了;你只需要记得在发送时添加一个\n。在 Python 方面,套接字上的 makefile 方法为您提供了一个类似文件的对象,与您在 Java 中所做的非常相似,它有一个 readline 方法, 所以你可以在另一个方向做同样的事情。