Does a UDP connection require a server/client? - java

I want to send out a UDP packet/message out to another device on the same ethernet connection, but I'm not sure where a server/client relationship would be here.
The receiving message is configured to automatically send a response back upon receiving a message, so both devices would just be communicating to each other...
Am I missing something?
I'm confused because the code I used to send a message from a client to a server has parameters "server ip" and "server port" so I'm not sure if I can 1) just replace the parameters and use the same code and 2) if it's possible, what to put in those parameters, the initial device's port # and ip? Or the second device's?
Thanks!
The code snippet:
new Thread(new Runnable() {
#Override
public void run() {
try {
InetAddress SERVERIP = InetAddress.getByName(SERVER_IP);
DatagramSocket socket = new DatagramSocket();
socket.setBroadcast(true);
byte[] msg = message.getBytes();
DatagramPacket packet = new DatagramPacket(msg, message.length(),
SERVERIP, SERVERPORT);
socket.send(packet);
socket.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}).start();

I'm not entirely sure if the question you want answered is how to respond to the device that sent the message from the device that received the message.
If this is the case then the following code is a basic example of how you could respond to the initial sender device by getting the address and port from the packet that was received over the socket.
// Receive and respond thread.
new Thread(new Runnable() {
#Override
public void run() {
try {
// Receive
DatagramSocket socket = new DatagramSocket(4445);
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// Respond
// Get sender's/return address from the packet that was received.
InetAddress address = packet.getAddress();
// Get sender's/return port from the packet that was received.
int port = packet.getPort();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
socket.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}).start();
I would also recommend reading the following documentation regarding writing a datagram server and client.

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.

MulticastSocket receives message twice

I send messages to WIFI Access Point via MulticastSocket and get replies always twice. If I try to send message to me self, I get message twice again. This is my receiver code:
protected Void doInBackground(Void... params) {
String lText;
byte[] lMsg = new byte[GlobalConfig.MAX_UDP_DATAGRAM_LEN];
DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length);
MulticastSocket ds = null;
try {
ds = new MulticastSocket (32001);
InetAddress serverAddr = InetAddress.getByName("224.237.124.120");
ds.joinGroup(serverAddr);
while (serverActive) {
ds.receive(dp);
Log.d("UDP packet received", dp.toString());
lText = new String(lMsg, 0, dp.getLength());
receivedMessage = lText;
doSomething();
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
return null;
}
I tried to send via DatagramSocket and via MulticastSocket - no matter. I get messages alway twice. I don't understand why!
EDIT: my LogCat:
I/GatewayController﹕ Message Sent
...
D/UDP packet received﹕ java.net.DatagramPacket#422dc860
D/UDP packet received﹕ java.net.DatagramPacket#422dc860
EDIT2: Sender code
protected Void doInBackground(Void... params) {
DatagramSocket ds = null;
try {
ds = new DatagramSocket();
InetAddress serverAddr = InetAddress.getByName("224.237.124.120");
DatagramPacket dp;
dp = new DatagramPacket(byteMsg, byteMsg.length,
serverAddr, 32000);
ds.send(dp);
I tried to send via DatagramSocket and via MulticastSocket - no matter. I get messages alway twice. I don't understand why!
EDIT: my LogCat:
I/GatewayController﹕ Message Sent ...
D/UDP packet received﹕ java.net.DatagramPacket#422dc860 D/UDP packet received﹕ java.net.DatagramPacket#422dc860
This is not evidence that you received the same message twice. It is evidence that you always receive into the same byte array. Try logging the message content.
However multicast is UDP, and UDP does not guarantee delivery, or single delivery, or sequenced delivery, so it remains possible you will get duplicates. If that's semantically important, you need to detect it via sequence numbers.
Here is the right way:
InetAddress group = InetAddress.getByName(GlobalConfig.MULTICAST_IP);
SocketAddress sockaddr = new InetSocketAddress(group,GlobalConfig.LOCAL_PORT);
ds = new MulticastSocket(sockaddr);
ds.joinGroup(group);
This is important, but difficult to find in examples in Internet:
SocketAddress sockaddr = new InetSocketAddress(group,GlobalConfig.LOCAL_PORT);
ds = new MulticastSocket(sockaddr);

Java UDP respond to broadcast request

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.)

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.).

Categories

Resources