web-dev-qa-db-ja.com

本当にシンプルTCP client

アプリでサーバーのURLを入力したいhttp://192.168.1.8/およびポート(例: 1234。サーバーがTCP Requestメッセージを受信すると、ファイルを送り返します(サーバーは既に実装されています)。

接続を維持したくないので、AsyncTaskのような複雑なものは必要ないと思います。サーバーから回答を受け取ったら、接続を閉じる必要があります。

今後の道のりやチップの兆候は大歓迎です。

16
G.V.

以下は、シンプルなTCP Socketsを使用するクライアントです。このクライアントは、 このチュートリアル (チュートリアルは、このGitHubリポジトリにもあります)。

このコードは、通常はJSON形式で、クライアントとサーバー間で文字列を送受信することに注意してください。

TCP=クライアントコード:

_import Android.util.Log;
import Java.io.BufferedReader;
import Java.io.BufferedWriter;
import Java.io.InputStreamReader;
import Java.io.OutputStreamWriter;
import Java.io.PrintWriter;
import Java.net.InetAddress;
import Java.net.Socket;

public class TcpClient {

    public static final String TAG = TcpClient.class.getSimpleName();
    public static final String SERVER_IP = "192.168.1.8"; //server IP address
    public static final int SERVER_PORT = 1234;
    // message to send to the server
    private String mServerMessage;
    // sends message received notifications
    private OnMessageReceived mMessageListener = null;
    // while this is true, the server will continue running
    private boolean mRun = false;
    // used to send messages
    private PrintWriter mBufferOut;
    // used to read messages from the server
    private BufferedReader mBufferIn;

    /**
     * Constructor of the class. OnMessagedReceived listens for the messages received from server
     */
    public TcpClient(OnMessageReceived listener) {
        mMessageListener = listener;
    }

    /**
     * Sends the message entered by client to the server
     *
     * @param message text entered by client
     */
    public void sendMessage(final String message) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                if (mBufferOut != null) {
                    Log.d(TAG, "Sending: " + message);
                    mBufferOut.println(message);
                    mBufferOut.flush();
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

    /**
     * Close the connection and release the members
     */
    public void stopClient() {

        mRun = false;

        if (mBufferOut != null) {
            mBufferOut.flush();
            mBufferOut.close();
        }

        mMessageListener = null;
        mBufferIn = null;
        mBufferOut = null;
        mServerMessage = null;
    }

    public void run() {

        mRun = true;

        try {
            //here you must put your computer's IP address.
            InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

            Log.d("TCP Client", "C: Connecting...");

            //create a socket to make the connection with the server
            Socket socket = new Socket(serverAddr, SERVER_PORT);

            try {

                //sends the message to the server
                mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

                //receives the message which the server sends back
                mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));


                //in this while the client listens for the messages sent by the server
                while (mRun) {

                    mServerMessage = mBufferIn.readLine();

                    if (mServerMessage != null && mMessageListener != null) {
                        //call the method messageReceived from MyActivity class
                        mMessageListener.messageReceived(mServerMessage);
                    }

                }

                Log.d("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");

            } catch (Exception e) {
                Log.e("TCP", "S: Error", e);
            } finally {
                //the socket must be closed. It is not possible to reconnect to this socket
                // after it is closed, which means a new socket instance has to be created.
                socket.close();
            }

        } catch (Exception e) {
            Log.e("TCP", "C: Error", e);
        }

    }

    //Declare the interface. The method messageReceived(String message) will must be implemented in the Activity
    //class at on AsyncTask doInBackground
    public interface OnMessageReceived {
        public void messageReceived(String message);
    }

}
_

次に、アクティビティでTcpClientをメンバー変数として宣言します。

_public class MainActivity extends Activity {

    TcpClient mTcpClient;

    //............
_

次に、AsyncTaskを使用してサーバーに接続し、UIスレッドで応答を受信します(サーバーから受信したメッセージは、AsyncTaskのonProgressUpdate()メソッドオーバーライドで処理されます)。

_public class ConnectTask extends AsyncTask<String, String, TcpClient> {

    @Override
    protected TcpClient doInBackground(String... message) {

        //we create a TCPClient object
        mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
            @Override
            //here the messageReceived method is implemented
            public void messageReceived(String message) {
                //this method calls the onProgressUpdate
                publishProgress(message);
            }
        });
        mTcpClient.run();

        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        //response received from server
        Log.d("test", "response " + values[0]);
        //process server response here....

}
_

サーバーへの接続を開始するには、AsyncTaskを実行します。

_new ConnectTask().execute("");
_

次に、サーバーにメッセージを送信します。

_//sends the message to the server
if (mTcpClient != null) {
    mTcpClient.sendMessage("testing");
}
_

サーバーへの接続はいつでも閉じることができます。

_if (mTcpClient != null) {
    mTcpClient.stopClient();
}
_
36
Daniel Nugent

