Cody
Cody

Reputation: 3

Android java client program using separate thread for socket IO, Can't find a way to send data with a button

Alright first off, I'm fairly new to java and android coding. I am creating a client program that uses import java.net.Socket to make a connection to a server. It does so after pressing a "login" button. The login button code starts with Thread background = new Thread(new Runnable() { to start a new thread, then proceeds to make the connection. socket = new Socket(dstAddress, dstPort); All is well. My problem is that on my interface I also have another button and an EditText with the intent that the user can type commands into the EditText and then press the "Send" button in order to send them to the server. The code for the "Send" button is obviously outside of the code for the "Login" button and therefore outside of that background thread etc. How can I make this work?

OutputStream out = socket.getOutputStream();
PrintWriter output = new PrintWriter(out);

output.print(LoginPacket); //send packet to server
output.flush();

is the code I used inside of the "Login" button to send the first packet to the server, but I can't use this code in the "Send" button, gives the error "socket cannot be resolved"

Is there a way to make socket globally accessable while it's connected and receiving data from the server such that I can use another button to send data back to the server?

Upvotes: 0

Views: 9699

Answers (2)

Jitesh Dalsaniya
Jitesh Dalsaniya

Reputation: 1917

Here is the code its working for me.

Android Side:

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;

import android.util.Log;

public class TCPClient {

    private String serverMessage;
    public static final String SERVERIP = "Your IP Address"; //your computer IP address
    public static final int SERVERPORT = 4444;
    private OnMessageReceived mMessageListener = null;
    private boolean mRun = false;

    PrintWriter out;
    BufferedReader in;

    /**
     *  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(String message){
        if (out != null && !out.checkError()) {
            out.println(message);
            out.flush();
        }
    }

    public void stopClient(){
        mRun = false;
    }

    public void run() {

        mRun = true;

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

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

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

            try {

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

                Log.e("TCP Client", "C: Sent.");

                Log.e("TCP Client", "C: Done.");

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

                //in this while the client listens for the messages sent by the server
                while (mRun) {
                    serverMessage = in.readLine();

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

                }

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

            } 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);

        }

    }

    public interface OnMessageReceived {
        public void messageReceived(String message);
    }
}

On Server Side in Core Java

ServerBoard.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ServerBoard extends JFrame
{
    private JTextArea messageArea;
    private JButton sendButton;
    private JTextField message;
    private JButton startServer;
    private TCPServer mServer;

    public ServerBoard(){
        super("ServerBoard");

        JPanel panelFields = new JPanel();
        panelFields.setLayout(new BoxLayout(panelFields,BoxLayout.X_AXIS));

        JPanel panelFields2 = new JPanel();
        panelFields2.setLayout(new BoxLayout(panelFields2,BoxLayout.X_AXIS));

        messageArea = new JTextArea();
        messageArea.setColumns(30);
        messageArea.setRows(10);
        messageArea.setEditable(false);

        sendButton = new JButton("Send");

        sendButton.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
                String msg = message.getText();
                messageArea.append("\n" + msg);
                mServer.sendMessage(msg);
                message.setText("");
            }
        });

        startServer = new JButton("Start Server");
        startServer.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
                startServer.setEnabled(false);

                mServer = new TCPServer(new TCPServer.OnMessageReceived(){
                    public void messageReceived(String msg){
                        messageArea.append("\n" + msg);
                    }
                });

                mServer.start();
            }
        });

        message = new JTextField();
        message.setSize(200,20);

        panelFields.add(messageArea);
        panelFields.add(startServer);

        panelFields2.add(message);
        panelFields2.add(sendButton);

        getContentPane().add(panelFields);
        getContentPane().add(panelFields2);

        getContentPane().setLayout(new BoxLayout(getContentPane(),BoxLayout.Y_AXIS));

        setSize(300,170);
        setVisible(true);
    }
}

TCPServer.java

import javax.swing.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer extends Thread
{
    public static final int SERVER_PORT = 4444;
    private boolean running = false;
    private PrintWriter mOut;
    private OnMessageReceived mMessageListener = null;
    private boolean mRun = false;
    PrintWriter out;

    public TCPServer(OnMessageReceived listener){
        this.mMessageListener = listener;
    }


    public static void main(String[] args) 
    {
        ServerBoard frame = new ServerBoard();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public void sendMessage(String message){
        if(mOut != null && !mOut.checkError()){
            mOut.print(message);
            mOut.flush();
        }
    }

    @Override
    public void run(){
        super.run();
        running = true;

        try{
            System.out.println("S: Connecting...");
            ServerSocket serverSocket = new ServerSocket(SERVER_PORT);
            Socket client = serverSocket.accept();
            System.out.println("S: Receiving...");

            try{
                mOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())),true);
                BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

                while(running){
                    String msg = in.readLine();
                    if(msg != null && mMessageListener != null){
                        mMessageListener.messageReceived(msg);
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public interface OnMessageReceived
    {
        public void messageReceived(String message);
    }
}

Upvotes: 1

Gabe Sechan
Gabe Sechan

Reputation: 93668

You don't write the socket in the button's click handler. Instead, you make the click handler send a message to the socket thread (for example, by adding an item to a synchronized list that the thread is waiting for an object to be places in). The socket thread then would write the data to the socket.

Upvotes: 1

Related Questions