Java not receiving udp packets on windows 7 - java

I'm making a system for reading smart-cards. The reader devices send out udp packets. Wireshark can see the packets but it says that they have an incorrect frame check sequence. This is on Windows 7, while on Debian it works flawlessly. I tried adding rules, for the specific ports used, to the firewall... even disabled it altogether... no joy :/
I wrote this bare bones code that should verify that the packets are reaching the java app :
try {
DatagramSocket s = new DatagramSocket(null);
InetSocketAddress address = new InetSocketAddress("192.168.1.100",8888);
s.bind(address);
byte buffer[] = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while(true)
{
System.out.println("Waiting...");
s.receive(packet);
System.out.println("Received!");
}
} catch (Exception e) {
e.printStackTrace();
}
It seems that they aren't ... any ideas?

Related

Java multiple UDP clients listening same port

Say I start a simple UDP server: nc -u localhost 10000
And a simple UDP client: nc -ul 10000
Then is it possible, in Java, to receive the messages sent by the server without getting an "Address already in use" exception because there's already a client?
EDIT: here's the code I'm using:
DatagramSocket socket = new DatagramSocket(port);
new Thread(() -> {
try {
while(true) {
byte[] receiveData = new byte[256];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
String message = new String( receivePacket.getData(), 0, receivePacket.getLength()).trim();
}
}
catch (SocketException ignore) {}
catch (IOException e) { e.printStackTrace(); }
}).start();
This leads to a java.net.BindException: Address already in use (bind failed).
Using this:
DatagramSocket socket = new DatagramSocket(null);
socket.setOption(SO_REUSEPORT, true);
socket.setOption(SO_REUSEADDR, true);
new Thread(() -> {
try {
while(true) {
byte[] receiveData = new byte[256];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
String message = new String( receivePacket.getData(), 0, receivePacket.getLength()).trim();
}
}
catch (SocketException ignore) {}
catch (IOException e) { e.printStackTrace(); }
}).start();
Produces no exception but I won't receive the messages sent by the server.
EDIT 2: in the real situation, the server is broadcasting messages.
This should be possible by utilizing StandardSocketOptions.SO_REUSEPORT:
For datagram-oriented sockets the socket option usually allows multiple UDP sockets to be bound to the same address and port.
The Linux Kernel supports this since 3.9.
On Windows, you might need to utilize SO_REUSEADDR, but I'm not exactly sure.
Using SO_REUSEADDR
The SO_REUSEADDR socket option allows a socket to forcibly bind to a port in use by another socket.

UDP packets not received in emulator from localhost

My app is unable to receive the UDP packets when running in the emulator. UDP packets are sent by below java program on "localhost" over the port 49999.
DatagramSocket clientsocket;
DatagramPacket dp;
BufferedReader br;
InetAddress ia;
byte buf[] = new byte[1024];
int cport = 50000, sport = 49999;
clientsocket = new DatagramSocket(cport);
dp = new DatagramPacket(buf, buf.length);
br = new BufferedReader(new InputStreamReader(System.in));
ia = InetAddress.getLocalHost();
while(true)
{
Random rand = new Random();
String str1 = rand.nextInt(100) + "";
buf = str1.getBytes();
System.out.println("Sending " + str1);
clientsocket.send(new DatagramPacket(buf,str1.length(), ia, sport));
try{
Thread.sleep(100);
} catch(Exception e){}
}
Another java UDP server program running on the same localhost receives the packets fine. This means that the packets are sent to localhost:49999 correctly.
To forward the packets from localhost to the emulator, I did telnet redirect as below:
telnet localhost 49999
redir add udp:49999:49999
The UDP receiver in the app looks like this:
byte[] data = new byte[1400];
DatagramPacket packet = new DatagramPacket(data, 1400);
DatagramSocket socket = new DatagramSocket(49999);
socket.setSoTimeout(200);
try{
socket.receive(packet); ---->> This throws a SocketTimeoutException
} catch(SocketTimeoutException e){}
My understanding was that the telnet redirect should take care of forwarding the packets from my development machine's localhost:49999 to emulator's localhost:49999 so that the data is available on the DatagramSocket(49999). However it keeps throwing the SocketTimeoutException all the time.
It would be a great help to know what is the missing piece of the puzzle here.
After connecting to the localhost you may want to check that the port was actually asigned as intended with the command netstat -na in the cmd. It also might be worth a try to use the IP 127.0.0.1 instead.

Do I need to wait for my UDP socket to be connected before sending anything?

