web-dev-qa-db-fra.com

Vraiment simple TCP client

Je veux avec mon application entrer dans l'URL de mon serveur, par exemple. http://192.168.1.8/ et le port, par exemple 1234. Lorsque mon serveur reçoit le message de requête TCP Request, il renvoie un fichier (le serveur est déjà implémenté).

Je pense que je n'ai pas besoin de quelque chose de compliqué comme une AsyncTask, car je ne veux pas garder la connexion. En recevant la réponse du serveur, ma connexion doit être fermée.

Toute indication d'avenir ou de pourboire est vivement appréciée.

16
G.V.

Voici un simple TCP qui utilise des sockets que je travaille en fonction du code dans ce tutoriel (le code du tutoriel est également disponible dans ce référentiel GitHub ).

Notez que ce code est conçu pour envoyer des chaînes entre le client et le serveur, généralement au format JSON.

Voici le code client 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);
    }

}

Ensuite, déclarez un TcpClient en tant que variable membre dans votre activité:

public class MainActivity extends Activity {

    TcpClient mTcpClient;

    //............

Ensuite, utilisez une AsyncTask pour vous connecter à votre serveur et recevoir des réponses sur le thread d'interface utilisateur (notez que les messages reçus du serveur sont gérés dans la substitution de méthode onProgressUpdate() dans AsyncTask):

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....

}

Pour établir la connexion avec votre serveur, exécutez la AsyncTask:

new ConnectTask().execute("");

Ensuite, en envoyant un message au serveur:

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

Vous pouvez fermer la connexion au serveur à tout moment:

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

Merci pour le code. Dans mon cas, j'avais de la difficulté à recevoir des données, car je n'utilisais pas de protocole basé sur les lignes. J'ai écrit une autre implémentation qui fonctionne avec la configuration de mon serveur spécifique:

  1. Dans le fichier TcpClient.Java, la commande "run ()" doit être remplacée par le fragment de code ci-dessous

    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 + "'"); 
    

// le reste du code est correct, voir l'original

  1. doInBackgroud dans votre MainActivity.Java poste un message reçu sur onProgressUpdate, vous pouvez l'afficher dans un autre objet, par exemple. Affichage

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

// "réponse" est un objet TextView déclaré dans votre fonction

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

et fonction

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

7
RAIMA

tout d’abord, donnez la permission Internet à votre application dans Android manifest

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

vous pouvez utiliser AsyncTask pour envoyer votre demande et recevoir votre fichier si facilement

    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

Essayez ce code dans 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);
        }

    }

Ça fonctionne correctement. Cette ligne dans un autre code ci-dessus peut être erronée.

mMessageListener.messageReceived (mServerMessage);

supprimez cette ligne et votre application fonctionne bien. vous pouvez surveiller votre connexion Android studio aussi.

Vous pouvez utiliser ce code pour votre serveur Golang. C'est mon serveur:

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