我正在Android上开发一个应用程序,我正在搜索范围内的所有同行,然后连接所有这些应用程序,启动发现的设备成为组所有者,所有其他人成为客户端,我已完成所有操作连接的事情,但现在我想让组所有者将消息发送给所有连接的对等体,如何实现这一点,请告诉我点对点通信的方法是什么,Android中的p2p也使用IP来实现发送和接收数据?
三江源 关心塔利班。
答案 0 :(得分:10)
Wi-Fi Direct / P2P可被视为普通Wi-Fi,但群组所有者(GO)充当软件接入点(dhcp服务器,配置等)。所以要回答你的上一个问题,是的,Wi-Fi Direct也使用IP来发送和接收数据。
您想要将数据发送给该群组中的所有成员吗?有两种解决方案:
最有效的方法是解决方案1,使用多播广播数据,因为您只需要发送一次数据。不幸的是,Android中的Wi-Fi多播支持非常分散,因为许多设备似乎阻止了非单播流量。如果您想沿着这条路线走下去,请参阅this article了解更多深度信息。
如果您希望保证所有设备的支持并且仅传输少量数据,则解决方案2是最佳方法。 GO需要组中客户端的IP地址,但由于在Android中实现Wi-Fi Direct的方式,所有设备都只知道GO IP。一种解决方案是让客户端连接到GO上的套接字,以获取其IP地址:
客户端代码
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));
}
}
});
群组所有者代码:
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();
}
}
现在你需要做的就是在每个客户端上启动一个服务器套接字,并让GO迭代通过客户端列表创建一个套接字连接到每个客户端列表并发送你想要广播的消息。
答案 1 :(得分:0)
现在我们有了https://github.com/libp2p/go-libp2p-pubsub-用于处理多播消息(它也可以将网络划分为主题)
,我们还有一些类似的漂亮的对等发现协议:https://github.com/libp2p/go-libp2p-examples/blob/master/chat-with-mdns/mdns.go
因此,您只需使用libp2p即可非常轻松地与本地网络中的多播主题消息进行交互
我刚刚测试了https://github.com/MoonSHRD/p2chat-android,它将您需要的解决方案包装到单个库中,可以在android中使用它。
到目前为止,我们可以与高级别的消息进行交互,而不是与低级别的套接字或流进行交互。希望这会帮助某人。
p.s。但是,我应该注意到,我还没有在Wi-Fi直接网络中测试mDNS发现
答案 2 :(得分:0)
开始时有几个选项,但是您可以根据需要进行选择。使用 jmdns/jmdns broadcast
和discover
服务非常容易。这是来自docs的示例,
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());
}
}
}
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());
}
}
}
如果您正在用Java开发桌面应用程序,那么您的目标应该是找到在那里存在的最佳跨平台DNS-SD(Zeroconf,Bonjour,DNS自我发现)库。
还有其他纯Java DNS-SD实现,但是尚不清楚它们是否提供与DNS-SD一样易于使用或经过全面测试的库。前往
Waiter一次。但是,我更喜欢通过jmdns
,它运作良好。由于对等连接应该使用IP(必须使用),因此一旦建立连接,您就可以轻松发送/接收数据。