Java UDP respond to broadcast request - java

At work we are developing an android app that communicates with set top boxes(STB).
It all works fine but I'm trying to create a "mock" STB that the app can connect to so I can control the responses for testing.
I have no access to the code in the STB to know how they set up the sockets but I do have a simplified version of the client code used by the app.
Here's the client code:
public class UDPClient {
public static void main(String[] args) throws SocketException, UnknownHostException {
DatagramSocket c = new DatagramSocket(12345);
c.setBroadcast(true);
c.setSoTimeout(20000);
String msearchData = "DATA";
byte[] sendData = mSearchData.getBytes();
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("239.255.255.250"), 1900);
c.send(sendPacket);
System.out.println("Request packet sent");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// wait for reply
byte[] recBuf = new byte[15000];
DatagramPacket receivePacket = new DatagramPacket(recBuf, recBuf.length);
try {
c.receive(receivePacket);
System.out.println("PACKET RECEIVED!");
System.out.println(new String(receivePacket.getData()));
} catch (IOException e) {
e.printStackTrace();
}
c.close();
}
}
When I run this code on my development laptop (and I'm on a wireless network with that STB) the STB responds.
However, I have another laptop setup to pretend to be another STB on the same network(mock STB).
The "mock" STB simply refuses to pick up the broadcasts requests and I'm stuck.
Here's some code I use to act as the mock STB. I've tried various combinations of ports but nothing works.
public class MockBox {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
socket.setBroadcast(true);
while (true) {
System.out.println(">>>Ready to receive broadcast packets!");
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
socket.receive(packet); // blocks
// Packet received
System.out.println(">>>Packet received from " + packet.getAddress().getHostAddress());
System.out.println(">>>Packet data: " + new String(packet.getData()));
socket.close();
}
}
}
Any help appreciated!

Disable the software firewall.
Use MulticastSocket instead of DatagramSocket. (Note: The address you specified above is a multicast address.)
Use TTL of at least 1. If that doesn't work, use 2. Repeat, but don't go above say 4 or 5 on a LAN, because at that point, you're already past reasonable. (Zero won't leave the machine. Using a value too high may cause the packet to be discarded somewhere along the route.)

Related

When we receive packets from an UDP server, why do we have to receive them in a seperate thread?

So my application is a very simple. If you type something through the scanner it sends it over to the server, the server sends it back to client. However, i don't understand why we have to put our code where we handle our receiving packets from the server into a thread?
The code below works fine but if i don't use use multithreading then the application doesn't work. The part where i send packets also stop working. Could you explain why this happens?
public class Client {
private static DatagramSocket socket = null;
public static void main(String[] args) {
System.out.println("Send to server:");
Scanner scanner = new Scanner(System.in);
while (true) {
try {
// port shoudn't be the same as in TCP but the port in the datagram packet must
// be the same!
socket = new DatagramSocket();
} catch (SocketException e1) {
System.out.println("[CLIENT] Unable to initiate DatagramSocket");
}
InetAddress ip = null;
try {
ip = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
System.out.println("[CLIENT] Unable to determine server IP");
}
// must be in a while loop so we can continuously send messages to server
String message = null;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
receive();
}
});
thread.start();
while (scanner.hasNextLine()) {
message = scanner.nextLine();
byte[] buffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, ip, 6066);
try {
socket.send(packet);
} catch (IOException e) {
System.out.println("[CLIENT] Unable to send packet to server");
}
}
}
}
private static void receive() {
// receiving from server
byte[] buffer2 = new byte[100];
DatagramPacket ps = new DatagramPacket(buffer2, buffer2.length);
while (true) {
try {
socket.receive(ps);
} catch (IOException e) {
System.out.println("[CLIENT] Unable to receive packets from server.");
}
System.out.println("[SERVER] " + new String(ps.getData()));
}
}
}
If you type something through the scanner it sends it over to the
server, the server sends it back to client.
So the main method runs on the main thread and does some job. The job that you just referenced.
Read some user input plus the following part
while (scanner.hasNextLine()) {
message = scanner.nextLine();
byte[] buffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, ip, 6066);
try {
socket.send(packet);
} catch (IOException e) {
System.out.println("[CLIENT] Unable to send packet to server");
}
}
Title: receive packets from an UDP server
You want to receive packets but you don't want to block the user from typing something as input and sending it to the server.
Therefore you need to do 2 jobs simultaneously. AKA multithreading

Running server and clients on one machine (netbeans 8.1)

