1

クライアントとサーバーの 2 つの Android アプリケーションを作成し、TCP を使用してデバイス間で通信します。サーバーには、TCP 通信をリッスンする次のコードがあります。

private class StartServer implements Runnable {     
    public void run() {
            getState(); // This just refreshes the server state
            try {
                serverSocket = new ServerSocket(5000);
                appendLog("Server successfully listening ["+getLocalIpAddress() + ":5000]"); //appendLog function just uses runOnUiThread() to update the log textview
            } catch (IOException e) {
                appendLog("Could not listen on port: 5000");
                //System.exit(-1);
            }
            BufferedReader in = null;
            BufferedWriter out = null;
            String input = null;


            try {
                clientSocket = serverSocket.accept(); 
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

                while (serverState) { //variable set by our getState() function

                    input = in.readLine();
                    appendLog("Received: " + input);
                    this.gotMessage(out, input);
                }
                in.close();
                out.close();
            } catch (IOException e) {
                //appendLog(e.toString());
                appendLog("Accept failed: 5000");
                //System.exit(-1);
            }
    }

この関数を呼び出して、受信したメッセージを実際に解析します。

private void gotMessage(BufferedWriter output, String msg) {
        if (msg != null) {
            String sString = msg;
            int to_do = 0;


            if (msg.matches("^(?i)(exit|quit|close)$")) {
                appendLog("Exiting");
                sString = "Goodbye";
                to_do=1;
            } else if (msg.matches("^(?i)(launch|run|open)\\s(.+)")) {
                appendLog("Launching application");
                sString = "Launching application";
            } else if (msg.matches("^(?i)(turn off|server off|deactivate)$")) {
                appendLog("Turning off server due to remote command.");
                sString = "Turning off...";
                to_do=2;
            } else if (msg.matches("^(?i)(restart|reboot)$")) {
                appendLog("Resetting server");
                sString = "Rebooting now...";
                to_do=3;
            }


            try {
                output.write("S: " + sString);
                output.newLine();
                output.flush();
            } catch (IOException e) {
                appendLog("Cannot parse message");
            }


            switch(to_do) {
                case 0:
                    break;
                case 1:
                    System.exit(0);
                    break;
                case 2:
                    serverOff();
                    break;
                case 3:
                    serverOff();
                    serverOn();
                    break;
                default:
                    break;
            }
        }
    }
}

サーバーのスレッド自体は、 を使用して開始されますThread t = new Thread(new StartServer()); t.start()。そして、私の知る限り、これはうまく機能します。端末と telnet を IP とポートに開いて、エラーなしで通信をやり取りできます。しかし、以下のクライアントコードから同じことをしようとすると. 私は最初のメッセージを受け取るだけで、それ以外に渡したものはすべて空虚に消えてしまいます。

public void sendToServer(View v) {
    try {
        String ip = ((TextView)findViewById(R.id.ip_box)).getText().toString(); //User entered IP address
        String to_send = ((EditText)findViewById(R.id.send_to_server)).getText().toString(); //User entered text to send
        this.s = new Socket(ip, 5000);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        appendLog("Sending: " + to_send);
        out.write(to_send);
                    out.newLine();
        out.close();
    } catch (Exception e) {
        Log.d("error", e.toString());
    }
}
4

1 に答える 1

1

文字列に改行文字がありますto_sendか? いいえの場合は、クライアント コードに追加out.newLine()します。

appendLog("Sending: " + to_send);
out.write(to_send);
out.newLine();

複数のクライアントをサポートするには、サーバー コードは次のようになります。

// main server loop
while (serverIsActive) {
    clientSocket = serverSocket.accept(); 
    // spawn new thread for each client
    ClientThread ct = new ClientThread(clientSocket);
    ct.start();
}

ClientThread はクライアント ソケットで動作し、行を読み取るための独自のループを持つ必要があります。クライアントがソケットを閉じるとすぐに停止する必要があります。

class ClientThread {
    ...
    public void run() {
        ....
        while ((inputLine = in.readLine()) != null) {
            // process client message
        }
        in.close();
    }
}
于 2013-05-17T15:21:48.627 に答える