通过以下方式接收消息:Android to Python Socket

时间:2014-04-26 19:58:02

标签: java android python sockets adt

所以我正在开发一个Android应用程序,它通过套接字连接到服务器(用Python编写)。 Android将图像发送到服务器并期望返回文本消息,然后更新TextView以显示收到的消息。

发生的情况是:服务器成功接收图像并发回消息。由于某种原因,该消息未显示在Android应用程序上。

我无法弄明白,是不是因为应用没有收到消息?或者确实收到了,但是消息和错误是显示消息?

这是服务器的代码(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() 

这是Android应用程序代码的片段:

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();
    }

我认为问题在于Android java代码,因为server.py成功地使用了测试client.py(即它从中收到了一个图像,发回了回复而客户端完全收到了它) 。 还有一个补充,当我对问题进行故障排除时,我尝试使用普通字符串(不是从服务器收到的字符串)更新TextView并且它不起作用!这可能表明问题的根源是更新部分。 我将不胜感激任何帮助,并提前感谢您。我是Android开发和java的新手。

1 个答案:

答案 0 :(得分:0)

你的问题有两个方面:

  1. 将图像写入套接字后立即调用oos.close()。我发现这是一个SocketException: Socket is closed。根据这个答案:Android: Socket is closed,关闭与套接字关联的流将关闭该套接字,并且您无法从中读取服务器的响应。所以,在你完成阅读后,将oos.close()移到最后。

  2. 在我对您的代码进行了修改后,它仍然抛出StreamCorruptedException。根据{{​​3}}的答案,这是因为你使用了两个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();
    
  3. 顺便说一下,您将UI元素msgReceived定义为顶部的TextView,但将其转换为代码底部的EditView。我得到了ClassCastException,直到我改变它们以相互匹配,所以要小心。