Talib
Talib

Reputation: 1164

Android Wi-Fi Direct Network

I am developing an application on Android where I am searching for all the peers in the range and afterwards connect with all of them, The device who initiated the the discovery become the group owner and all others become client, I have done all the connection thing but now I want to the group owner to send the message to all the connecting peers, How to achieve this and also please tell me what is the methodology in peer-to-peer communication , Does p2p in Android also use IP to send and receive data?

Thankyou Regards Talib.

Upvotes: 7

Views: 10066

Answers (3)

Kiran Maniya
Kiran Maniya

Reputation: 9009

There are several options to start with but you can choose according to your requirements. It's fairly easy to broadcast and discover the service using jmdns/jmdns. Here is the example from docs,

  • Service Registration
import java.io.IOException;
import java.net.InetAddress;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;

public class ExampleServiceRegistration {

    public static void main(String[] args) throws InterruptedException {

        try {
            // Create a JmDNS instance
            JmDNS jmdns = JmDNS.create(InetAddress.getLocalHost());

            // Register a service
            ServiceInfo serviceInfo = ServiceInfo.create("_http._tcp.local.", "example", 1234, "path=index.html");
            jmdns.registerService(serviceInfo);

            // Wait a bit
            Thread.sleep(25000);

            // Unregister all services
            jmdns.unregisterAllServices();

        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}
  • Service Discovery
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceListener;

public class ExampleServiceDiscovery {

    private static class SampleListener implements ServiceListener {
        @Override
        public void serviceAdded(ServiceEvent event) {
            System.out.println("Service added: " + event.getInfo());
        }

        @Override
        public void serviceRemoved(ServiceEvent event) {
            System.out.println("Service removed: " + event.getInfo());
        }

        @Override
        public void serviceResolved(ServiceEvent event) {
            System.out.println("Service resolved: " + event.getInfo());
        }
    }

    public static void main(String[] args) throws InterruptedException {
        try {
            // Create a JmDNS instance
            JmDNS jmdns = JmDNS.create(InetAddress.getLocalHost());

            // Add a service listener
            jmdns.addServiceListener("_http._tcp.local.", new SampleListener());

            // Wait a bit
            Thread.sleep(30000);
        } catch (UnknownHostException e) {
            System.out.println(e.getMessage());
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

if you are developing desktop application in java, your goal should be to find the best cross-platform DNS-SD (Zeroconf, Bonjour, DNS self discovery) library exists out there.

There are other pure Java DNS-SD implementations, but it's unclear if any of them offer a library that is as easy to use or fully tested as DNS-SD. Head over to the Waiter once. However, I prefer going through the jmdns, It works well. As the peer to peer connection is supposed to use IP(it have to), you can send/receive data easily once the connection is established.

Upvotes: 0

Jack Bekket
Jack Bekket

Reputation: 11

Now we have https://github.com/libp2p/go-libp2p-pubsub - for handling multicast messages (and it's also could shard network into topics)

and we also have some pretty peer discovery protocol like that: https://github.com/libp2p/go-libp2p-examples/blob/master/chat-with-mdns/mdns.go

So, you can very easily to interact with topic messages multicast in local network, just using libp2p

I've just test https://github.com/MoonSHRD/p2chat-android which wrap solution you need into single library, which can be used from android.

This far we could interact with high level of messages instead of interaction with sockets or streams at low levels. Hope this will help someone.

p.s. However, I should notice, that I didn't test mDNS discovery in wi-fi direct networks yet

Upvotes: 1

Nikki Ashton
Nikki Ashton

Reputation: 256

Wi-Fi Direct/P2P can be considered as normal Wi-Fi but where the group owner (GO) acts as a software access point (dhcp server, provisioning, etc). So to answer your last question, yes Wi-Fi Direct also uses IP to send and receive data.

You want to send data to all members in the group? There are two solutions for this:

  1. Broadcast the message once using multicast.
  2. Send the message to each individuel client in the group.

The most efficient method would be solution 1, to broadcast the data using multicast, as you would only need to send the data once. Unfortunately Wi-Fi multicast support is very fragmented in Android, as a lot of devices seem to block non-unicast traffic. See this article for more in depth information if you want to go down this route.

Solution 2 is the best method if you want to guarantee support on all devices and only transmit a small amount of data. The GO need the IP addresses of the clients in the group, but because of the way Wi-Fi Direct is implemented in Android, only the GO IP is known to all devices. One solution is to let the clients connect to a socket on the GO, to get their IP address:

Client code

private static final int SERVER_PORT = 1030;

... // on group join:
wifiP2pManager.requestConnectionInfo(channel, new ConnectionInfoListener() {
    @Override
    public void onConnectionInfoAvailable(WifiP2pInfo p2pInfo) {
        if (!p2pInfo.isGroupOwner) {
            // Joined group as client - connect to GO
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress(p2pInfo.groupOwnerAddress, SERVER_PORT));
        }
    }
});

Group owner code:

private static final int SERVER_PORT = 1030;
private ArrayList<InetAddress> clients = new ArrayList<InetAddress>();

public void startServer() {
    clients.clear();
    ServerSocket serverSocket = new ServerSocket(SERVER_PORT);

    // Collect client ip's
    while(true) {
       Socket clientSocket = serverSocket.accept();
       clients.add(clientSocket.getInetAddress());
       clientSocket.close();
    }
}

Now all you need to do is start a serversocket on each client, and make to GO iterate through the client list creating a socket connection to each and sending the message you want to broadcast.

Upvotes: 12

Related Questions