i have two android apps ,one can send the string over LAN at specific IP and other app for receiving but i want to broadcast the string over LAN?

StackOverflow https://stackoverflow.com/questions/18240721

Question

I want to broadcast the string over LAN, but when I change the server IP in client code to 255.255.255.255 it doesn't broadcast. What shall I do in order to broadcast the string over LAN? What shall I do in client code so that all the listening ports at different IP's can receive the string at same time.

My client or code for sending the string 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();
            }
        }
    }
}

My server or code for receiving 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");
        }
    }
}
Était-ce utile?

La solution

Socket is a TCP socket. Broadcasting is not possible with TCP. If you want to use TCP, you cannot broadcast, you must have a connection open to each client and send the data over each connection separately.

DatagramSocket is a UDP socket. Broadcasting is possible with UDP. However, the caveat is that UDP does not guarantee that your message will actually arrive. To guarantee that your message arrives you must implement some kind of acknowledgment/retry protocol, but if you do that, you might as well use TCP, since that's what it does.

Edit: Another question and my responses from 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 subject here is device or service discovery, a not uncommon challenge. There are many options. Here are some, in no particular order:

  1. Specify the server IP address in the client device's configurations and have them connect to you.
  2. Specify a list of the client IP addresses in the server device's configuration and have it connect to all of them.
  3. Implement some kind of UDP discovery protocol where you broadcast a discovery request over UDP and devices respond with information about their IP address, etc. Same caveat as above.
  4. Have your server broadcast UDP messages announcing its presence and its IP address, have your clients listen for these and establish TCP connections to server. Same caveat as above.
  5. Check out an existing service discovery protocol, e.g. jmdns.sourceforge.net (compatible with Bonjour/zeroconf). This is actually quite a common issue and many protocols exist to solve it.
  6. Have your server scan all IPs in its subnet and attempt to establish a TCP connection to each. 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: Avoid manual configuration requirements by using UDP and its broadcast capabilities to automatically exchange configuration information. Use that information to establish TCP connections, and then use TCP for reliable data transfer. Keep in mind that UDP broadcasts are limited in scope to the subnet, so you could not use broadcast-based discovery to discover machines on other LANs -- for that you'd have to do some kind of central service registry with TCP based registration and a well-known registration server.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top