I have a problem to run a server and clients in one (mac) machine. I can run the server but when I run the client it give me an error java.net.BindException: Address already in use
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
as far as I know that there is somthing call ssh that need to be used but I don't know how to use it to do solve this.
Thanks
public class WRRCourseWork {
public static void main(String[] args) {
try {
DatagramSocket IN_socket = new DatagramSocket(3000);
DatagramSocket OUT_socket = new DatagramSocket(5000);
IN_socket.setSoTimeout(0);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
//recive the message
IN_socket.receive(packet);
String message = new String(buffer);
System.out.println("Got message: " + message.trim());
// send the message
String host = "";
InetAddress addr = InetAddress.getByName(host);
DatagramPacket OUT_Packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 5000);
OUT_socket.send(OUT_Packet);
System.out.println("Sending Message: "+ message.trim());
}
} catch (Exception error) {
error.printStackTrace();
}
}
...
public class Messages {
public static void main(String [] args) {
System.out.println("hiiiiiii");
//String host = "localhost";
try {
while (true) {
InetAddress addr = InetAddress.getLocalHost();
String message = "Hello World";
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 4000);
DatagramSocket socket = new DatagramSocket(4000);
socket.send(packet);
//socket.close();
}
} catch(Exception error) {
// catch all errors
error.printStackTrace();
}
}
}
There are a few things that you might want to change here:
1) You are sending a UDP packet on port 4000 from your client but listening on port 3000 in your server(receiver) code. Ports should be same.
2) There might be another instance of your server code running in another Netbeans tab or from your terminal may be, which is already bound to the port. Please ensure that you have only one instance running for your server code. This will resolve your 'Address already in use error'
3) I also added 'Thread.sleep(500)' in the client(sender) code in the infinite while loop that you have set up. Without this, the code was ending up with a 'Bad File Descriptor' error on my machine. Probably it was a conflict with the Socket handle running into a problem with the infinite loop in place.
With these changes, data exchange between client and server is working fine.

Why does my UDP connection stop working?

