I need to write a Java program that can catch UDP packets. I wrote a basic UDP Receiver program but I am unsure how to adjust it for this purpose.
import java.io.*;
import java.net.*;
public class BasicReceiver {
public static void main(String[] args) {
int port = args.length == 0 ? 57 : Integer.parseInt(args[0]);
new BasicReceiver().run(port);
}
public void run(int port) {
try {
DatagramSocket serverSocket = new DatagramSocket(port);
byte[] receiveData = new byte[8];
String sendString = "polo";
byte[] sendData = sendString.getBytes("UTF-8");
System.out.printf("Listening on udp:%s:%d%n",
InetAddress.getLocalHost().getHostAddress(), port);
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
while(true)
{
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData(), 0,
receivePacket.getLength() );
System.out.println("RECEIVED: " + sentence);
// now send acknowledgement packet back to sender
InetAddress IPAddress = receivePacket.getAddress();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
IPAddress, receivePacket.getPort());
serverSocket.send(sendPacket);
}
} catch (IOException e) {
System.out.println(e);
}
// should close serverSocket in finally block
}
}
I am not receiving any packets but I can see packets on my Ethernet Port:
WireShark Snapshot
Related
I want to create a datagram server/client program where the server picks a random string from an array and send it to the client. But when i run the server and then the client which sends data about the buf byte array. The client sends the data to the serve as I understand but the server doesn't receive it.
Here's the client code:
import java.io.*;
import java.net.*;
import java.util.*;
public class SDClient {
protected static String labelText;
public static void main(String[] args) throws IOException {
//socket setup
MulticastSocket socket = new MulticastSocket(1);
System.out.println("socket opened");
InetAddress group = InetAddress.getByName("230.0.0.0");
socket.joinGroup(group);
System.out.println("socket joined group");
//packet setup
DatagramPacket packet;
byte[] buf = new byte[256];
//send packet
packet = new DatagramPacket(buf, buf.length);
packet.setAddress(group);
packet.setPort(2);
socket.send(packet);
System.out.println("packet sent to: ");
System.out.println("Port: " + packet.getPort() + " Address: " + packet.getAddress());
//receive packet
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
System.out.println("packet received");
//display packet string
labelText = new String(packet.getData(), 0, packet.getLength());
System.out.println("label text: " + labelText);
socket.leaveGroup(group);
socket.close();
}
}
here's the server code:
import java.io.*;
import java.net.*;
import java.util.*;
public class SDServerThread extends Thread {
protected DatagramSocket socket = null;
protected String[] labelText = {"Packet sent and received", "Hello World!", "It works."};
public SDServerThread() throws IOException {
this("SDServerThread");
}
public SDServerThread(String name) throws IOException {
super(name);
socket = new DatagramSocket(2);
System.out.println("socket opened");
}
public void run() {
try {
byte[] buf = new byte[256];
DatagramPacket packet = null;
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
System.out.println("packet received");
String getText = getText();
buf = getText.getBytes();
InetAddress group = InetAddress.getByName("230.0.0.0");
packet = new DatagramPacket(buf, buf.length, group, 1);
socket.send(packet);
System.out.println("packet sent");
} catch (IOException e) {
e.printStackTrace();
}
}
private String getText() {
int textNr = (int)(Math.random() * 3);
String returnT = labelText[textNr];
return returnT;
}
}
Thanks in advence
I fixed it by making the servers DatagramSocket into a MulticastSocket and then made it join the group the client is in.
public class SDServerThread extends Thread {
protected MulticastSocket socket = null;
...
socket = new MulticastSocket(2);
...
socket.joinGroup(group);
}
I'm try use my IOT device with Java, but the Java doesn't receive any UDP packet. My packets are very simple and I belive that this is the problem.
The wireshark listen all the packets and a similar DELPHI software too.
My code:
package br.imply.server;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Main {
public static void main(String[] args) {
try {
int porta = 4865;
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
DatagramSocket serverSocket = new DatagramSocket(porta);
boolean isStopped = false;
InetAddress inetAddress = InetAddress.getLocalHost();
System.out.println("Iniciando servidor: " + inetAddress.getHostAddress() + ":" + porta);
while (!isStopped) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
System.out.println("Aguardando conexão...");
serverSocket.receive(receivePacket);
System.out.println("Conectado em " + receivePacket.getAddress());
String sentence = new String(receivePacket.getData());
System.out.println("received: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
//do something with clientSocket
}
} catch (IOException ex) {
System.out.println(Main.class.getName() + " " + ex);
}
}
}
I'm trying to send a message using a udp client to udp server and send the message back to client with various metadata about the received message.
I have these two classes:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class UdpDateClient {
public static void main(String[] args) throws IOException {
String host = "localhost";
if (args.length > 0)
host = args[0];
// get a datagram socket on any available port
try {
DatagramSocket socket = new DatagramSocket();
// send request
byte[] buf = new byte[2048];
buf="hi it's Max".getBytes();
InetAddress address = InetAddress.getByName(host);
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445);
socket.send(packet);
// get response
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// display response
buf = packet.getData();
int len = packet.getLength();
String received = (new String(buf)).substring(0, len);
System.out.println("From server: " + received);
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Date;
public class UdpDateServer {
private DatagramSocket socket = null;
private boolean moreClients = true;
public static void main(String[] args) {
UdpDateServer server = new UdpDateServer();
server.start();
}
public UdpDateServer() {
try {
socket = new DatagramSocket(4445);
System.out.println("server ready...");
} catch (SocketException e) {
e.printStackTrace();
System.exit(1);
}
}
public void start() {
DatagramPacket packet;
while (moreClients) {
try {
byte[] buf = new byte[2048];
// receive request
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
System.out.println("recieved packet from client: "+new String(packet.getData()));
// prepare response
String responseString = "Client's message received: "+new String(packet.getData())+"\n"
+ "Received on:" +new Date().toString();
buf = responseString.getBytes();
System.out.println("buf to be sent from server: "+(new String(buf)));
System.out.println("buf.length="+buf.length);
// send the response to "address" and "port"
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
moreClients = false;
}
}
socket.close();
}
}
what I get on the client side is only first 11 bytes of the message that is sent by the server:
Client side:
From server: Client's me
Server side:
server ready...
recieved packet from client: hi it's Max
buf to be sent from server: Client's message received: hi it's Max
Received on:Fri Aug 14 16:00:20 IDT 2015
buf.length=2116
As you can see, the message from server that is recieved back by the client is cut after 11 characters.
What am I doing wrong?
The problem is the line buf="hi it's Max".getBytes(); of the client code.
Here you set the buffer length to 11.
Your client code should look like the following
DatagramSocket socket = new DatagramSocket();
// send request
byte[] buf = "hi it's Max".getBytes();
InetAddress address = InetAddress.getByName(host);
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445);
socket.send(packet);
// get response
buf = new byte[2048];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// display response
buf = packet.getData();
int len = packet.getLength();
String received = (new String(buf)).substring(0, len);
System.out.println("From server: " + received);
socket.close();
byte[] buf = new byte[2048];
buf="hi it's Max".getBytes();
after this buf.length will be 11 not 2048!
And on your way back
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
will only receive 11 Bytes because buf.length is 11. Change the first block to something like
byte[] buf = new byte[2048];
System.arraycopy("hi it's Max".getBytes(), 0, buf, 0, 11);
I took code from some sources in internet, here it is:
Server Side:
import java.io.*;
import java.net.*;
class Server {
public static void main(String args[]) throws Exception {
DatagramSocket serverSocket = new DatagramSocket(9876);
serverSocket.setBroadcast(true);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
serverSocket.receive(receivePacket);
//System.out.println(serverSocket.getAddress().getHostAddress());
System.out.println(receivePacket.getAddress().getHostAddress()+" is connected");
String sentence = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("RECEIVED: " + sentence +" from: "+receivePacket.getAddress().getHostAddress());
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
System.out.println("Port: "+port);
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length, IPAddress, port); //
serverSocket.send(sendPacket);
}
}
}
Client1 Side:
import java.io.*;
import java.net.*;
class Client1 {
public static void main(String args[]) throws Exception {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
clientSocket.setBroadcast(true);
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
Boolean status = true;
while(status){
String sentence = "";
sentence = inFromUser.readLine();
if(sentence.equals("exit")){
break;
}
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("FROM SERVER:" + modifiedSentence);
}
clientSocket.close();
}
}
Client2 Side: same as Client1.
My questions are:
how to give notification in Server side which will tell you the client's IP address when a client is connected?
how to broadcast message from one client to the other clients? ex: Client1 sends message to Server, the Server broadcast the message to all of its clients, not only to Client1.
Thank you in advance
I have an UDP send and receive which works in my device Samsung Galaxy Ace Plus (S7500) but the same code doesn't work in other devices, for example Samsung Galaxy S4. I don't have any error.
Send :
public class SendThread extends Thread {
byte[] receiveData = new byte[1024];
DatagramSocket serverSocket = null;
public SendThread() {
this.start();
}
public void run() {
DatagramSocket serverSocket = null;
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
try {
serverSocket = new DatagramSocket("MY SOCKET PORT");
InetAddress IP = InetAddress.getByName("MY IP");
String send= "I am Android";
sendData = send.getBytes();
DatagramPacket send = new DatagramPacket(sendData, sendData.length, IP, "MY SEND PORT");
serverSocket.send(send);
serverSocket.close();
} catch (Exception e) {
}
}
}
Receive :
public class ReceiveThread extends Thread {
byte[] receiveData = new byte[1024];
DatagramSocket serverSocket = null;
boolean isActive = true;
public ReceiveThread() {
this.start();
}
public void run() {
DatagramSocket serverSocket = null;
byte[] receiveData = new byte[1024];
while (isActive) {
try {
serverSocket = new DatagramSocket("MY RECEIVE PORT");
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
serverSocket.close();
} catch (Exception e){
}
}
}
}
This problem ocurred because some devices lock the Datagram receiver because the protocol security implemented by factory.
Your code is not wrong, but you need change the DatagramSocket for MulticastSocket.
For this your need execute some steps:
First, it's needed to add the uses-permission:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
On AmdroidManifest.xml
Second, it's necessary create a MulticastLock; Without this the MulticastSocket is not work properly;
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
Thirdy, replace the DatagramSocket by MulticastSocket. Only on receive methods was needed put the code below or similar:
MulticastSocket ms = new MulticastScoket("Your socket port");
ms.joinGroup("Your IP");
It's not needed any modifies to send messages.
I use the multcast ip equals to 239.255.255.255. Attempt to range of multicast ip because the wrong ip will block the method flow correctly.
Finally, before use MulticastSocket it's needed to execute MulticastLock.acquire(), and after use execute MulticastLock.release();
It could be puted on service, and acquire or release MulticastLock on start or stop service.