コードをありがとう。私の場合、回線ベースのプロトコルを使用していないため、データの受信に問題がありました。特定のサーバー設定で機能する代替実装を作成しました。

  1. TcpClient.Javaファイルでは、「ru​​n()」コマンドを次のコードフラグメントに置き換える必要があります

    public void run(){

    _mRun = true;
    
    try {
        InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
        Log.e("TCP Client", "C: Connecting...");
        Socket socket = new Socket(serverAddr, SERVER_PORT);
        try {
            mBufferOut = new PrintWriter(socket.getOutputStream());
            Log.e("TCP Client", "C: Sent.");
            mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            int charsRead = 0; char[] buffer = new char[1024]; //choose your buffer size if you need other than 1024
    
            while (mRun) {
                charsRead = mBufferIn.read(buffer);
                mServerMessage = new String(buffer).substring(0, charsRead);
                if (mServerMessage != null && mMessageListener != null) {
                    mMessageListener.messageReceived(mServerMessage);}
                mServerMessage = null;
            }
            Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'"); 
    _

//残りのコードはOK、オリジナルを参照

  1. mainActivity.JavaのdoInBackgroudは、受信したメッセージをonProgressUpdateに投稿します。他のオブジェクトで表示できます。 TextView

    _@Override
    protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
            Log.d("test", "response " + values[0]);
            response.setText(response.getText() + "/n" +values[0]);
    } 
    _

//「response」は関数で宣言されたTextViewオブジェクトです

_public class MainActivity extends AppCompatActivity {
TextView response; //...so on
_

と機能

protected void onCreate(Bundle savedInstanceState) { response = (TextView) findViewById(R.id.textView); //..so on

7
RAIMA

まず、アプリにインターネット許可をAndroid manifest

<uses-permission Android:name="Android.permission.INTERNET"/>

AsyncTaskを使用してリクエストを送信し、ファイルを簡単に返送できます

    public void send_request() {
    send_request sr = new send_request();
    sr.execute();
}

class send_request extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... voids) {
        try {             /*note : ip address must be in Quotation mark*/
                          /*note : port doesn't need to be inside the Quotation mark*/
            Socket s = new Socket(/*ip address :*/"192.168.1.8",/*port :*/ 1234);
            PrintWriter printWriter = new PrintWriter(s.getOutputStream());
            printWriter.write("your message");
            printWriter.flush();
            printWriter.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void onPostExecute(final String Data) {
        /*Data is what you receive from your server*/
        Log.e("my_Data","Data is : " + Data);
    }
}
1
YO_USA

TcpClientで次のコードを試してください。

 public void run() {
        mRun = true;
        try {
            InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
            Log.e("TCP Client", "C: Connecting...");
            Socket socket = new Socket(serverAddr, SERVER_PORT);
            try {
                mBufferOut = new PrintWriter(socket.getOutputStream());
                Log.e("TCP Client", "C: Sent.");
                mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                int charsRead = 0; char[] buffer = new char[2024]; //choose your buffer size if you need other than 1024
                while (mRun) {
                    charsRead = mBufferIn.read(buffer);
                    mServerMessage = new String(buffer).substring(0, charsRead);
                    if (mServerMessage != null && mMessageListener != null) {
                        Log.e("in if---------->>", " Received : '" + mServerMessage + "'");
                    }
                    mServerMessage = null;
                }
                Log.e("-------------- >>", " Received : '" + mServerMessage + "'");
            } catch (Exception e) {
                Log.e("TCP", "S: Error", e);
            } finally {
                //the socket must be closed. It is not possible to reconnect to this socket
                // after it is closed, which means a new socket instance has to be created.
                socket.close();
                Log.e("-------------- >>", "Close socket " );
            }

        } catch (Exception e) {
            Log.e("TCP", "C: Error", e);
        }

    }

正常に動作します。上記の他のコードのこの行は、問題を引き起こします。

mMessageListener.messageReceived(mServerMessage);

この行を削除すると、アプリが正常に機能します。ログインを監視できますAndroid studioも。

Golangのサーバーでこのコードを使用できます。これが私のサーバーです。

package main

import (
    "bufio"
    "flag"
    "fmt"
    "net"
    "strconv"
)
var addr = flag.String("addr", "", "The address to listen to; default is \"\" (all interfaces).")
var port = flag.Int("port", 37533, "The port to listen on; default is 37533.")
func main() {
    flag.Parse()
    fmt.Println("Starting server...")
    src := *addr + ":" + strconv.Itoa(*port)
    listener, _ := net.Listen("tcp", src)
    fmt.Printf("Listening on %s.\n", src)

    defer listener.Close()

    for {
        conn, err := listener.Accept()
        if err != nil {
            fmt.Printf("Some connection error: %s\n", err)
        }
        go handleConnection(conn)
    }
}

func handleConnection(conn net.Conn) {
    remoteAddr := conn.RemoteAddr().String()
  LocalAddr :=conn.LocalAddr().String()

  fmt.Println("Client LocalAddr  " + LocalAddr)
    fmt.Println("Client connected from " + remoteAddr)
    scanner := bufio.NewScanner(conn)
    for {
        ok := scanner.Scan()

        if !ok {
            break
        }

        handleMessage(scanner.Text(), conn)
    }
    fmt.Println("Client at " + remoteAddr + " disconnected.")
}

func handleMessage(message string, conn net.Conn) {
    fmt.Println("> " + message)
    if len(message) > 0 {
    conn.Write([]byte("This is from Golang.\n"))
    fmt.Println("----------> we send it....")
    }
}
0
Moh_beh