I have written a class which sends some messages to a UDP socket. I noticed that at the start on my first try using the socket, it would timeout. When I went to do a wireshark capture, I kept seeing the first packet not being sent from my machine which is causing a timeout as the server needs to have two messages before sending a status back. Here is my code.
DatagramSocket socketN = null;
try {
socketN = new DatagramSocket();
DatagramPacket connect = new DatagramPacket(connectMsg, connectMsg.length, ipAddr, port);
socketN.send(connect);
socketN.setSoTimeout(5000);
DatagramPacket start = new DatagramPacket(startMsg, startMsg.length, ipAddr, port);
DatagramPacket status = new DatagramPacket(status, status.length);
socketN.send(start);
socketN.receive(status);
} catch (InterruptedException | IOException e) {
e.printStackTrace();
} finally {
socketN.close();
}
Based on the code and my wireshark capture, I can see the message start being sent from my PC but not the message connect. This block of code is repeated a number of times so on other times it is repeated the timeout does not occur.

udp in android example

i am using the below code to send text message between two android devices but i could not receive the packet at the receiver side
the sender:
String messageStr="Hello Android!";
Log.d("note","message prepaered");
int server_port = 12345;
try{
Log.d("note","socket prepaered");
DatagramSocket s = new DatagramSocket();
Log.d("note","socket defined");
InetAddress local = InetAddress.getByName(ip.getText().toString());
int msg_length=messageStr.length();
byte[] message = messageStr.getBytes();
Log.d("note","converting message to bytes");
DatagramPacket p = new DatagramPacket(message, msg_length,local,server_port);
s.send(p);
Log.d("note","sending msg");}
catch (SocketException e){
Log.d("error",e.getMessage());
}
catch(IOException v1){
Log.d("error", v1.getMessage());
}
the receiver :
String text;
int server_port = 12345;
byte[] message = new byte[1500];
try{
DatagramPacket p = new DatagramPacket(message, message.length);
Log.d("note","putting msg in packet");
DatagramSocket s = new DatagramSocket(server_port);
Log.d("note","defining socket");
s.receive(p);
Log.d("note","recieving packet");
text = new String(message, 0, p.getLength());
msg.setText(text);
s.close();
}
catch (SocketException e){
Log.d("error",e.getMessage());
}
catch(IOException v1){
Log.d("error", v1.getMessage());
}
thanks in advance for help
Ok. There are a lot of undefined variables in your story.
First of all, you should try this at a local machine, where you can be sure that this is not a network problem.
Second, try to wrap the receiving code in a endless loop, it will make the debugging easier.
If by now, you found out that your code is actually working on a localhost,
you should check your network configuration on your devices, make sure you are using the right addresses, and both devices are in the same network.
If you have trouble making your code work on a localhost, try to test your server and client independently on a working software, like http://sourceforge.net/projects/sockettest/ for example, it will allow you to make sure that your client and server code is working
Also don't forget about the timing, start your receiver first.
P.S. Please format your code properly.

Multicasting message from Android app to local server

I'm developing an Android app that at some points, sends a multicast message. I'm running this on an emulator device so far.
On the same machine, I have a server (not Android, a plain Java app) that is expecting the multicast message, but it never gets it. When I start the server, since it is on my local machine, I start it the loopback interface (127.0.0.1). I must say that I've done this with regular Java apps and it works perfectly.
Here's the code for the Android App:
try {
InetAddress group = InetAddress.getByName(MULTICAST_HOST);
byte[] data = DISCOVER_MESSAGE.getBytes();
DatagramSocket ds = new DatagramSocket();
ds.setSoTimeout(60000);
DatagramPacket dp = new DatagramPacket(data, data.length, group, TcpipSIBDiscoverer.PORT);
ds.send(dp);
byte[] buf = new byte[1024];
dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
if (dp.getLength() > 0) {
byte[] tmp = new byte[dp.getLength()];
System.arraycopy(dp.getData(), 0, tmp, 0, tmp.length);
String received = new String(tmp);
Logger.debug(this, "Received from SIB: " + received);
SIBDescriptor sibDescriptor = createSIBDescriptor(received);
this.discoveryListener.connectorSIBDiscovered(sibDescriptor);
}
} catch (SocketTimeoutException e) {
Logger.error("Socket time excedeed while waiting a response when discovering SIBs. Trying again");
} catch (IOException e) {
Logger.error("There was some kind of IO error while waiting for a response when discovering SIBs. Trying again");
}
As you can see, I'm using a regular DatagramSocket instead of MulticastSocket. This works in plain Java apps, since the listening server address is 235.0.0.1:5555.
Not really sure if the code is not working or I have to do something in the emulator device so it can truly reach my loopback interface... Any ideas?
Thanks!
Alex
127.0.0.1 on android refers to the device's localhost (or the emulators).
To reach localhost of your 'local machine' you should use 10.0.2.2.
This is discussed in a lot of topics.

Categories