I want to make my server able to accept messages from two clients. but something went wrong. Help needed! I tried to run same client twice, but received only one message and some errors.
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Serv1 {
public static void main(String[] args) throws IOException {
Listner listner = new Listner();
Thread thread = new Thread(listner);
thread.start();
System.out.println("thread already started");
DatagramSocket s = new DatagramSocket(8787);
byte[] receiveData = new byte[1024];
System.out.println ("Waiting for datagram packet");
DatagramPacket p = new DatagramPacket(receiveData, receiveData.length);
System.out.println("about to receive packet N1");
s.receive(p);
String sentence = new String(p.getData());
InetAddress IPAddress = p.getAddress();
int port = p.getPort();
System.out.println ("From: " + IPAddress + ":" + port);
System.out.println ("Message: " + sentence);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
receiveData = new byte[1024];
System.out.println ("Waiting for datagram packet");
p = new DatagramPacket(receiveData, receiveData.length);
System.out.println("about to receive packet N2");
s.receive(p);
sentence = new String(p.getData());
IPAddress = p.getAddress();
port = p.getPort();
}
}
class Listner implements Runnable
{
public void run() {
String text = null;
while(true){
text = null;
int server_port = 8787;
byte[] receiveData = new byte[1024];
DatagramPacket p = new DatagramPacket(receiveData, receiveData.length);
DatagramSocket s = null;
try{
s = new DatagramSocket(server_port);
}catch (SocketException e) {
e.printStackTrace();
System.out.println("Socket excep, port used");
}
try {
s.receive(p);
}catch (IOException e) {
e.printStackTrace();
System.out.println("IO EXcept");
}
text = new String(receiveData, 0, p.getLength());
System.out.println("message = "+text);
s.close();
}
}
}
run:
thread already started
Waiting for datagram packet about to receive packet N1
java.net.BindException: Address already in use: Cannot bind
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
at java.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:91)
at java.net.DatagramSocket.bind(Socket excep, port used
DatagramSocket.java:372)
at java.net.DatagramSocket.<init>(DatagramSocket.java:211)
at java.net.DatagramSocket.<init>(DatagramSocket.java:262)
at java.net.DatagramSocket.<init>(DatagramSocket.java:235)
at serv1.Listner.run(Listner.java:29)
at java.lang.Thread.run(Thread.java:662)
Exception in thread "Thread-0" java.lang.NullPointerException
at serv1.Listner.run(Listner.java:35)
at java.lang.Thread.run(Thread.java:662)
From: /192.168.1.102:58977
Message: hi, i am the first one
Waiting for datagram packet
about to receive packet N2
BUILD SUCCESSFUL (total time: 59 seconds)**strong text**
You are trying to bind the same port twice. That's not how it works. You should have 1 thread listening to the port, and a pool of threads to process the requests. Whenever new information comes thought the port, you give the request data (the new info received) to a thread for processing.
You are creating 2 DatagramSocket's on the same port (8787). One is created in the main method, and the other is created in the Listner inner class' run() method.
I'm not sure what you're trying to do here, but you either need to run the Listner class' DatagramSocket on a different port or pass the one created by the main() method to the Listner class.
Related
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
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 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);
}
}
}
I have 3 nodes A, B and C with their respective port numbers.
I'm trying to write a java program that takes in 3 arguments:
its node name and its 2 neighboring node's ports and broadcasts a string "Hello I'm A" to them (so A would broadcast to B and C). It will do this every 3 seconds.
This program will be run in 3 separate instances.
Upon receiving a string it will print what node it has received it from "Received string" (example for Port B).
I have difficulties implementing this, I have heard of something called multicasting with UDP though. Here is my work so far, what am I doing wrong?
class UDP {
public static void main(String[] args) throws Exception {
String nodeName = args[0];
int neighbourPort1 = Integer.valueOf(args[1]);
int neighbourPort2 = Integer.valueOf(args[2]);
while(true) {
Thread.sleep(3000); //every 3 seconds
//Continously broadcast and listen to neighbour1
DatagramSocket socket1 = null;
try {
//CREATE SOCKET TO NEIGHBOUR1
InetAddress host = InetAddress.getByName("localhost");
socket1 = new DatagramSocket();
socket1.connect(host, neighbour1);
//CREATE DATAGRAMS FOR SENDING
String message = "Hello I'm " + nodeName;
byte[] sendData = message.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, host, port);
socket1.send(sendPacket);
//CREATE DATAGRAMS FOR RECEIVING
byte[] receiveData = new byte[100]; //is there a way to determine the needed space?
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket1.receive(receivePacket);
System.out.println("Received string");
} catch(Exception e) { }
//Do the same for neighbour2, code is basically identical except for variables
DatagramSocket socket2 = null;
try {
//CREATE SOCKET TO NEIGHBOUR2
InetAddress host = InetAddress.getByName("localhost");
socket2 = new DatagramSocket();
socket2.connect(host, neighbour2);
//FOR SENDING DATAGRAMS
String message = "Hello I'm " + nodeName;
byte[] sendData = message.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, host, port);
socket2.send(sendPacket);
//FOR RECEIVING DATAGRAMS
byte[] receiveData = new byte[100]; //is there a way to determine the needed space?
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket2.receive(receivePacket);
System.out.println("Received string");
} catch(Exception e) { }
}
}
}
I know I'm close to the solution. I'm able to broadcast properly but it's the constantly listening part that gets me.
I think its best to use a separate Thread to listen for data on your own port.
A sends data to B and blocks until it gets a packet from B.
B sends data to C and blocks until it gets a packet from C.
C sends data to A and blocks until it gets a packet from A.
Every node is waiting for each other. Just send the packets and wait 3 seconds.
The other thread is going to listen only.
public class UDP {
public static void main(String[] args) throws Exception {
final String nodeName = args[0];
final int ownPort = Integer.valueOf(args[1]);
final int neighbourPort1 = Integer.valueOf(args[2]);
final int neighbourPort2 = Integer.valueOf(args[3]);
// Don't create a new socket every time
DatagramSocket neighbour1 = new DatagramSocket();
DatagramSocket neighbour2 = new DatagramSocket();
neighbour1.connect(InetAddress.getLocalHost(), neighbourPort1);
neighbour2.connect(InetAddress.getLocalHost(), neighbourPort2);
// You have to LISTEN
new Thread() {
#Override
public void run() {
try {
DatagramSocket socket = new DatagramSocket(ownPort);
byte[] buffer = new byte[socket.getReceiveBufferSize()];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
// Blocks until it gets a packet
socket.receive(packet);
System.out.println("Received string");
}
// socket.close();
} catch (final Exception e) {
e.printStackTrace();
}
}
}.start();
while (true) {
Thread.sleep(3000);
sendPacket(neighbour1, nodeName);
sendPacket(neighbour2, nodeName);
}
// If you're not using an infinite loop:
// neighbour1.close();
// neighbour2.close();
}
private static void sendPacket(DatagramSocket to, String from) throws Exception {
String message = "Hello I'm " + from;
byte[] data = message.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length);
to.send(packet);
}
}
Here is a simple frame for a server with two threads, one writing and one reading, place your network code at the right places.
package testing;
import java.util.Scanner;
public class ThreadTest {
public class MyListenerThread extends Thread {
#Override
public void run() {
/*
* Open Datagram ...
*/
while (true) {
/*
* Read data ...
*/
Scanner scanner = new Scanner(System.in);
System.out.println("read: " + scanner.next());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MySenderThread extends Thread {
#Override
public void run() {
/*
* Open Multicast ...
*/
while (true) {
/*
* Send ...
*/
System.out.println("Send ...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void start() {
MyListenerThread listener = new MyListenerThread();
MySenderThread sender = new MySenderThread();
listener.start();
sender.start();
}
public static void main(String[] args) {
ThreadTest server = new ThreadTest();
server.start();
}
}
Is multi-threading possible in a simple java server using udp connectionless protocol? give an example!!
Multi-threading is actually simpler with UDP because you don't have to worry about connection state. Here is the listen loop from my server,
while(true){
try{
byte[] buf = new byte[2048];
DatagramPacket packet = new DatagramPacket( buf, buf.length, address );
socket.receive( packet );
threadPool.execute( new Request( this, socket, packet ));
.......
The threadPool is a ThreaPoolExecutor. Due to the short-lived nature of UDP sessions, thread pool is required to avoid the overhead of repeatedly thread creation.
Yes, it's possible through the use of the DatagramChannel class in java.nio. Here's a tutorial (It does not address the multithreading, but that is a separate issue anyway).
Here is one example try putting your own ip to get the hard-coded message back
package a.first;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class Serv {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
Listner listner = new Listner();
Thread thread = new Thread(listner);
thread.start();
String messageStr = "Hello msg1";
int server_port = 2425;
DatagramSocket s = new DatagramSocket();
InetAddress local = InetAddress.getByName("172.20.88.223");
int msg_length = messageStr.length();
byte[] message = messageStr.getBytes();
DatagramPacket p = new DatagramPacket(message, msg_length, local,
server_port);
System.out.println("about to send msg1");
s.send(p);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
messageStr = "Hello msg2";
msg_length = messageStr.length();
message = messageStr.getBytes();
p = new DatagramPacket(message, msg_length, local,
server_port);
System.out.println("about to send msg2");
s.send(p);
}
}
class Listner implements Runnable
{
#Override
public void run() {
String text = null;
while(true){
text = null;
int server_port = 2425;
byte[] message = new byte[1500];
DatagramPacket p = new DatagramPacket(message, message.length);
DatagramSocket s = null;
try{
s = new DatagramSocket(server_port);
}catch (SocketException e) {
e.printStackTrace();
System.out.println("Socket excep");
}
try {
s.receive(p);
}catch (IOException e) {
e.printStackTrace();
System.out.println("IO EXcept");
}
text = new String(message, 0, p.getLength());
System.out.println("message = "+text);
s.close();
}
}
}