My laptop is connected with ethernet cable and wifi
my ethernet ip: 192.168.18.32
my wifi ip: 192.168.18.167
Now I would like to send a udp packet through java using wifi network interface.
I read that if i bind to the correspoding ip then the corresponding interface will be used to send udp packet ie if i bind to ip 192.168.18.167 then udp packets will sent using wifi interface
my code is:
final String wiFiCardAddressName = "192.168.18.32";
final String ethernetAddressName = "192.168.18.167";
final InetAddress wiFiCardAddress = InetAddress.getByName(wiFiCardAddressName);
final InetAddress ethernetAddress = InetAddress.getByName(ethernetAddressName);
DatagramSocket datagramSocketWifi = new DatagramSocket(10000, wiFiCardAddress);
System.out.println(ethernetAddress);
DatagramSocket datagramSocketEt = new DatagramSocket(6666, ethernetAddress);
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, serverPort);
but whenever this send method is called
datagramSocketWifi.send(sendPacket);
datagramSocketet.send(sendPacket);
It shows the following error:
Exception in thread "main" java.net.BindException: Cannot assign requested address: Datagram send failed
at java.net.DualStackPlainDatagramSocketImpl.socketSend(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.send(Unknown Source)
at java.net.DatagramSocket.send(Unknown Source)
at socket_test.Client_UDP_Bind.main(Client_UDP_Bind.java:50)
My server was running on localhost ie 127.0.0.1 when i moved my server to an external host ie IP then this same code worked. I could sent packets using ehternet or wife and could see the log in wireshark.
Related
I need to communicate with a server using udp message like this. For example, my client ip is 192.168.86.50 and the server is listening to port 7777 on address 127.0.0.1
UDP message from my client to server: 192.168.86.50:54321 --> 127.0.0.1:7777
The client will reply with a UDP message like this: 127.0.0.1:7777 --> 192.168.86.50:54321
How do I write Netty to dynamically listening to a source port of a udp message? The source port is dynamically generate from the OS.
Thanks,
You can specify the Source (local) address while connecting.
Here is a snippet:
Bootstrap bootstrap = new Bootstrap()
.group(new NioEventLoopGroup(1))
.channel(NioDatagramChannel.class)
.handler(new Handler());
SocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 7777);
SocketAddress localAddress = new InetSocketAddress("192.168.86.50", 5555);
bootstrap.connect(serverAddress, localAddress);
I am trying to make an streaming app and I want to use UDP. I would like the connection to be P2P. So I have a java tcp server running on google cloud, an android phone and my pc. When android connects to tcp server it will create a DatagramSocket on the server that will receive the packet android sends to get the port and ip. Same for the pc. Each client will get the other's client ip and port and each client will get the port that the server received (EG: android sends from port 18000, it will get other's client ip and port and port 18000). Then I close the initial DatagramSocket and open a new one that is bound to the port it gets from server (in our eg 18000). But the connection is never created between the pc and android (android is on 4G and pc on router , so different networks)
socket = new DatagramSocket(Integer.parseInt(po));
Here is how I create the P2P datgram socket, where po is 18000 (each client has different po - the android has 18000 and the pc has let's say 45000), I get those port from tcp server and is ok.
public void send() throws NumberFormatException, IOException
{
//only for testing
byte[] buffer = new byte[1024];
buffer = "test".getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length,InetAddress.getByName(ip),Integer.parseInt(port));
socket.send(packet);
}
Here is how i send data from the P2P datagram. The ip is the other's client public ip and the port is the other's client port that is listening.
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
byte[] buffer = new byte[64000];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
socket.receive(packet);
//acum ca am primit
String ana = new String(packet.getData());
System.err.println("Am primit de la celalalt "+ana);
}
}
Here is the thread that listens for incoming packets.
The main problem is that this works but only when the client are on the same network as the server!Even if I both client are on the same netowk , but the server is on a different one, they won't receive anything. Data sent from TCP is 100% correct.
DatagramPacket packet= new DatagramPacket(buffer,buffer.length, InetAddress.getByName("server_ip"),port_main);
socket_udp.send(packet);
Here is how I send the UDP packet to the server in order to get the port back.
I tried using the same socket_udp ,without creating socket var again, it failed too.
I would like to bind a MulticastSocket to the address 127.0.0.1 (Socket should only be reachable within the current host) but with the following code example i got a
java.net.SocketException: Network is unreachable: Datagram send failed exception
Is there a way to fix the problem? Here is my code
int port = 6677;
InetAddress group = InetAddress.getByName("232.0.1.10");
try(MulticastSocket s = new MulticastSocket(new InetSocketAddress(InetAddress.getByName("127.0.0.1"),port))){
String msg = "Hello";
s.joinGroup(group);
DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),group, port);
s.send(hi);
}
Multicast is a little odd when compared to traditional UDP communication. The whole point is to share data on a known "channel", simultaneously, to anyone who wants access. This sharing is "signaled" to the network by using an IP address in the range 224.0.0.1 to 239.255.255.255. If you try to bind to 127.0.0.1, you just aren't doing Multicast anymore. And if you take a minute and think about it, that makes sense - you can't share the internal interface with other computers.
I'm implementing a DNS server with DatagramSocket (UDP) in Java and the code looks like:
try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
DatagramPacket request = ... // Init Packet
socket.receive(request);
... // Parse request, Resolve, then Generate reesponse
socket.send(response);
}
It works fine on my PC and most servers (including aws, linode, etc), but does not work well on a server with double ethernet adapter.
This server has a network config:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.1.204
netmask 255.255.255.0
auto eth1
iface eth1 inet static
address 192.168.1.207
netmask 255.255.255.0
When I test this DNS, I get:
# nslookup
> server 192.168.1.207
Default server: 192.168.1.207
Address: 192.168.1.207#53
> info.dev.
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; connection timed out; no servers could be reached
>
It seems to receive a packet from eth1 (192.168.1.207) but send to eth0 (192.168.1.204). And my code does not know which interface the packet is received from.
try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
...
socket.receive(request); // local socket address not known :-(
...
socket.send(response); // local socket address not known :-(
}
Socket (TCP) can do this but I do not know whether DatagramSocket (UDP) can do so.
UPDATE-1:
bind one interface instead of 0.0.0.0, it works fine.
UPDATE-2:
Socket (TCP) can get both local and remote address:
try (ServerSocket server = new ServerSocket(23)) {
try (Socket socket = server.accept()) {
System.out.println(socket.getLocalSocketAddress());
System.out.println(socket.getRemoteSocketAddress());
}
}
The local address of that DatagramSocket is 0.0.0.0:53. The one you specified when you constructed it. Which interface it uses to reply on is determined by the static IP routing tables. Not by this code. And getting the local address of the DatagramSocket, or even the target address of the datagram (which you can get in C but not Java), wouldn't help you to solve this problem, if it is a problem.
my code does not know which interface the packet is received from.
Correct. It doesn't care. It is listening at all IP addresses. You told it to do that. It only cares about the remote address, which you haven't shown but have clearly got correct.
try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
I don't know why you've posted this twice.
What you have here is a static IP routing issue. Not a programming problem.
I have a WIFI device, that I am experimenting with. From my macbook I can make a direct connection to the device over wifi. After I have WIFI connection I should be able to communicate with the device over multicast.
However, as soon as I try to send a datagram packet to the camera when I am connected I get some IOException:
java.io.IOException: Can't assign requested address
I reviewed some networking settings and found out that Multicast is enabled for my laptop, also I added the multicast address that is used (239.255.255.250) to the routing table. (Read this somewhere) Still no luck...
Why do I get this exception from my application?
Here is the code I use to connect:
DatagramSocket socket = null;
DatagramPacket packet = null;
try {
socket = new DatagramSocket();
InetSocketAddress iAddress = new InetSocketAddress("239.255.255.250", 1900);
packet = new DatagramPacket(sendData, sendData.length,iAddress);
socket.send(packet);
I think it has something to do with my network / setup.
When I reconnect to my wireless acces point, my app doesn't give this exception and I can see the package in my console:
MacBook-Pro-van-Roy:~ Roy$ sudo tcpdump -ni en1 host 239.255.255.250
Password:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en1, link-type EN10MB (Ethernet), capture size 65535 bytes
19:54:18.688367 IP 192.168.1.34.57428 > 239.255.255.250.1900: UDP, length 129
19:54:18.789447 IP 192.168.1.34.57428 > 239.255.255.250.1900: UDP, length 129
19:54:18.890506 IP 192.168.1.34.57428 > 239.255.255.250.1900: UDP, length 129
InetSocketAddress is not a InetAddress (it's a SocketAddress). You probably want something like this:
InetAddress addr = InetAddress.getByName("239.255.255.250");
packet = new DatagramPacket(sendData, sendData.length, addr, 1900);
socket.send(packet);