Multicast Socket Joined Client Ip Address - java

I'm working in client server project in java. i'm using MulticastSocket . I have to send some message to selective clients. But i don't know how to get joined client address. Can anyone please help me out.

Use code like below, this may help you.
private void init() throws IOException {
DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.configureBlocking(true); //optional
channel.bind(new InetSocketAddress(5000));
InetAddress iGroup = InetAddress.getByName("224.0.0.1");
NetworkInterface intrf = NetworkInterface.getByName("lo"); // lo name could be changed according your requirement
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, intrf);
channel.join(iGroup, intrf);
}

Related

Why I can't connect my sockets from two PCs in Java?

So far I have achieved making server/client relations on the same computer by parallelly running different java classes. As I don't want to overcomplicate this question, I will post my simplified code which works perfectly fine.
Server:
public class Server {
public static final int PORT = 9090;
public static void main (String[] args) {
try {
ServerSocket serverSocket = new ServerSocket (PORT);
Socket client = serverSocket.accept ();
System.out.println ("Client connected!");
} catch (IOException ioException) {
ioException.printStackTrace ();
}
}
}
Client:
public class Client {
public static final int PORT = 9090;
public static final String IP_ADDRESS = "127.0.0.1";
public static void main (String[] args) {
try {
Socket socket = new Socket (IP_ADDRESS,PORT);
} catch (IOException ioException) {
ioException.printStackTrace ();
}
}
}
After I run them, I get the expected output - console in class Server prints "Client connected!".
Like any other curious programmer, I decided to try out the same program on my two laptops. One laptop has client code, while second has server code. Of course, I had to change "127.0.0.1" or "localhost" to ip address my server laptop has by typing on google "what is my IP address". I just copied that new IP address into IP_ADDRESS variable and hoped it would work the same. Unfortunately, it didn't happen. My client laptop looks as if it never connected to server laptop, because server laptop never printed message "Client connected!". What am I missing? It looks so easy, yet it doesn't work. Could someone help me solve this?
P.S. I don't want to share my IP address due to privacy reasons, but it was the first number that pops when any of you google: what is my IP address?
If you are on a local network, you don't have to take your public IP. You need to find your local IP (if you are on linux, a simple "ip a" and you'll have your IP address, if you are on windows )
If you are not on a local network, you could open your router' settings to open the 9090 port but I STRONGLY discourage you to do something like that for security reason.

Netty UDP broadcast receiver works on one NIC but not on another - why?

Hi – I wonder if anyone can help me. I’m using Netty 4.1.9 to send UDP messages between two Linux machines:
Both machines are attached via 3 separate NICs to the same 3 networks.
I have some working code that sends the messages from one to the other and that is received okay.
I then changed the code to force the UDP traffic onto a different network, out through a different NIC on the sender.
The sending works, I can see the traffic on the different network, but now the netty receiver can’t see the traffic.
As far as I can see the receiver code shouldn’t care which NIC the data comes in on, so I don’t understand what the issue is.
I’m sure the data arrives at the receiver host on the correct NIC because running “tshark -i ” on the receiver shows the traffic on the correct network, with the correct destination port, and expected length.
The broadcast address I'm using in both cases is 255.255.255.255.
Here's the code for the setting up the receiver channel, this code works fine when the traffic arrives on the first NIC, but not when it arrives on the other:
public Channel createReceivingChannel(final int port,
final EventLoopGroup myGroup) throws InterruptedException
{
return new Bootstrap()
.group(myGroup)
.channelFactory(new ChannelFactory<NioDatagramChannel>()
{
#Override
public NioDatagramChannel newChannel()
{
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
}
})
.handler(new ReceiverInitializer(this.protocolConfig))
.bind(port).sync().channel();
}
Here's the sender code that works with the receiver, but puts the UDP messages on the wrong network:
public Channel createSendingChannel( final NetworkAddress localAddress,
final int port,
final EventLoopGroup myGroup) throws InterruptedException
{
return new Bootstrap()
.group(myGroup)
.channelFactory(new ChannelFactory<NioDatagramChannel>()
{
#Override
public NioDatagramChannel newChannel()
{
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
}
})
.localAddress(localAddress.address, port)
.option(ChannelOption.SO_BROADCAST, true)
.handler(new SenderInitializer(this.protocolConfig))
.bind(0).sync().channel();
}
And here's my sender code that puts the data on the right network, but the receiver above can't see it:
public Channel createSendingChannel(
final NetworkAddress localAddress,
final int port,
final EventLoopGroup myGroup) throws InterruptedException
{
final InetSocketAddress localSocketAddress = new InetSocketAddress(localAddress.address, port);
return new Bootstrap()
.group(myGroup)
.channelFactory(new ChannelFactory<NioDatagramChannel>()
{
#Override
public NioDatagramChannel newChannel()
{
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
}
})
.localAddress(localAddress.address, port)
.option(ChannelOption.SO_BROADCAST, true)
.handler(new SenderInitializer(this.protocolConfig))
.bind(localSocketAddress).sync().channel(); // difference here to bind the sender to correct NIC
}
Any help gratefully received at this stage. I'm stuck.
Many thanks in advance,
Michael.

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.
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:
Broadcast the message once using multicast.
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.
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
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.

