4

我的 Android 应用程序遇到了很大的问题,我想向您寻求帮助。

我目前正在使用套接字编写 Android Clietn-Server 应用程序。我在 Internet 上找到了很多教程,并从中为我的项目创建了基础知识。但是,所有教程都仅用于发送一条消息,仅此而已。我需要发送更多,所以我一直在尝试修改它。

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

服务器:

@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()行为很奇怪。只有“已连接”。显示在服务器上。

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

编辑: 这是我发现的东西:

  • 如果我在连接中发送的消息比所有消息都为空(null)并且在第二个连接错误显示后 - 请重新连接手机
  • 如果我在连接中发送更多没有 s.close 行的消息,sendMessageToServer则只有一条消息通过。之后不显示错误。
  • 消息形式runTcpConnection总是显示(除非在此函数中没有 SystemClock.sleep(10))

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

4

1 回答 1

2

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

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

和runTcpConnection中的这一行

s.close();

每当您不想与服务器通信时,套接字应该关闭(onstop 是一个示例,或者当更改活动时......)
您也应该只创建一个 BufferedWriter 实例。
希望这有帮助。

于 2012-06-10T16:00:36.153 回答