I have two following classes (including only main methods for simplicity)
public class UDPServer {
public static void main(String[] args) throws IOException {
int serverPort = 9876;
DatagramSocket socket = new DatagramSocket(serverPort);
byte[] buffer = new byte[1024];
boolean isConnected = true;
while (isConnected) {
try {
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
socket.receive(request);
DatagramPacket reply = new DatagramPacket(
request.getData(),
request.getLength(),
request.getAddress(),
request.getPort()
);
socket.send(reply);
} catch (IOException ex) {
isConnected = false;
Logger.getLogger(UDPServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class UDPClient {
public static void main(String[] args) {
String pathToQuery = getUserInput();
List<Packet> queried = UDPServer.getQueriedServerDataTypes(pathToQuery);
try {
if (args.length < 1) {
System.out.println("Usage: UDPCLient <msg> <server host name>");
System.exit(-1);
}
// Create a new datagram socket
DatagramSocket socket = new DatagramSocket();
// Preferred IPv4 address (cmd: ipconfig/all)
InetAddress host = InetAddress.getByName(args[0]);
int serverPort = 9876;
for (int i = 0; i < queried.size(); i++) {
Packet dataType = queried.get(i);
String requestFile = "data_type_request_v" + (i + 1) + ".txt";
UDPServer.saveToFile(
dataType,
"Server request.",
requestFile
);
// Serialize Packet object to an array of bytes
byte[] data = Tools.serialize(dataType);
System.out.println("Sent: " + Arrays.toString(data));
// Request datagram packet will store data query for the server
DatagramPacket request = new DatagramPacket(
Objects.requireNonNull(data),
data.length,
host,
serverPort
);
// Send serialized datagram packet to the server
socket.send(request);
// The reply datagram packet will store data returned by the server
DatagramPacket reply = new DatagramPacket(data, data.length);
System.out.println("Reply: " + Arrays.toString(reply.getData()));
// Acquire data returned by the server
socket.receive(reply);
// Store deserialized data in null Packet object.
Packet read = (Packet) Tools.deserialize(data);
System.out.println("Reading deserialized data...\n" + read.toString());
String responseFile = "data_type_response_v" + (i + 1) + ".txt";
UDPServer.saveToFile(
read,
"Server response.",
responseFile
);
boolean isResponseEqualRequest = UDPServer.isResponseEqualRequest(
requestFile,
responseFile
);
if (isResponseEqualRequest) {
System.out.println("Communication successful. Server response corresponds to the request.");
} else {
System.out.println("Communication unsuccessful. Server response does not correspond to the request.");
}
}
// Close the datagram socket
socket.close();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(UDPClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
In order for the UDPClient to work properly, UDPServer has to be running in the background. I want to run the UDPServer.main() in parallel thread and as soon as UDPClient.main() finishes, the thread should terminate as well.
How do I do that?
Related
I want to send/receive messages by the multicast socket.
This is my code
'''
public class MulticastSender {
public static final String GROUP_ADDRESS = "230.0.0.1";
public static final int PORT = 7766;
public static void main(String[] args) throws InterruptedException {
DatagramSocket socket = null;
try {
// Get the address that we are going to connect to.
InetAddress address = InetAddress.getByName(GROUP_ADDRESS);
System.out.println("GROUP_ADDRESS: " + address);
// Create a new Multicast socket
socket = new DatagramSocket();
DatagramPacket outPacket = null;
long counter = 0;
while (true) {
String msg = "Sent message No. " + counter;
counter++;
outPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, address, PORT);
socket.send(outPacket);
System.out.println("Server sent packet with msg: " + msg);
Thread.sleep(1000); // Sleep 1 second before sending the next message
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (socket != null) {
socket.close();
}
}
}
'''
'''
public class MulticastReceiver {
public static final byte[] BUFFER = new byte[4096];
public static void main(String[] args) {
MulticastSocket socket = null;
DatagramPacket inPacket = null;
try {
// Get the address that we are going to connect to.
SocketAddress address = new InetSocketAddress(MulticastSender.GROUP_ADDRESS, MulticastSender.PORT);
// Create a new Multicast socket
socket = new MulticastSocket(address);
socket.joinGroup(address, NetworkInterface.getByName("eth0"));
while (true) {
// Receive the information and print it.
inPacket = new DatagramPacket(BUFFER, BUFFER.length);
socket.receive(inPacket);
// System.out.println(socket.getInterface());
String msg = new String(BUFFER, 0, inPacket.getLength());
System.out.println("From " + inPacket.getAddress() + " Msg : " + msg);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
'''
It is working on my local host. however, I want to send messages from my AWS server instance (with public ipv4) and receive them in the local client. How to do it?
if yes, please give me an example!
Tks all
My listener ->
public void startListening(){
String[] details = session.split(":");
SessionUser user = new SessionUser();
System.out.println("Waiting for another user..");
listening = new Thread("listen thread"){
public void run() {
while(true) {
while (user.users < 2) {
try {
Socket socket1 = socket.accept();
System.out.println(socket1.getInetAddress().toString() + " has joined...");
user.users++;
socket1.close();
} catch (Exception e) {
System.out.println("Ran into a error!");
}
}
}
}
};
listening.start();
}
My sender ->
public void join(InetAddress address, int port){
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
try {
DatagramSocket socket = new DatagramSocket();
System.out.println("Attempting to join session <" + address.toString() + ":" + port + ">!");
socket.send(packet);
System.out.println("Joining......");
}catch (Exception e){
System.out.println("Unable to connect, this may be a server error, or you've entered incorrect details!");
}
}
So i just want to send packets to the hosts server upon connecting, however, when i run this i am not seeing any sort of output, here is a picture that will probably explain it better then i can -> click me
Change your server to receive the packets as well
DatagramSocket serverSocket = new DatagramSocket(port);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
serverSocket.receive(packet); // This will block until a packet is received
System.out.println("Received: " + new String(packet.getData()));
Try testing with your client
public void join(InetAddress address, int port){
byte[] data = "Hello".getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
try {
DatagramSocket socket = new DatagramSocket();
System.out.println("Attempting to join session <" + address.toString() + ":" + port + ">!");
socket.send(packet);
System.out.println("Joining......");
}catch (Exception e){
System.out.println("Unable to connect, this may be a server error, or you've entered incorrect details!");
}
}
If you need to maintain a connection, it's better to use TCP with Sockets.
In your receiver, you're reading from a TCP socket, whereas your sender is sending an UDP packet. This cannot work.
I'm studying java network programming now and i wrote a program that the client sends 30 times current time to Server and the Server will create a new thread to parse the received UDP packet and give feedback to Client if Server receives the UDP packet.
The question is, after I run my code, the Server can receive the UDP packet and create a new thread, but it seems like DatagramSocket and DatagramPacket don't pass to the thread. Thence the thread can't give a feedback to Client and Client will wait all the time after send the first UDP packet.
My code is here:
Server
public class MulUDPServer {
public static void main(String[] args) {
DatagramSocket socket = null;
DatagramPacket receivedPacket;
final int PORT = 10010;
byte[] b = new byte[1024];
receivedPacket = new DatagramPacket(b, b.length);
try {
socket = new DatagramSocket(PORT);
System.out.println("Server start!");
while (true) {
// receive the packet from server
socket.receive(receivedPacket);
// to check if Server get the packet
System.out.println(new String(receivedPacket.getData(), 0, receivedPacket.getLength()));
// start the thread to handle the packet we have got
Thread thread = new Thread(new LogicThread(socket, receivedPacket));
thread.start();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// close the connection
socket.close();
} catch (Exception e) {
}
}
}
Thread
public class LogicThread implements Runnable {
DatagramSocket socket = null;
DatagramPacket receivedPacket = null;
public LogicThread(DatagramSocket socket, DatagramPacket receivedPacket) {
this.socket = socket;
this.receivedPacket = receivedPacket;
}
public void run() {
try {
// to test if a thread have been set up
System.out.println("a thread have been set up");
byte[] data = receivedPacket.getData();
int len = receivedPacket.getLength();
// get the client IP
InetAddress clientAddress = receivedPacket.getAddress();
// get the client port
int clientPort = receivedPacket.getPort();
// print the info about received packet
System.out.println("Client's IP:" + clientAddress.getHostAddress());
System.out.println("Client's port:" + clientPort);
System.out.println("The info:" + new String(data, 0, len));
// feedback to Client
byte[] b = "OK".getBytes();
DatagramPacket sendPacket = new DatagramPacket(b, b.length, clientAddress, clientPort);
// send
socket.send(sendPacket);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client
public class MulUDPClient {
public static void main(String[] args) {
DatagramSocket socket = null;
DatagramPacket sendPacket;
DatagramPacket receivedPacket;
String serverHost = "localhost";
int serverPort = 10010;
try {
socket = new DatagramSocket();
InetAddress address = InetAddress.getByName(serverHost);
byte[] b = new byte[1024];
receivedPacket = new DatagramPacket(b, b.length);
System.out.println("Client ready!");
for (int i = 0; i < 30; i++) {
// get the current time
Date d = new Date();
String content = d.toString();
byte[] data = content.getBytes();
sendPacket = new DatagramPacket(data, data.length, address, serverPort);
socket.send(sendPacket);
System.out.println("already send time");
Thread.sleep(10);
// receive packet from Server
socket.receive(receivedPacket);
byte[] response = receivedPacket.getData();
int len = receivedPacket.getLength();
String s = new String(response, 0, len);
System.out.println("the feedback from Server:" + s);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// close the connection
socket.close();
} catch (Exception e) {
}
}
}
}
the **Result** after run the Server and Client separately in two terminals:
Server
Server start!
Fri Nov 23 14:52:02 CST 2018
a thread have been set up
Client
Client ready!
already send time
From the result we can know, the Client have send a UDP packet and the Server parse it correctly and create a thread. Then the program is waiting...
It puzzle me a few days, Can anyone help me to solve it? :). Thanks!
Edit
Client
**CAN NOT** work
for (int i = 0; i < 30; i++) {
Thread writerWorker = new WriterWorker(socket);
writerWorker.start();
Thread readerWorker = new ReaderWorker(socket);
readerWorker.start();
}
**CAN** work
for (int i = 0; i < 30; i++) {
Date d = new Date();
String content = d.toString();
byte[] data = content.getBytes();
sendPacket = new DatagramPacket(data, data.length, address, serverPort);
socket.send(sendPacket);
Thread.sleep(10);
Thread readerWorker = new ReaderWorker(socket);
readerWorker.start();
}
WriterWorker
public class WriterWorker extends Thread {
DatagramSocket socket;
String serverHost = "localhost";
int serverPort = 10000;
DatagramPacket sendPacket;
public WriterWorker(DatagramSocket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
InetAddress address = InetAddress.getByName(serverHost);
Date d = new Date();
String content = d.toString();
byte[] data = content.getBytes();
sendPacket = new DatagramPacket(data, data.length, address, serverPort);
socket.send(sendPacket);
System.out.println("already send time");
} catch (Exception e) {
// TODO: handle exception
}
}
}
there is a flaw in your logic, when you do socket.receive(receivedPacket); this will let the worker wait until some datagramm packets does arrive...
the right way to handle asynchron communication via sockets would be the following (here an example for client side)
socket = new DatagramSocket();
Thread readerWorker = new ReaderWorker(socket);
readerWorker.start();
Thread writerWorker = new WriterWorker(socket);
writerWorker.start();
that way you would seperate reading and writing into different threads and the blocking methode socket.receive(...) would not stop your writing thread...
each worker would implement it's own worker loop
writer loop:
while(true){
if (sendPacket!= null){
socket.send(sendPacket);
}
Thread.sleep(10);
}
reader loop:
while(true){
socket.receive(receivedPacket);
handlePacket(receivedPacket);
}
NOTE:
that code was written totally out of my mind i didn't check proper syntax
delete the "Thread.sleep(10)" in client
I have a UDP multicast server listening on 2 sockets on 2 different ports. I achieved listening on these 2 sockets from clients. But i want to identify on which socket a client is sending a packet. Since my problem is that ; on the server if I listen on socket(9999) and if the client is sending on socket(8888) then at the server side I want it to identify the incoming packet is from which port.
public class MulticastReceiver
{
public static void main(String[] args)
{
MulticastSocket socket = null;
DatagramPacket packet = null;
MulticastSocket soc = null;
byte[] inBuf = null;
try
{
socket = new MulticastSocket(8888);
soc = new MulticastSocket(9999);
InetAddress address = InetAddress.getByName("224.2.2.3");
socket.joinGroup(address);
soc.joinGroup(address);
System.out.println("224.2.2.3 ready to receive packets");
while(true)
{
inBuf=new byte[256];
packet = new DatagramPacket(inBuf,inBuf.length);
System.out.println("port is: "+ packet.getAddress() + packet.getPort());
if(packet.getPort() == 9999)
{
soc.receive(packet);
//System.out.println("Data at 224.2.2.3:: " + new String(packet.getData()));
}
else
socket.receive(packet);
System.out.println("Data at 224.2.2.3:: " + new String(packet.getData()));
}
}
catch(Exception e)
{
}
}
}
public class MulticastSender {
public static void main(String[] args) {
DatagramSocket socket = null;
DatagramPacket outPacket = null;
byte[] outBuf;
final int PORT = 8888;
try {
socket = new DatagramSocket();
long counter = 0;
String msg;
msg = "This is multicast! ";
outBuf = msg.getBytes();
//Send to multicast IP address and port
InetAddress address = InetAddress.getByName("224.2.2.3");
outPacket = new DatagramPacket(outBuf, outBuf.length, address, PORT);
socket.send(outPacket);
System.out.println("Server sends : " + msg);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
} catch (IOException ioe) {
System.out.println(ioe);
}
}
}
public class AnotherSender {
public static void main(String[] args) {
DatagramSocket socket = null;
DatagramPacket outPacket = null;
byte[] outBuf;
final int PORT = 9999;
try {
socket = new DatagramSocket();
long counter = 0;
String msg;
msg = "This is another multicast! " + counter;
counter++;
outBuf = msg.getBytes();
//Send to multicast IP address and port
InetAddress address = InetAddress.getByName("224.2.2.3");
outPacket = new DatagramPacket(outBuf, outBuf.length, address, PORT);
socket.send(outPacket);
System.out.println("Server sends : " + msg);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
} catch (IOException ioe) {
System.out.println(ioe);
}
}
}
Your code doesn't make sense. The packet won't have a port number at all until you put one into it or receive() does, and at best this will just read alternately between the two sockets, blocking each time, possibly forever, receiving from one socket, and thus starving the other one.
You need a receiving thread for each non-blocking socket.
I'm trying to allow clients that connect to my UDP server to send packets to the server, I have a server running so packets can be sent to the clients, but trying to send packets back via the client to the server seems to create some weird errors.
If I start the server, then open a client, the client will receive the first packet from the server, the client then tries to send the packet to the server, this is received by the server, but then the client throws this error
Exception in thread "main" java.lang.NumberFormatException: For input string: "testing"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.parseDouble(Unknown Source)
at Pong.PongUDPClient.main(PongUDPClient.java:71)
Line 71 will be pointed at in the code
The server console is just printing out the data it should be sending to the client,
Here is the whole code for the server
package Pong;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.Socket;
//This is the actual server
public class PongUDPServerThread extends Thread {
//speed to send data
private long dataSpeed = 10;
private int port = 4447;
private int idPlayer = 0;
private PongModel model;
private PongView view;
private PongPlayerThread players[] = new PongPlayerThread[2];
private MulticastSocket socket = null;
private InetAddress group;
private DatagramPacket packet = null;
private int ID = 1;
public PongUDPServerThread() throws IOException
{
super("PongUDPServerThread");
}
public String rtnInfo()
{
String str;
str = model.getBall().getX() + ":" +
model.getBall().getY() + ":" +
model.getBats()[0].getX() + ":" +
model.getBats()[0].getY() + ":" +
model.getBats()[1].getX() + ":" +
model.getBats()[1].getY();
return str;
}
public void setupPong() throws IOException
{
System.out.println("Pong");
model = new PongModel();
view = new PongView();
new PongController( model, view );
model.addObserver( view ); // Add observer to the model
//view.setVisible(true); // Display Screen
model.makeActiveObject(); // Start play
//start server
socket = new MulticastSocket(port);
InetAddress group = InetAddress.getByName("230.0.0.1");
socket.setReuseAddress(true);
socket.joinGroup(group);
//socket.setReuseAddress(true);
//Inform server user
System.out.println("Server is running");
}
public void run()
{
//Server loop
while(true)
{
//Receive the data
try
{
byte[] receiveBuf = new byte[256];
packet = new DatagramPacket(receiveBuf, receiveBuf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println(received);
}
catch (IOException e)
{
}
try
{
byte[] buf = new byte[256];
//Gather data
buf = rtnInfo().getBytes();
//System.out.println(buf.toString());
//Send data
packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("230.0.0.1"), port);
socket.send(packet);
//Sleep the server
try
{
sleep((long)dataSpeed);
}
catch (InterruptedException e)
{
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
//socket.close();
}
}
Here is the client code
package Pong;
import java.io.*;
import java.net.*;
import java.util.*;
public class PongUDPClient {
private static int port = 4447;
public static void main(String[] args) throws IOException
{
//Setup pong rdy
PongModel model = new PongModel();
PongView view = new PongView();
new PongController( model, view );
model.addObserver( view ); // Add observer to the model
String pos;
model.makeActiveObject(); // Start play
//model.clientModel();
MulticastSocket socket = new MulticastSocket(port);
//socket.setReuseAddress(true);
InetAddress address = InetAddress.getByName("230.0.0.1");
//Join the UDP list port
socket.setReuseAddress(true);
socket.joinGroup(address);
DatagramPacket packet;
view.setVisible(true); // Display Screen
System.out.println("Connected");
//Id is sent here.
while(true)
{
//Send data to server
try
{
byte[] receiveBuf = new byte[256];
//Gather data
receiveBuf = "testing".getBytes();
//System.out.println(buf.toString());
//Send data
packet = new DatagramPacket(receiveBuf, receiveBuf.length, InetAddress.getByName("230.0.0.1"), port);
socket.send(packet);
//Sleep the server
}
catch (IOException e)
{
e.printStackTrace();
}
byte[] buf = new byte[256];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
//System.out.println("Server data: " + received);
String[] posValues = received.split(":");
model.getBall().setX(Double.parseDouble(posValues[0])); // <-- Line 71
model.getBall().setY(Double.parseDouble(posValues[1]));
model.getBats()[0].setX(Double.parseDouble(posValues[2]));
model.getBats()[0].setY(Double.parseDouble(posValues[3]));
model.getBats()[1].setX(Double.parseDouble(posValues[4]));
model.getBats()[1].setY(Double.parseDouble(posValues[5]));
//Check for keyboard input
if(PongController.moveUp == true && PongController.moveDown == false)
{
System.out.println("Up");
PongController.moveUp = false;
}
else if(PongController.moveUp == false && PongController.moveDown == true)
{
System.out.println("Down");
PongController.moveDown = false;
}
else
{
//serverOut.println("nothing");
}
}
}
}
Been stuck on this for awhile, and can't seem to find any tutorials on how to send packets from client to server using Multicast.
You are experiencing multicast loopback. Turn it off with MulticastSocket#setLoopbackMode(true), or, if that peer is just sending to the multicast group, not receiving, it doesn't need to join the group at all.