通过:Android 接收 Python Socket 消息
我正在开发一个安卓应用,它通过一个套接字连接到一个用Python写的服务器。安卓应用会发送一张图片到服务器,然后期待服务器返回一条文本消息,接着它会更新一个TextView
来显示收到的消息。
发生的情况是:服务器成功接收了图片并发送回了一条消息。但不知为何,这条消息在安卓应用上没有显示出来。
我搞不清楚,是因为应用没有收到这条消息?还是收到了,但在显示消息时出现了错误?
这是服务器的代码(server.py
):
from socket import *
HOST = "x.x.x.x" #replaced with the server's IP
PORT = 6000
s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print "Connected by: " , addr
while True:
data = conn.recv(40960)
with open('image.jpg', 'wb') as file:
file.write(data)
reply = raw_input("Reply: ")
conn.sendall(reply)
conn.close()
这是安卓应用代码的一部分:
static TextView msgReceived;
public void onClickSend(View view) {
Thread t = new Thread(new Runnable(){
String imgPath = "/mnt/sdcard/Pictures/0001.jpg";
@Override
public void run() {
try {
Socket s = new Socket("x.x.x.x", 6000); //create socket
//---- SEND IMAGE TO SERVER ---//
FileInputStream fis = new FileInputStream(imgPath); //read image as bytes
byte [] buffer1 = new byte [fis.available()]; //create buffer that will hold the bytes
fis.read(buffer1); //read file contents to the buffer
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); //create the object to be sent
oos.writeObject(buffer1); //send the contents of the buffer to the socket
oos.close();
//---- RECEIVE TEXT FROM SERVER ---//
tempIn = new ObjectInputStream(s.getInputStream());
Message clientmessage = Message.obtain();
ObjectInputStream ois = new ObjectInputStream(tempIn);
String strMessage = (String)ois.readObject();
System.out.println(strMessage);
clientmessage.obj = strMessage;
mHandler.sendMessage(clientmessage);
ois.close();
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //catch (ClassNotFoundException e) {
//e.printStackTrace();
//}
}
});
t.start();
}
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg){
Display(msg.toString());
}
};
public void Display(String serverMsg){
msgReceived = (EditText) findViewById(R.id.msgReceived);
msgReceived.setText(serverMsg);
//Toast.makeText(getBaseContext(), serverMsg, Toast.LENGTH_SHORT).show();
}
我觉得问题出在安卓的Java代码上,因为server.py
在用一个测试的client.py
时运行得很好(也就是说,它成功接收了图片,发送了回复,客户端也完美接收到了)。
还有一点,在我排查问题时,我尝试用一个普通字符串(不是从服务器收到的那条)来更新TextView
,结果也没有成功!所以这可能表明问题出在更新的部分。
我非常感谢任何帮助,提前谢谢大家。我对安卓开发和Java非常陌生。
1 个回答
你的问题有两个方面:
你在把图片写入套接字后,立刻调用了
oos.close()
。我发现这样会抛出一个SocketException: Socket is closed
的错误。根据这个回答:Android: Socket is closed,关闭与套接字相关的流会同时关闭那个套接字,这样你就无法从中读取服务器的响应了。所以,把oos.close()
移到最后,在你完成读取后再关闭。我对你的代码做了这个修改后,仍然抛出了
StreamCorruptedException
的错误。根据这个回答:StreamCorruptedException: invalid type code: AC,这个错误是因为你使用了两个 ObjectInput/OutputStreams。我不太确定怎么只用一个,除非你采用我之前建议的修改。我重新调整了你的代码,变成了下面这样,这在我的系统上使用你的 Python 服务器代码是可以工作的。// Write to socket ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); //create the object to be sent oos.writeObject(buffer1); //send the contents of the buffer to the socket oos.flush(); // Read from socket BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream())); StringBuilder response = new StringBuilder(); String line; while ((line = input.readLine()) != null) response.append(line); Message clientmessage = Message.obtain(); clientmessage.obj = response.toString(); mHandler.sendMessage(clientmessage); oos.close(); input.close(); s.close();
顺便提一下,你在代码顶部定义了 UI 元素 msgReceived
为 TextView
,但在代码底部却把它转换成了 EditView
。我遇到了 ClassCastException
的错误,直到我把它们改成一致的,所以要小心。