i tried my hands on networking and this is the first time i have understood some bit of it.i have a program with a client and server.What i want to do is that the server should send data continuously to a port and whenever there is any data in port say 2656 ,the client should read the data from that port and the data should be flushed from the port.I have created a server program and a client program but the client is not receiving any packet.I m running client and server on two different machines.
Server Program
import java.io.*;
import java.net.*;
public class Server{
public static void main(String args[]) throws Exception {
DatagramSocket dsocket = new DatagramSocket();
try {
String host = "192.168.0.15";
int count =1;
byte[] message = "Java Source and Support".getBytes();
// Get the internet address of the specified host
InetAddress address = InetAddress.getByName(host);
// Initialize a datagram packet with data and address
for(;;)
{
DatagramPacket packet = new DatagramPacket(message, message.length,
address, 2656);
// Create a datagram socket, send the packet through it, //close it.
System.out.println("Sending data"+message.toString();
dsocket.send(packet);
}
} catch (Exception e) {
System.err.println(e);
}
finally
{
dsocket.close();
}
}
}
Client program
package saturdayTest;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPReceive {
public static void main(String args[]) {
try {
int port = 2656;
// Create a socket to listen on the port.
DatagramSocket dsocket = new DatagramSocket(port);
byte[] buffer = new byte[2048];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
System.out.println("Waiting for a packer");
dsocket.receive(packet);
String msg = new String(buffer, 0, packet.getLength());
System.out.println(packet.getAddress().getHostName() + ": "
+ msg);
packet.setLength(buffer.length);
}
} catch (Exception e) {
System.err.println(e);
}
}
}
Related
So in my code below i have a singlethreaded server and a multithreaded client. The reason for this is because i want the client to send packets and receive packets simultaneously. However when i start the server and run multiple clients the server can process multiple clients simultaneously even tough the server is not multithreaded? Can you explain this?
Server:
public class server {
public static void main(String[] args) throws IOException{
new server();
}
//declare the UDP server socket
DatagramSocket datagramSocket;
int port = 3741;
public server() throws IOException {
//create UDP server with a specific port number
datagramSocket = new DatagramSocket(port);
System.out.println("[UDP server] Datagram socket started on port " + port);
//prepare the packet structure for received packets
int dataLength = 100; //must be large enough so some part of packet doesn't get lost
byte[] receiveData = new byte[dataLength];
DatagramPacket packet = new DatagramPacket(receiveData, receiveData.length);
while(true) {
datagramSocket.receive(packet);
System.out.println("client connected");
InetAddress inetAddress = packet.getAddress();
int clientPort = packet.getPort();
byte[] data = packet.getData();
//send response back to the client host
byte[] sendData = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(data, data.length, inetAddress, clientPort);
datagramSocket.send(datagramPacket); //sending data from server to client
}
}
}
Client:
public class client {
public static void main(String[] args) throws Exception {
new client();
}
public client() throws Exception{
DatagramSocket socket = new DatagramSocket();
InetAddress ip = InetAddress.getByName("127.0.0.1");
String message = "hello from client";
DatagramPacket packetSend = new DatagramPacket(message.getBytes(), message.getBytes().length, ip, 3741);
Thread th = new Thread(new Runnable() {
#Override
public void run() {
for(int i = 0; i < 100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
socket.send(packetSend);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
th.start();
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
//this part can't be in a thread because the loop above us will finish first before this starts
//we can put this code before the loop and start a thread this would also work
while(true) {
try {
socket.receive(packet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String data = new String(packet.getData()).trim();
System.out.println(data);
}
}
}
You think "the server can process multiple clients simultaneously even tough the server is not multithreaded" cause your brain cheat you. Acutually they are processing one by one in a reliatively fast speed. It's easy to see if you use wireshark or tcpdump to capture the server side packets. You will find the interesing truth.
I am doing a server and client socket datagram.
The client connects to the server and you need to write in the client a string that contains Hello or hello.
When the server detects a string with hello or Hello, repplies to the client with another string.
The problem is that the client doesn't read the string that the server sends.
Here is my code.
Client
public class Client {
public static void main(String[] args) {
try {
System.out.println("Creando socket datagram");
DatagramSocket datagramSocket = new DatagramSocket();
Scanner myObj = new Scanner(System.in); // Create a Scanner object
System.out.println("Say Hello");
String saludo = myObj.nextLine();
System.out.println("Sending message");
InetAddress addr = InetAddress.getByName("localhost");
DatagramPacket datagrama = new DatagramPacket(saludo.getBytes(), saludo.getBytes().length, addr, 5555);
datagramSocket.send(datagrama);
System.out.println("Message sent");
System.out.println("Reading message");
byte[] mensaje = new byte[25];
DatagramPacket datagrama1 = new DatagramPacket(mensaje, 25);
datagramSocket.receive(datagrama1);
System.out.println("Message recieved: " + new String(mensaje));
System.out.println("Closing");
datagramSocket.close();
System.out.println("FInished");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server
public class Server {
public static void main(String[] args) throws InterruptedException {
try {
for (;;) {
System.out.println("Creating socket datagram");
InetSocketAddress addr = new InetSocketAddress("localhost", 5555);
DatagramSocket datagramSocket = new DatagramSocket(addr);
System.out.println("RReading message");
byte[] mensaje = new byte[25];
DatagramPacket datagrama1 = new DatagramPacket(mensaje, 25);
datagramSocket.receive(datagrama1);
System.out.println("Message recieved: " + new String(mensaje));
if (new String(mensaje).contains("hello") || new String(mensaje).contains("Hello")) {
String quetal = "¿Hello, how are you doing?";
System.out.println("Sending message");
TimeUnit.SECONDS.sleep(2);
DatagramPacket datagrama2 = new DatagramPacket(quetal.getBytes(), quetal.getBytes().length, addr.getAddress(),
5555);
datagramSocket.send(datagrama2);
System.out.println("Message Sent");
}
datagramSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have tried putting a sleep in the server in case the server sends the string before the client tries to read.
Many thanks for the help as always.
The client is using the parameter-less DatagramSocket() constructor to bind to a random port with which to send and receive on:
Constructs a datagram socket and binds it to any available port on the local host machine. The socket will be bound to the wildcard address, an IP address chosen by the kernel.
However, when the server receives a datagram, you are ignoring the IP and port where the datagram was actually sent from:
DatagramSocket.receive(DatagramPacket)
Receives a datagram packet from this socket. When this method returns, the DatagramPacket's buffer is filled with the data received. The datagram packet also contains the sender's IP address, and the port number on the sender's machine.
When the server is sending the reply, you are sending it back to the server itself at localhost:5555, not to the client at all.
On the server side, you need to change this:
DatagramPacket datagrama2 = new DatagramPacket(..., addr.getAddress(), 5555);
To either this:
DatagramPacket datagrama2 = new DatagramPacket(..., datagrama1.getAddress(), datagrama1.getPort());
Or to this:
DatagramPacket datagrama2 = new DatagramPacket(..., datagrama1.getSocketAddress());
On a side note, your server is also ignoring the actual length of the data that is being sent by the client. The server is receiving data using a 25-byte array, but the client may not actually be sending 25 bytes. If the client sends less than 25 bytes, you will end up with a String that contains random garbage on the end of it. And if the client sends more than 25 bytes, `receive() will truncate the data.
Try something more like this instead:
System.out.println("Reading message");
byte[] buffer = new byte[65535];
DatagramPacket datagrama1 = new DatagramPacket(buffer, buffer.length);
datagramSocket.receive(datagrama1);
String mensaje = new String(datagrama1.getData(), datagrama1.getLength());
System.out.println("Message recieved: " + mensaje);
if (mensaje.contains("hello") || mensaje.contains("Hello")) {
...
}
This was fun :)
Kindly keep in mind, the way this is coded might not be the best, however it works as you want.
The Client sends Hello, The server receives Hello, and Sends (Hello back at you).
Both then terminate. It doesnt keep on looping those 2 messages forever, but I showed you the idea.
The Server needs to act as a Client as well in order to send messages.
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 DReceiver{
public static void replyToTheClientListening() throws IOException {
DatagramSocket ds = new DatagramSocket();
String str = "hello back at you";
InetAddress ia = InetAddress.getByName("127.0.0.1");
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), ia, 3001);
ds.send(dp);
ds.close();
}
public static void listenToMessagesFromTheClient() throws IOException {
DatagramSocket ds = new DatagramSocket(3000);
ds.setSoTimeout(60000); //Wait 60 SECONDS for messages
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
ds.receive(dp);
String strRecv = new String(dp.getData(), 0, dp.getLength());
if("hello".equalsIgnoreCase(strRecv)) { //hello in any case
System.out.println("Received a MSG from the Client " + strRecv);
replyToTheClientListening();
}
ds.close();
}
public static void main(String[] args) throws Exception {
listenToMessagesFromTheClient();
}
}
The DSender is a Client but also needs to act as a Server (To Listen to Messages coming in from the other Server)
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 DSender{
public static void actAsAServerAndListenToMessages() throws IOException {
//Listen to Port 3001 --The Server will send to that port
DatagramSocket dsReceive = new DatagramSocket(3001);
dsReceive.setSoTimeout(60000); //Make it wait 60 SECONDS
byte[] buf = new byte[1024];
DatagramPacket dpReceive = new DatagramPacket(buf, 1024);
dsReceive.receive(dpReceive);
String strRecv = new String(dpReceive.getData(), 0, dpReceive.getLength());
System.out.println("Client -- Received a Msg back from Server --" + strRecv);
dsReceive.close();
}
public static void sendAMessageAsAClientToTheServer() throws IOException {
// Client will send a message to Port 3000 which the Server listens to.
DatagramSocket ds = new DatagramSocket();
String str = "hello";
InetAddress ia = InetAddress.getByName("127.0.0.1");
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), ia, 3000);
ds.send(dp);
ds.close();
}
public static void main(String[] args) throws Exception {
sendAMessageAsAClientToTheServer();
actAsAServerAndListenToMessages();
}
}
Reference :
https://www.javatpoint.com/DatagramSocket-and-DatagramPacket
I run the server, then the Client.
Am new to Socket programming am trying to establish a communication between a Server and a client but i don't know how to do that am a bit confused on how to go about it. I have written the program below but it is given error and i can't get my head round why.
package server;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Server {
public static void main(String[] args) {
// TODO code application logic here
try {
DatagramSocket socket = new DatagramSocket(7000);
socket.setSoTimeout(0);
while(true)
{
byte []buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
socket.receive(packet);
String message = new String (buffer);
System.out.println(message);
String Reply ="Am here";
DatagramPacket data = new DatagramPacket(Reply.getBytes(), Reply.getBytes().length, packet.getAddress(), packet.getPort());
socket.send(data);
}
}
catch (Exception error){
error.printStackTrace();
}
}
}
Client
package client;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Client {
public static void main(String[] args) {
// TODO code application logic here
try{
String message = "Hello Server";
String host = "localhost";
InetAddress addr = InetAddress.getByName(host);
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 7000);
DatagramSocket socket = new DatagramSocket(4000);
socket.send(packet);
DatagramSocket sockets = new DatagramSocket(7000);
sockets.setSoTimeout(0);
while(true)
{
byte []buffer = new byte[1024];
DatagramPacket packets = new DatagramPacket(buffer,buffer.length);
sockets.receive(packets);
String messages = new String (buffer);
System.out.println(messages);
}
}
catch (Exception error){
error.printStackTrace();
}
}
}
How can i get them communicated. I have heard about Multi-threading but can't get my head round how it works.
I get the following error.
java.net.BindException: Address already in use: Cannot bind
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:84)
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:93)
at java.net.DatagramSocket.bind(DatagramSocket.java:392)
at java.net.DatagramSocket.<init>(DatagramSocket.java:242)
at java.net.DatagramSocket.<init>(DatagramSocket.java:299)
at java.net.DatagramSocket.<init>(DatagramSocket.java:271)
at client.Client.main(Client.java:32)
If you wanting to send/receive from a client to a server using a socket then use ServerSocket on the serverside.
Then use accept - This listens for a connection to be made to this socket and accepts it.
The Socket object returned by Accept has Input and Output Stream which can be be read and written to.
The client will just use a Socket Object
See http://cs.lmu.edu/~ray/notes/javanetexamples/ for an example
If for some reason you insist on using DatagramSocket, then see this example https://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html
The error occurs because the port you are trying to bind your socket to is already in use. Port 7000 is used both by the client and server:
DatagramSocket sockets = new DatagramSocket(7000);
I am trying to send a message over UDP and comparing it with a string literal, but it does not seem to work.
Here is the UDP server code
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Controller {
public static void main(String args[]) {
//create UDP server
try {
DatagramSocket socket = new DatagramSocket(5002);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
//wait for done message
socket.receive(packet);
String msg = new String (packet.getData());
if(msg.equals("Done"))
{
System.out.println("Done received");
}
else {
System.out.println("Done not received");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
And here is the UDP client code
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Slave {
public static void main(String args[]) {
//create UDP client
try {
DatagramSocket socket = new DatagramSocket();
byte[] buffer;
//send Done message
buffer = "Done".getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getLocalHost(), 5002);
socket.send(packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}
The output I get is "done not received", even though done message is sent. What is wrong with the code?
The problem is, that you are declaring a buffer with 1024 bytes, which you are the converting to a string. That string does not equal "Done", it is simply "too long". You have to obtain the actual length of your sent data. You could do something like this in your Controller:
public class Controller {
public static void main(String args[]) {
//create UDP server
try {
DatagramSocket socket = new DatagramSocket(5002);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
//wait for done message
socket.receive(packet);
//Get actual data length and copy it
byte[] data = new byte[packet.getLength()];
System.arraycopy(packet.getData(), packet.getOffset(), data, 0, packet.getLength());
//Create string from actual data
String msg = new String (data);
if(msg.equals("Done"))
{
System.out.println("Done received");
}
else {
System.out.println("Done not received");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
String msg = new String(packet.getData(), packet.getOffset(), packet.getLength());
DatagramPacket contains other information such as the port and host. Calling new String() on the data will extract more information than just the data message. Using packet.getData() and setting the offset will make sure that you extract just the data in the packet and leave out the port and host.
See the JavaDocs for DatagramPacket for more information.
When I debug your code, I can see that the message is "Done" with a lot of following '\u0000' which seems to be a unicode represantation of 0
So you either remove the zeros or you change your if statement to
msg.startsWith("Done")
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.