0

I am successfully sent message from client to server and my code sent message to last connected client, not to all connected clients. I need to implement send message to all connected clients. my code is bellow.

client


 public class Client extends Activity {

private Socket socket;
Button connectBtn;
EditText ip;
private static final int SERVERPORT = 8080;
private String SERVER_IP;
private Socket clientSocket;
String response = "";
private TextView text;
Handler updateConversationHandler;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ip = (EditText)findViewById(R.id.EditTextIP);
    text = (TextView)findViewById(R.id.msg);
    updateConversationHandler = new Handler();
    connectBtn = (Button)findViewById(R.id.ipButton);
    connectBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            SERVER_IP = ip.getText().toString();
            Toast.makeText(Client.this,"ip set",Toast.LENGTH_SHORT).show();
            new Thread(new ClientThread()).start();
        }
    });
}

public void onClick(View view) {
    try {
        EditText et = (EditText) findViewById(R.id.EditText01);
        String str = et.getText().toString();
        PrintWriter out = new PrintWriter(new BufferedWriter(
                new OutputStreamWriter(socket.getOutputStream())),
                true);
        out.println(str);
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

class ClientThread implements Runnable {

    @Override
    public void run() {
        try {
            InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
            socket = new Socket(serverAddr, SERVERPORT);
            CommunicationThread commThread = new CommunicationThread(socket);
            new Thread(commThread).start();
        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }


    }
}

class CommunicationThread implements Runnable {
    // private Socket clientSocket;
    private BufferedReader input;
    public CommunicationThread(Socket aClientSocket)
    {
        clientSocket = aClientSocket;
        try {
            this.input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public void run()
    {
        while (!Thread.currentThread().isInterrupted())
        {
            try
            {
                String read = input.readLine();
                Log.d("msg","readString"+read);
                updateConversationHandler.post(new updateUIThread(read));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class updateUIThread implements Runnable {
    private String msg;
    public updateUIThread(String str) {
        this.msg = str;
    }

    @Override
    public void run() {
        //if(msg!=null)
        text.setText("Server Says: "+ msg + "\n");
    }
}

}

Server


public class MainActivity extends Activity {

private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text,iptext;
public static final int SERVERPORT = 8080;
String message;
Button btn;
private Socket socket;
Socket  clientSocket;
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    text = (TextView) findViewById(R.id.text2);
    iptext = (TextView) findViewById(R.id.ip);
    //btn = (Button)findViewById(R.id.send);
    iptext.setText(getIpAddress());
    updateConversationHandler = new Handler();
    this.serverThread = new Thread(new ServerThread());
    this.serverThread.start();


}

public void onClick(View view) {
    try {
        if(clientSocket==null)
            Toast.makeText(MainActivity.this, "null socket", Toast.LENGTH_SHORT).show();
        else
        {
            Toast.makeText(MainActivity.this, "Msg send to socket", Toast.LENGTH_SHORT).show();
            PrintWriter out = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(clientSocket.getOutputStream())),
                    true);
            out.println("viky");
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
@Override
protected void onStop() {
    super.onStop();
    try {
        serverSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

class ServerThread implements Runnable {

    public void run() {
        Socket socket = null;
        try {
            serverSocket = new ServerSocket(SERVERPORT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (!Thread.currentThread().isInterrupted()) {
            try {
                Log.e("ServerThread","CommunicationThread started");
                socket = serverSocket.accept();
                CommunicationThread commThread = new CommunicationThread(socket);
                new Thread(commThread).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

public String getIpAddress() {
    String ip = "";
    try {
        Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
                .getNetworkInterfaces();
        while (enumNetworkInterfaces.hasMoreElements()) {
            NetworkInterface networkInterface = enumNetworkInterfaces
                    .nextElement();
            Enumeration<InetAddress> enumInetAddress = networkInterface
                    .getInetAddresses();
            while (enumInetAddress.hasMoreElements()) {
                InetAddress inetAddress = enumInetAddress
                        .nextElement();

                if (inetAddress.isSiteLocalAddress()) {
                    ip += "Server running at : "
                            + inetAddress.getHostAddress();
                }
            }
        }

    } catch (SocketException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        ip += "Something Wrong! " + e.toString() + "\n";
    }
    return ip;
}

class CommunicationThread implements Runnable {

    // private Socket clientSocket;
    private BufferedReader input;
    public CommunicationThread(Socket aClientSocket) {
        clientSocket = aClientSocket;
        try {
            this.input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        while (!Thread.currentThread().isInterrupted()) {

            try {
                String read = input.readLine();
                if(read!=null && !read.equals(""))
                updateConversationHandler.post(new updateUIThread(read));

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

class updateUIThread implements Runnable {
    private String msg;

    public updateUIThread(String str) {
        this.msg = str;
    }

    @Override
    public void run() {
        text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
    }
}
}

Do I have any mistakes in my code or something I missed?

halfer
  • 19,824
  • 17
  • 99
  • 186
Vivek P Pillai
  • 243
  • 4
  • 14
  • 1
    `successfully sent message from client to server and my code sent message to last connected client`. Impossible. Your network code in that on click handler of the server will cause a `NetworkOnMainThreadException`. – greenapps Jan 02 '17 at 14:34
  • @greenapps but its working without error. I need to send message to all connected client – Vivek P Pillai Jan 03 '17 at 05:31
  • @greenapps I don't have much knowledge in it.. please correct me. Also if client app stops server shows "Client says:null" – Vivek P Pillai Jan 03 '17 at 05:37
  • You have a communication thread for every client. That is ok. But you have only one global `Socket clientSocket`. So for every new client you overwrite the former value. So that is your problem. If you realise that you can easily deduce a solution. – greenapps Jan 03 '17 at 10:30
  • @greenapps i noticed it.. where should i make the change? i have implemented a socket arraylist and store each socket in it and in onClick method on server i use a for loop for send message to all added clients . still not working – Vivek P Pillai Jan 09 '17 at 08:14
  • That arraylist and loop is indeed the way to go. And only telling that it is not working is not the way to go if you want help. – greenapps Jan 09 '17 at 09:15
  • @greenapps not working means , it still send message to last added client. – Vivek P Pillai Jan 10 '17 at 07:41
  • So you do not want help i conclude. – greenapps Jan 10 '17 at 10:13

1 Answers1

1

Looking at your code, I think you are using TCP connection between server and client. Unfortunately in TCP, There is no facility of broadcasting (sending msg to all clients at once).

Alternatively you can use here UDP connection as mentioned in the docs. or you can send msg to all client one by one, but I think it's not much efficient so go for UDP.

One Server client example of UDP is: here..

The code which I've implemented for UDP, is look like:

Server Code:

import android.os.AsyncTask;
import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;



public class udpFirst extends AsyncTask<Void,Void,Void> {
@Override
protected Void doInBackground(Void... voids) {


    try {
        String messageStr="Hello Android!";
        int server_port = 6668;
        // TODO: fill in UDP Client IP, 255 is for broadcast. You can use 255.255.255.255 also.
        InetAddress local = InetAddress.getByName("192.168.43.255");
        DatagramPacket p = new DatagramPacket(messageStr.getBytes(),
                messageStr.length(),
                local,server_port);
        Log.i("UDP server about to: ", "send");
        DatagramSocket s = new DatagramSocket();
        s.send(p);
        s.close();
        Log.i("***** UDP server: ", "Done sending");
    } catch ( SocketException e) {
        Log.i("***** UDP server has: ", "Socket Exception");
    } catch ( UnknownHostException e ) {
        Log.i("***** UDP server has: ", "UnknownHostException");
    } catch (IOException e){
        Log.i("UDP server has Exc", "e: " + e);
    }

    return null;
}
}

Client:

import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;



public class udpSecond extends AsyncTask<Void,Void,Void> {

Context context;

udpSecond(Context c){
    context = c;
}



@Override
protected Void doInBackground(Void... voids) {

    try {
        Log.i("***** UDP client: ", "starting");
        final String text;
        int server_port = 6668;
        byte[] message = new byte[2048];
        DatagramPacket p = new DatagramPacket(message, message.length);
        DatagramSocket s = new DatagramSocket(server_port);
        Log.i("***** UDP client: ", "about to wait to receive");
        s.receive(p); // blocks until something is received
        Log.i("***** UDP client: ", "received");
        text = new String(message, 0, p.getLength());
        Log.i("*UDP client message: ", text);

        Handler handler =  new Handler(context.getMainLooper());
        handler.post( new Runnable(){
            public void run(){
                Toast.makeText(context, text,Toast.LENGTH_LONG).show();
            }
        });

        Log.d("Udp tutorial","message:" + text);
        s.close();
    } catch ( SocketException e) {
        Log.i("***** UDP client has: ", "Socket Exception");
    } catch (IOException e){
        Log.i("UDPclient has Exception", "e: " + e);
    }

    return null;
}
}

Hope this helps :)

Kaushal28
  • 5,377
  • 5
  • 41
  • 72
  • `Unfortunately in TCP, There is no facility of broadcasting (sending msg to all clients).`. What do you mean? A client is only a client if it is connected to the server. Of course a TCP server can send a message to all connected clients. You might confuse OP whit what you are telling. – greenapps Jan 02 '17 at 14:31
  • http://stackoverflow.com/questions/4295177/is-broadcasting-via-tcp-possible @greenapps – Kaushal28 Jan 02 '17 at 14:33
  • @greenapps yes, it can send msg to all connected clients but not at once. I mentioned that you've to send it one by one. – Kaushal28 Jan 02 '17 at 14:34
  • 1
    @greenapps Nothing confusing about it. There is no *broadcast* means of doing so. It has to be done by multiple unicast. – user207421 Jan 02 '17 at 14:36
  • `I mentioned that you've to send it one by one.`. Is it? Not that i read that anywhere? Now you confuse me. – greenapps Jan 02 '17 at 14:36
  • @greenapps read this in my second paragraph, starting from `Alternatively... `, now see in bold letters. – Kaushal28 Jan 02 '17 at 14:37
  • That still is beside the wishes of OP as i understand it. OP should send messages one by one to all clients using TCP. – greenapps Jan 02 '17 at 14:40
  • entire code. Use UDP instead. See the link mentioned in my answer, or see the edits. – Kaushal28 Jan 03 '17 at 14:24