Java – I have two android apps, one that can send strings over LAN on a specific IP and one that is used to receive, but I want to broadcast strings over LAN?

I have two android apps, one that can send strings over LAN on a specific IP and one that is used to receive, but I want to broadcast strings over LAN?… here is a solution to the problem.

I have two android apps, one that can send strings over LAN on a specific IP and one that is used to receive, but I want to broadcast strings over LAN?

I want to broadcast the

string over LAN, but when I change the server IP in the client code to 255.255.255.255, it doesn’t broadcast. What should I do to broadcast strings over LAN? What should I do in the client code so that all listening ports for different IPs can receive strings at the same time.

The client or code I send the string to is:

public class MainActivity extends Activity {

private Socket socket;
    private static final int SERVERPORT = 6000;
    private static final String SERVER_IP = "192.168.1.10";

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     

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);
            } catch (UnknownHostException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }
}

The code for my server or receive string is:

public class MainActivity extends Activity {
    private ServerSocket serverSocket;

Handler updateConversationHandler;
    Thread serverThread = null;
    private TextView text;
    public static final int SERVERPORT = 6000;

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView) findViewById(R.id.text2);
        updateConversationHandler = new Handler();
        this.serverThread = new Thread(new ServerThread());
        this.serverThread.start();
    }

@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 {
                    socket = serverSocket.accept();
                    CommunicationThread commThread = new CommunicationThread(socket);
                    new Thread(commThread).start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

class CommunicationThread implements Runnable {

private Socket clientSocket;
        private BufferedReader input;

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

public void run() {
            while (! Thread.currentThread().isInterrupted()) {
                try {
                    String read = input.readLine();
                    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");
        }
    }
}

Solution

A socket is a TCP socket. TCP cannot broadcast. If you want to use TCP, you can’t broadcast, you have to open a connection for each client and send data through each connection separately.

DatagramSocket is a UDP socket. Broadcasts are possible using UDP. However, it is important to note that UDP does not guarantee that your message will arrive. To guarantee that your message arrives, you must implement some sort of acknowledgment/retry protocol, but if you do, you might as well use TCP, because that’s what it does.

EDIT: Another question and my response in the comments below. OP wrote:

then how i’ll get the IP’s of listening devices in LAN in order to make connection separately?

The topic here is device or service discovery, which is not uncommon challenges. There are many options. Here are a few, in no particular order:

  1. Specify the server IP addresses in the configuration of the client devices and have them connect to you.
  2. Specify a list of client IP addresses in the configuration of the server appliance and have it connect to all of them.
  3. Implement a UDP discovery protocol in which you broadcast a discovery request over UDP and the device responds with information about its IP address, etc. Same as the above considerations.
  4. Have your server

  5. broadcast UDP messages, announce their presence and IP address, and have your clients listen for these messages and establish a TCP connection to the server. Same as the warning above.
  6. Check existing service discovery protocols, such as jmdns.sourceforge.net (compatible with Bonjour/zeroconf). This is actually a very common problem, and there are many protocols that can solve it.
  7. Have your server scan all IPs in its subnet and attempt to establish a TCP connection to each IP. Very time-consuming, but may be appropriate.

Options 1-2 are the simplest to implement, but require manual configuration by the user.

Options 3-5 have a common theme: avoiding manual configuration requirements by automatically exchanging configuration information using UDP and its broadcast features. Use this information to establish a TCP connection, and then use TCP for reliable data transfer. Keep in mind that the scope of UDP broadcasts is limited to subnets, so you cannot use broadcast-based discovery to discover machines on other LANs—because you must use TCP-based registration and a well-known registration server.

Option 6 avoids manual configuration at the expense of poor discovery performance and potentially high system resource usage. Options 3-5 are designed to optimize the discovery process.

Related Problems and Solutions