嘿,我刚开始学习android,我的任务是制作一个从python服务器发送和接收数据的应用程序。它完美地发送数据,但我无法让客户端接收数据。请对我宽容一点我是新来的这是我的代码:
安卓代码:
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()
这里有一个在Python中创建更灵活、更可靠的套接字服务器的想法。
如果你不能确定要读取多少数据,那么从套接字中读取可能会很有挑战性。例如,如果假设任何消息都不会超过1K,那么您可能会尝试recv(1024(,但这是不可靠的。具体地说,客户端可以发送800字节,但服务器可以"发送"800字节;参见";一次调用recv((可以减少字节数。
所以,您需要的是一个协议,使服务器能够准确地知道需要多少数据。
一种方法是对消息使用固定长度的前导码。我们可以利用打包/解包函数(来自结构模块(来构建独立于网络的整数,这些整数在实际消息之前发送。服务器知道需要该前导码(长度固定(,通过拆包该值可以对精确的字节数执行recv((。
下面的示例通过实现echo进程来利用这个范例,服务器在自己的线程中运行,客户端发送消息,服务器立即用它最初收到的任何消息进行回复。在这个例子中,客户端以"0"结束;终止开关";。
我可能会接受各种各样的批评,但无论如何,
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()
注意:这已经在macOS上进行了测试,在Windows 上可能无法正常工作
由以下原因引起:libcore.io.ErrnoException:连接失败:ETIMEDOUT(连接超时(
您的客户端尝试使用.readLine()
读取一行。
但是。。你的服务器正在发送线路吗?您的服务器发送:
client.send("K".encode())
(那只是一个字符。为什么不是一个大句子呢?(
但无论如何,当字符串以n
结尾时,它只是一行。
因此更改为:
client.send("Hello Worldn".encode())