After creating an UDP connection and connecting from the client to the server, it stops working randomly. Why is this happening?
This doesn't usually happen when running the client and the server on the same computer using "localhost" as the IP, but when using different computers on the same network it happens.
When I try and connect using different computers at first it works but after some time it just stops; the connection is "terminated".
Also, ignore the game.player stuff, it is just a player of mine.
This is my code:
Client:
public class GameClient extends Thread {
private InetAddress ipAddress;
private DatagramSocket socket;
private Main game;
public GameClient(Main main, String ipAddress) {
this.game = main;
try {
this.socket = new DatagramSocket();
this.ipAddress = InetAddress.getByName(ipAddress);
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
try {
socket.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
String message = new String(packet.getData());
message = message.trim();
if (message.startsWith("00")) {
System.out.println("Player connected. Got server response...");
String msg = "01" + game.player.getPos();
sendData(msg.getBytes());
}
if (message.startsWith("01")) {
message = message.substring(2);
List<String> coords = Arrays.asList(message.split(","));
game.updateMP(coords);
String msg = "01" + game.player.getPos();
sendData(msg.getBytes());
}
}
}
public void sendData(byte[] data) {
DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress,
1331);
try {
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
My server class:
public class GameServer extends Thread {
private DatagramSocket socket;
private Main game;
public GameServer(Main main) {
this.game = main;
try {
this.socket = new DatagramSocket(1331);
} catch (SocketException e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
try {
socket.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
String message = new String(packet.getData());
message = message.trim();
if (message.startsWith("00")) {
message = message.substring(2);
game.playerConnected = true;
sendData("00".getBytes(), packet.getAddress(), packet.getPort());
}
if (message.startsWith("01")) {
message = message.substring(2);
List<String> coords = Arrays.asList(message.split(","));
game.updateMP(coords);
String msg = "01" + game.player.getPos();
sendData(msg.getBytes(), packet.getAddress(), packet.getPort());
}
}
}
public void sendData(byte[] data, InetAddress ipAddress, int port) {
DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress,
port);
System.out.println(ipAddress + ", " + port);
try {
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
And my "Main" class:
(just a part of it):
if (JOptionPane.showConfirmDialog(null, "Do you want to run the server?") == 0) {
socketServer = new GameServer(this);
socketServer.start();
socketType = 0;
} else {
socketClient = new GameClient(this, JOptionPane.showInputDialog(null, "IP:"));
socketClient.start();
socketClient.sendData("00".getBytes());
socketType = 1;
}
Looks like you have a packet flow without any delays. My suspicion is, that this mass of packets just overflows the network, thus breaking the "connection" (UDP is connectionless).
Let's break the packet flow down:
Server thread is created (constructor), binding to port 1331 (UDP).
Server thread starts, first step: listen on socket (blocking).
Client thread is created, binds to a random (free) port.
Client thread is started, first step: listen on socket (blocking).
Main thread calls sendData("00") on client, which works fine of course.
Server thread receives the "00" packet, sets playerConnected to true and sends "00" back (to inform the client of successful connection to the game). Then server listens again on the socket.
Client thread receives the "00" packet, and sends a "01..." packet. Client listens again on socket.
Server thread receives the "01" packet, updates its game object and sends a "01" packet back to the client (with no delay).
Client thread receives the "01" packet, updates its game object and sends a "01" packet back (with no delay)
The last two steps repeat indefinitely, with no delay.
On the same computer it works better, because the loopback interface is virtual and can handle much more packets per second, so the overflow happens later than on a real network.
Updating a position of a player in a network game is an issue as old as network games. There are many articles on that topic. Search e.g. for "client side position prediction" or sth. like "online game compensate latency", read the Quake2 source code (https://github.com/id-Software/Quake-2/blob/master/client/cl_pred.c) etc.
Beside of that: avoid using Strings, avoid creating tons of new byte arrays, for performance. In Java you will be punished by the Garbage Collector.

Remote client doesn't receive UDP packets

I have simple UDP server/client program, I forwarded my ports and server receives and sends packets via internet,but the client on the remote machine cant receive them,so im wondering how to receive packets without forwarding ports on client side(if its even possible)? And if its not possible , what should i do to make client to receive UDP packets via internet?
Client receive thread looks like this :
public void run(){
DatagramSocket serverSocket = null;
while(true){
try {
serverSocket = new DatagramSocket(7000+clientNumber+100);
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte[] receiveData = new byte[1024];
DatagramPacket receiveX = new DatagramPacket(receiveData, receiveData.length);
try {
serverSocket.receive(receiveX);
} catch (IOException e) {
System.out.println("Nepagavau paketo");
}
String korX = new String( receiveX.getData());
Play.priesoX = Float.parseFloat(korX);
serverSocket.close();
}
You don't need to do port forwarding for the client side, NAT takes care of that automatically.
http://en.wikipedia.org/wiki/Network_address_translation
Your client might not be reachable for different reasons (firewall, etc.).

Java - UDP and Multicast detection

On a single port I want to listen for Multicast, UDP, and TCP traffic. (on my LAN)
I also want to respond via UDP, if something is detected.
The code works below, but only for Multicast detection. The while(true) loop is definitely doing it just, from the main().
But I'm running into a wall with adding another protocol detection method.
Can a single application have multiple sockets open, in multiple protocols?
I'm sure it's my limited knowledge of threading, but maybe someone can see my hiccup below.
public class LANPortSniffer {
private static void autoSendResponse() throws IOException {
String sentenceToSend = "I've detected your traffic";
int PortNum = 1234;
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("192.168.1.121");
byte[] sendData = new byte[1024];
sendData = sentenceToSend.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, PortNum);
clientSocket.send(sendPacket);
clientSocket.close();
}//eof autoSendResponse
private static void MulticastListener() throws UnknownHostException {
final InetAddress group = InetAddress.getByName("224.0.0.0");
final int port = 1234;
try {
System.out.println("multi-cast listener is started......");
MulticastSocket socket = new MulticastSocket(port);
socket.setInterface(InetAddress.getLocalHost());
socket.joinGroup(group);
byte[] buffer = new byte[10*1024];
DatagramPacket data = new DatagramPacket(buffer, buffer.length);
while (true) {
socket.receive(data);
// auto-send response
autoSendResponse();
}
} catch (IOException e) {
System.out.println(e.toString());
}
}//eof MulticastListener
// this method is not even getting launched
private static void UDPListener() throws Exception {
DatagramSocket serverSocket = new DatagramSocket(1234);
byte[] receiveData = new byte[1024];
System.out.println("UDP listener is started......");
while(true)
{
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
System.out.println("UDP RECEIVED: " + sentence);
}
}
public static void main(String[] args) throws Exception {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
try {
MulticastListener();
} catch (UnknownHostException e) {
e.printStackTrace();
}
// this does not appear to be detected:
try {
UDPListener();
} catch (Exception e) {
e.printStackTrace();
}
}
}//eof LANPortSniffer
In main(), I tried adding a second try/catch, for a simple UDPListener() method.
But it seems to be ignored when I run the application in Eclipse.
Does the main() method only allow for one try/catch?
In a nutshell, I'd like to listen on a single port for Multicast, UDP, and TCP packets all at the same time. Is this possible?
Your getting into a Threading issue here. I think you need to brush up on understanding of Java. When you call MulticastListener() it will never leave that block until your connection fails. It has a continous while loop. You need to create a new Thread for each of these activities.
Thread t = new Thread(new Runnable() {
public void run() {
MulticastListener();
}
}
t.start();
However I recommend you read up on your understanding of the programs flow and use of a more object orientated approach before you start trying to implement a threaded program.
1) You'll need raw socket access, which you won't get with a MulticastListener.
2) Look-up Promiscuous Mode and Raw Sockets in Java.
3) Threading issues are irrelevant - they will only give you better reactive performance - suggest you get it working with one thread before you improve your code.

Categories

Resources