TCP connection to send and receive Java/Android with Visual Basic .NET Server

I have searched everywhere to find an answer for this question:
I have a TCP client on my android application that sends an message to the server which is written in Visual Basic .NET Framework 4.
Now i want to send an message from my server to the phone over 3g, it works on wifi and 3g..
private class startserver extends Thread
{
public void server() throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(8765);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println(clientSentence.substring(1));
msgshower = clientSentence.substring(1);
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "Received: " + msgshower , Toast.LENGTH_LONG).show();
}
});
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
#Override
public void run() {
try {
server();
} catch (Exception e) {
e.printStackTrace();
}
}
I start it in the OnCreate method
Now i send a message with (VB.NET)
Private Sub sends(ByVal message As String)
Dim tcp As New TcpClient
tcp.Connect(connectedIP, 8765)
Dim bw As New IO.BinaryWriter(tcp.GetStream)
bw.Write(message)
bw.Close()
tcp.Close()
End Sub
On wifi it will arrive, on 3g it wont... any idea's how to do this?
How do other applications archive this?
I think you're having problem with the ip address asigned by your mobile phone operator. The fact that works on wifi, but not on 3G, I think that is because your mobile(when connected through 3G) doesn't have a public IP address.
When you use SocketServer in your mobile, you're opening a port a waiting for others to connect to it. If your IP address is not reachable from internet, it won't happen (it's like having a computer behind a firewall.)
Could you try to implement the server in the VB machine, assuming that it has a public reachable address? This way, the phone wouldn't act as a server, it wouldn't be necessary to have a reachable address, as long as the VB machine has one. Then, you should use Socket class to bind to the server ip and port.
Totally confused by your code list above..
If you want to host a server in VB.NET, you should not use TcpClient class but TcpListener and if you need a better performance, use Socket class directly.
At the Android client side, you should new Socket(server,servPort), when you want to send message, write the outputStream, and read the inputStream to receive message.

MulticastSocket in java : BindException all the time

I am coding a basic app, a chat that sends message through the network using multicast and unicast, depending on the situation. So far, no problem, until a while ago when I began the MulticastSocket part. I have a BindException when I run this basic code (I removed all my other methods that do not concern the part with my problem) :
private MulticastSocket socket_multicast;
private int port;
private InetAddress multicast_address;
public void setPort(int p) {
port = p;
}
public void setMulticastAddress(String s) {
try {
multicast_address = InetAddress.getByName(s);
} catch (IOException e) {
e.printStackTrace();
}
}
public void joinGroup() {
System.out.println("Port : "+port+"\n #IP : "+multicast_address+"\n");
try {
socket_multicast = new MulticastSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
try {
socket_multicast.joinGroup(multicast_address);
} catch (IOException e) {
e.printStackTrace();
}
}
When I run this piece of code, I have the following error (I put 225.1.1.1 and 4567 in the GUI):
Port : 4567
#IP : /225.1.1.1
java.net.BindException: Address already in use
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
at
java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:85)
at java.net.DatagramSocket.bind(DatagramSocket.java:373)
at java.net.MulticastSocket.<init>(MulticastSocket.java:165)
at java.net.MulticastSocket.<init>(MulticastSocket.java:130)
at networkinterface.MulticastIF.joinGroup(MulticastIF.java:61)
No matter which combinason of IP and port I put, always get the same error. I even restarted my computer, it made no changes.
Notes : To test, I do a right click in my class with the main in the Package view, then "Run as -> Java application". Does Eclipse makes some kind of virtual machine when I do that, or only uses the loopback address 127.0.0.1, or whatever ? When I print the result of InetAddress.getLocalHost(); I've got "akee-netbook/127.0.1.1". Since I use Unicast and Multicast, Maybe it only uses the loopback address, and tries to bind on an already-binded address. If so, how can I properly test my app ? I don't know if I am being clear, if not, tell me !
One last thing, Why is there a slash when I print my ip address? Will it be a problem later ? or is it smth that comes from the toString() method?
Are you running this on a linux system? If so, have you compiled multicasting into the kernel or loaded the module for it?
Regarding the toString(), see the javadocs for InetAddress.toString()
Huh, I know where I went wrong. I am using an UDP socket (DatagramSocket) with the #IP/port, and then I try to bind again on the same #IP/port with a MulticastSocket. Because Multicast uses UDP I presumed that I could use the same socket for both Unicast and Multicast traffic, it seems that it doesn't work that way.
Anyway, thank's for your answers and sorry for taking your time over a n00b problem, solved with two characters :
socket_multicast = new MulticastSocket(port);
replaced with
socket_multicast = new MulticastSocket(port+1);
-_-"

Categories