Android 客户端不会从 python 服务器接收

Android client won't receive from python server

嘿,我刚开始学习 android,我的任务是制作一个从 python 服务器发送和接收数据的应用程序。它可以完美地发送数据,但我无法让客户端接收数据。请放轻松,我是新手,这是我的代码:

Android代码:

class MyTask extends AsyncTask<Void, Void, Void> {
        @SuppressLint(("Wrong Thread"))
        @Override
        protected Void doInBackground(Void... voids) {

            try {
                Log.d("ORI", "1- before connect");
                sock = new Socket(LOCAL_HOST, PORT);
                Log.d("ORI", "2 - after connect" );
                prWriter = new PrintWriter(sock.getOutputStream());
                prWriter.write(msg);
                prWriter.flush();
                BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = in.readLine()) != null) {
                    response.append(line);
                }
                Toast.makeText(getApplicationContext(), response, Toast.LENGTH_LONG);
                sock.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

这是我的 Python 服务器:

import socket

server_sock = socket.socket()
server_sock.bind(("0.0.0.0", 5024))
server_sock.listen(1)

client, addr = server_sock.accept()
print(addr[0])
flag = False
while True:
    try:
        data = client.recv(1024).decode()
    except Exception as e:
        print(str(e))
        break

    else:
        if not flag:
            if data == '':
                pass
            print(data)
            try:
                client.send("K".encode())
            except Exception as e:
                print(e)
            else:
                print("OK")
                flag = True



server_sock.close()

Caused by: libcore.io.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)

您的客户端尝试使用 .readLine().

读取一行

但是..您的服务器发送线路了吗?您的服务器发送:

 client.send("K".encode())

(那只是一个字,为什么不是大句呢?)

但不管怎么说,当字符串以\n结尾时,它只是一行。

所以改为:

 client.send("Hello World\n".encode())

这是 Python 中更灵活、更可靠的套接字服务器的想法。

如果您不能确定要读取多少数据,那么从套接字读取数据可能会很困难。例如,如果假设任何消息都不会超过 1K,那么您可能会想 recv(1024) 但这并不可靠。具体来说,客户端可以发送 800 个字节,但服务器可能会在一次调用 recv() 时“看到”更少的字节。

因此,您需要的是一种协议,使服务器能够准确了解预期的数据量。

实现此目的的一种方法是在消息中使用固定长度的前导码。我们可以利用 pack/unpack 函数(来自 struct 模块)来构建网络独立整数,这些整数在实际消息之前发送。服务器知道期望前导码(固定长度)并通过解包该值可以对精确的字节数执行 recv()。

以下示例通过实现 echo 进程来利用此范例,服务器在该进程中运行在自己的线程中,客户端发送一条消息,服务器立即回复任何它第一时间收到。在此示例中,客户端以“kill switch”结束。

我可能会接受各种批评,但无论如何:

import socket
import threading
from struct import pack, unpack

HOST = 'localhost'
PORT = 7070
FORMAT = ('!Q', 8)
MSG = '''The Owl and the Pussy-cat went to sea 
   In a beautiful pea-green boat, 
They took some honey, and plenty of money, 
   Wrapped up in a five-pound note. 
The Owl looked up to the stars above, 
   And sang to a small guitar, 
"O lovely Pussy! O Pussy, my love, 
    What a beautiful Pussy you are, 
         You are, 
         You are! 
What a beautiful Pussy you are!"'''


def sendbuffer(s, b):
    buffer = pack(FORMAT[0], len(b)) + b
    offset = 0
    while offset < len(buffer):
        offset += s.send(buffer[offset:])


def recvbuffer(s):
    p = s.recv(FORMAT[1], socket.MSG_WAITALL)
    n = unpack(FORMAT[0], p)[0]
    return None if n == 0 else s.recv(n, socket.MSG_WAITALL)


def server():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((HOST, PORT))
        s.listen()
        conn, _ = s.accept()
        with conn:
            while (data := recvbuffer(conn)):
                sendbuffer(conn, data)


def client(msg):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((HOST, PORT))
        sendbuffer(s, msg.encode())
        data = recvbuffer(s)
        print(data.decode())
        sendbuffer(s, b'') # kill switch


def main():
    threading.Thread(target=server).start()
    client(MSG)


if __name__ == '__main__':
    main()

N.B。这已经在 macOS 上测试过,在 Windows

上可能无法正常工作