Android上两个应用程序之间的套接字通信

时间:2012-06-10 12:24:18

标签: java android sockets chat

我的Android应用程序存在很大问题,我想请求您的帮助。

我目前正在使用套接字编写Android Clietn-Server应用程序。我在互联网上找到了很多辅导员,从中我已经为我的项目创建了基础知识。但是,所有教程仅适用于一个消息发送,这就是全部。我需要发送更多它们,所以我一直在尝试修改它。

这是负责服务器和客户端的代码片段。其余的在这个时候并不重要。

服务器

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        serverStatus = (TextView) findViewById(R.id.server_status);
        recivedMsg = (TextView)findViewById(R.id.rec_msg);

        SERVERIP = getLocalIpAddress();

        Thread fst = new Thread(new ServerThread());
        fst.start();
    }

    public class ServerThread implements Runnable {

        public void run() {
            try {
                if (SERVERIP != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            serverStatus.setText("Listening on IP: " + SERVERIP);
                        }
                    });
                    serverSocket = new ServerSocket(SERVERPORT);
                    while (true) {
                        // listen for incoming clients
                        Socket client = serverSocket.accept();
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                serverStatus.setText("Connected." + System.getProperty("line.separator"));
                            }
                        });

                        try {
                            line = null;
                            while (connected) {
                                BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                                if((line = in.readLine())!=null)
                                {
                                    Log.d("ServerActivity", line);
                                    handler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            if(recivedMsg.equals("CLOSE"))
                                            {
                                                recivedMsg.append("CLOSE socket");
                                                connected = false;
                                            }
                                            else
                                            {
                                                recivedMsg.append("MSG: " + line + System.getProperty("line.separator"));
                                            }
                                            // do whatever you want to the front end
                                            // this is where you can be creative
                                        }
                                    });
                                }
                                else
                                {
                                    recivedMsg.append("empty" + System.getProperty("line.separator"));
                                }
                            }
                            break;
                        } catch (Exception e) {
                            handler.post(new Runnable() {
                                @Override
                                public void run() {
                                    serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
                                }
                            });
                            e.printStackTrace();
                        }
                    }
                } else {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            serverStatus.setText("Couldn't detect internet connection.");
                        }
                    });
                }
            } catch (Exception e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        serverStatus.setText("Error");
                    }
                });
                e.printStackTrace();
            }
        }
    }

客户端

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        serverIp = (EditText) findViewById(R.id.server_ip);
        connectPhones = (Button) findViewById(R.id.connect_phones);

        sendField = (EditText) findViewById(R.id.send_field);
        sendMsg = (Button) findViewById(R.id.msg_send);

        connectPhones.setOnClickListener(connectListener);
        sendMsg.setOnClickListener(sendMessage);
    }

    @Override
    protected void onStop() {
         super.onStop();
         try {
                 BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                 //send output msg
                 String outMsg = "CLOSE"; 
                 out.write(outMsg);
                 out.flush();
                 // make sure you close the socket upon exiting
                 s.close();
         } catch (IOException e) {
                 e.printStackTrace();
         }
    }

    private OnClickListener connectListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            serverIpAddress = serverIp.getText().toString();
            runTcpConnection();
            sendMessageToServer("Msg");
        }
    };

    private OnClickListener sendMessage = new OnClickListener() {

        @Override
        public void onClick(View v) {
            sendMessageToServer(sendField.getText().toString());
        }
    };

    private void runTcpConnection() {
        try {
            s = new Socket(serverIpAddress, SERVERPORT);
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            //send output msg
            String outMsg = "TCP connecting to " + SERVERPORT + System.getProperty("line.separator"); 
            out.write(outMsg);
            out.flush();
            Log.i("TcpClient", "sent: " + outMsg);
            SystemClock.sleep(10);
            s.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    };

    public void sendMessageToServer(String str) {
        try {
                    s = new Socket(serverIpAddress, SERVERPORT);
                    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                    //send output msg
                    String outMsg = str + System.getProperty("line.separator"); 
                    out.write(outMsg);
                    out.flush();
                    Log.i("TcpClient", "sent: " + outMsg);
                    s.close();
                } catch (UnknownHostException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    Log.d("", "hello222");
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    Log.d("", "hello4333");
                }

            }

现在设备连接正确。此外,他们正在发送第一条连接消息(OnClickListener connectListener中的消息)。 问题是,当我尝试使用sendMessageToServer发送另一条消息时,这是不可能的。这些消息仅在客户活动被销毁后显示。

非常有趣的是,没有SystemClock.sleep(10);监听器runTcpConnection()表现得很奇怪。只有'连接'。显示在服务器上。

有人可以告诉我我必须做些什么才能正常发送消息吗?

修改 这是我发现的事情:

  • 如果我在连接发送的消息多于所有消息(空)并且在第二个连接错误显示后 - 请重新连接电话
  • 如果我在sendMessageToServer中没有s.close行发送更多消息的连接,则只有一条消息正在通过。之后没有显示错误。
  • 消息表单runTcpConnection始终显示(除非此函数中没有SystemClock.sleep(10))

希望它能帮助某人诊断我的错误。

1 个答案:

答案 0 :(得分:2)

正如我所看到的,每当用户点击按钮发送时你都会创建一个新套接字,对吗?
我建议您在用户单击连接时只启动一次,然后在发送点击事件中使用它(因为这是TCP,如果您创建新的套接字实例,您将断开与服务器的连接)
因此,您应该删除 sendMessageToServer 中的 这些行

s = new Socket(serverIpAddress, SERVERPORT);
s.close();

runTcpConnection 中的这一行

s.close();

每当您不希望与服务器通信时,套接字应该关闭(以停止为例,或更改活动时......)
此外,您也应该只创建一个BufferedWriter实例 希望这有帮助。