IPv6 Multicast Check Java - java

Is there any better to way to check if I can receive a given IP Multicast transmission. Following code works fine but there is a problem in this code - it blocks the current thread until it gets the multicast packets.
Thank you.
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class MulticastTest {
static String MCAST_ADDR = "FF7E:230::1234";// "235.1.1.1";
static int DEST_PORT = 1234;
static int BUFFER_LENGTH = 16;
public static void main(String args[]) {
try {
byte[] b = new byte[BUFFER_LENGTH];
DatagramPacket dgram = new DatagramPacket(b, b.length);
MulticastSocket socket = new MulticastSocket(DEST_PORT);
socket.joinGroup(InetAddress.getByName(MCAST_ADDR));
socket.receive(dgram); // blocks until a datagram is received
System.err.println("Received " + dgram.getLength() + " bytes from " + dgram.getAddress());
dgram.setLength(b.length); // must reset length field!
} catch (Exception e) {
}
}
}

You could set a timeout-value with the method socket.setSoTimeout(int).
http://download.oracle.com/javase/1.4.2/docs/api/java/net/Socket.html#setSoTimeout(int)
If you don't receive any data within the timeout, a SocketTimeoutException is raised

Related

How do I make a java app communicate with an ESP32 board?

I've been trying to establish a TCP socket connection between an ESP32 board and a Java server. After establishing the connection, I want the server to send a packet to the ESP32 to request its ID (I use the ID to identify the clients, as there are going to be more of them), but the server doesn't seem to be transmitting anything (ESP32 isn't receiving anything). I even tried using Wireshark to track the packets, but upon connection, there is no message to be seen. Sorry for the horrible code, I'm still a beginner, when it comes to communication programming. Thanks in advance for your help.
Here is the code for the ESP32:
#include <WiFi.h>
WiFiClient client;
// network info
char *ssid = "SSID";
char *pass = "Password";
// wifi stats
int wifiStatus;
int connAttempts = 0;
// Client ID
int id = 128;
IPAddress server(192,168,1,14);
int port = 3241;
String inData;
void setup() {
Serial.begin(115200); // for debug
// attempting to connect to the network
wifiStatus = WiFi.begin(ssid, pass);
while(wifiStatus != WL_CONNECTED){
Serial.print("Attempting to connect to the network, attempt: ");
Serial.println(connAttempts++);
wifiStatus = WiFi.begin(ssid, pass);
delay(1000);
}
// info
Serial.print("Connected to the network, IP address is: '");
Serial.print(WiFi.localIP());
Serial.print("', that took ");
Serial.print(connAttempts);
Serial.println(" attempt(s).");
connAttempts = 0;
// connection to the main server
Serial.println("Starting connection to the server...");
while(!client.connect(server, port)){
Serial.print("Attempting connection to the server, attempt no. ");
Serial.println(connAttempts++);
delay(1000);
}
Serial.print("Connection successful after ");
Serial.print(connAttempts);
Serial.println(" attempt(s)!");
}
void loop() {
if(client.available()){
Serial.println("Incoming data!");
inData = client.readString();
}
if(inData != ""){
Serial.print("Incoming data: ");
Serial.println(inData);
if(inData == "REQ_ID"){
String msg = "INTRODUCTION;"
strcat(msg, m);
client.print(msg);
}
inData = "";
}
if(!client.connected()){
Serial.println("Lost connection to the server! Reconnecting...");
connAttempts = 0;
while(!client.connect(server, port)){
Serial.print("Attempting connection to the server, attempt no. ");
Serial.println(connAttempts++);
delay(1000);
}
Serial.print("Reconnection successful after ");
Serial.print(connAttempts);
Serial.println(" attempt(s)!");
}
delay(10);
}
And here is the client handler class from the Java server:
package org.elektrio.vsd2020;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
public class ClientHandler implements Runnable {
public Socket netSocket;
public BufferedInputStream in;
public BufferedOutputStream out;
private int clientID;
public ClientHandler(Socket skt) throws IOException {
this.netSocket = skt;
this.in = new BufferedInputStream(this.netSocket.getInputStream());
this.out = new BufferedOutputStream(this.netSocket.getOutputStream());
}
public void close() throws IOException{
this.in.close();
this.out.close();
this.netSocket.close();
}
#Override
public void run() {
while(netSocket.isConnected()){
try{
byte[] arr = new byte[2048];
in.read(arr);
String[] input = new String(arr, StandardCharsets.US_ASCII).split(";");
// if the message is tagged as "INTRODUCTION", it identifies a reply from the ESP32, which contains the client ID
if(input[0].equals("INTRODUCTION")){
clientID = Integer.parseInt(input[1]);
}
}
catch (IOException e) {
System.out.println("[" + LocalDateTime.now() + " at ClientHandler] Exception at client ID '" + clientID + "'!");
e.printStackTrace();
}
}
System.out.println("[" + LocalDateTime.now() + " at ClientHandler] Client ID '" + clientID + "' disconnected!");
Tools.clients.remove(this);
}
public int getID(){
return clientID;
}
public int reqID() throws IOException{
String req = "REQ_ID";
out.write(req.getBytes(StandardCharsets.US_ASCII));
}
}
Server's main class:
package org.elektrio.vsd2020;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static ServerSocket server;
public static ServerSocket remoteAccessServer;
public static ExecutorService pool;
public static boolean serviceRunning = true;
public static void main(String[] args) {
try{
// startup args
int port = args.length > 0 ? Integer.parseInt(args[0]) : 3241;
int maxClients = args.length > 1 ? Integer.parseInt(args[2]) : 10;
// startup parameters info
Tools.log("Main", "Server started with parameters: ");
if(args.length > 0) Tools.log("Main", args);
else Tools.log("Main", "Default parameters");
// server socket and the threadpool, where the client threads get executed
server = new ServerSocket(port);
pool = Executors.newFixedThreadPool(maxClients);
// main loop
while(true){
if(Tools.clients.size() < maxClients){
// connection establishment
Socket clientSocket = server.accept();
ClientHandler client = new ClientHandler(clientSocket);
Tools.log("Main", "New client connected from " + clientSocket.getRemoteSocketAddress());
// starting the client operation
pool.execute(client);
Tools.clients.add(client);
Thread.sleep(500);
client.reqID();
}
}
}
catch (IOException | InterruptedException ioe){
Tools.log("Main", "IOException at MAIN");
ioe.printStackTrace();
}
}
}
And lastly, the Tools class
package org.elektrio.vsd2020;
import java.time.LocalDateTime;
import java.util.ArrayList;
public class Tools {
public static ArrayList<ClientHandler> clients = new ArrayList<>();
public static void log(String origin, String message){
System.out.println("[" + LocalDateTime.now() + " at " + origin + "] " + message);
}
public static void log(String origin, String[] messages){
for(String msg : messages) System.out.println("[" + LocalDateTime.now() + " at " + origin + "] " + msg);
}
}
I have some recommendations:
I- Your server implementation, i.e. while(true){... Thread.sleep(500); ... }, resembles microcontroller-style programming. Java has much more powerful tools for socket communication, such as reactive frameworks. I suggest using frameworks like Netty:
Netty 4 User Guide
Introduction to Netty
It may require some effort to learn these but their performance is much better.
And also there exists modern protocols for IoT systems, like MQTT or even RSocket. You can use them instead of plain TCP connection.
II: In IoT systems, isolating the problem is very important. So in your case, using TCP terminal tools like Hercules helps a lot. These tools can act as both server and client; so you can use them instead of ESP32 and Java Server and test if the other side works well.
III: In IoT communications, try to limit the messages. Thus Instead of this conversion between ESP32 and Java:
ESP32: Hi
Java: Hello, who are you?
. My ID is ...
. Pass me the data...
. Here is the data...
Use this:
ESP32: Hi. I am ID .. and This is my data
Server: OK Thanks!

Why does this non-blocking IO call fail?

Background
I'd like to send a large (30MB, but could be much larger in the future) amount of data using Java's non-blocking SocketChannel
Why non-blocking? So that the computation of the next bytes to send isn't blocked waiting for the network
When I use the SocketChannel in blocking mode, the transfer completes without a problem
When I set the SocketChannel to non-blocking, it completes significantly faster, but the server doesn't receive all of the data
The server does receive some of the data, though
Question
Why is my large (30MB) file transfer failing when using a non-blocking Java NIO SocketChannel, and how do I fix it?
Files
I gutted the program and wrote the example so it so that it will all run in one go via javac *.java && java Main
It creates a Future for the server, a Future for the client, has the client send 30MB of random bytes to the server, and then blocks on the main thread until both Futures complete (though the server never does)
Note: This is primarily about TheClient.java
If the line between the comments <CommentOutToMakeWork> and </CommentOutToMakeWork> is commented out, the SocketChannel will be blocking and the transfer will complete
Main.java:
import java.io.IOException;
import java.lang.InterruptedException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
public static void main(String[] args) throws ExecutionException, IOException, InterruptedException {
final SocketAddress address = new InetSocketAddress("127.0.0.1", 12345);
final int size = 30 * 1000 * 1000;
ExecutorService executor = Executors.newFixedThreadPool(2);
TheServer theServer = new TheServer(address, size);
TheClient theClient = new TheClient(address, size);
Future<String> serverFuture = executor.submit(theServer);
Thread.sleep(2000);
Future<String> clientFuture = executor.submit(theClient);
System.out.println("MAIN: Received from client: " + clientFuture.get());
System.out.println("MAIN: Received from server: " + serverFuture.get());
executor.shutdown();
}
}
TheClient.java:
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Random;
import java.util.concurrent.Callable;
class TheClient implements Callable<String> {
private TheClient() {}
public TheClient(SocketAddress address, int size) {
this.size = size;
this.from = new byte[size];
this.serverAddress = address;
new Random().nextBytes(from);
}
private int size;
private byte[] from;
private SocketAddress serverAddress;
public String call() throws IOException {
SocketChannel socketChannel = SocketChannel.open();
System.out.println("CLIENT: Attempting to connect to server...");
socketChannel.connect(serverAddress);
// <CommentOutToMakeWork>
socketChannel.configureBlocking(false);
// </CommentOutToMakeWork>
System.out.println("CLIENT: Connection established. Sending " + size + " bytes.");
// For this example, this is one large write, but even my actual
// program, which uses a loop and puts smaller chunks onto the channel,
// is too fast for the SocketChannel.
socketChannel.write(ByteBuffer.wrap(from));
System.out.println("CLIENT: Write completed.");
return "CLIENT: Success!";
}
}
TheServer.java:
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.util.Random;
import java.util.concurrent.Callable;
class TheServer implements Callable<String> {
private TheServer() {}
public TheServer(SocketAddress address, int size) {
this.size = size;
this.to = new byte[size];
this.serverAddress = address;
}
private int size;
private byte[] to;
private SocketAddress serverAddress;
public String call() throws IOException {
ServerSocketChannel serverChannel = ServerSocketChannel.open().bind(serverAddress);
System.out.println("SERVER: Awaiting connection...");
InputStream clientSocketInputStream = serverChannel.accept().socket().getInputStream();
System.out.println("SERVER: Connection established. Attempting to read " + size + " bytes.");
for (int i = 0; i < size; ++i) {
to[i] = (byte) clientSocketInputStream.read();
}
System.out.println("SERVER: Read completed.");
return "SERVER: Success!";
}
}
I believe the answer lies in the WritableByteChannel.write documentation:
Unless otherwise specified, a write operation will return only after writing all of the r requested bytes. Some types of channels, depending upon their state, may write only some of the bytes or possibly none at all. A socket channel in non-blocking mode, for example, cannot write any more bytes than are free in the socket's output buffer.
So it looks like you need to use the return value of write to find out how much has been written, and handle the case when it's not all been written. What isn't clear from the description is how you handle that case - you may find you need to do some scheduling to continue writing when the socket output buffer has drained, for example.

Getting java.io.EOFException when calling readObject() on ObjectInputStream

I am trying to implement simple UDP communication between two sockets. In order to be sent in UDP packet, data needs to be converted to byte array. I created simple class named Packet which is used to store various data types. This class implements Serializable interface so it can be converted to byte array and sent over UDP protocol. Program worked fine until I put HashMap object inside Packet class. Error occurs on server side when recived data is being converted back to Packet object.
Here is client code:
package hr.fer.tel.rassus.udp.server;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.HashMap;
public class UDPClient {
final static int PORT = 10001; // server port
/**
* #param args the command line arguments
*/
public static void main(String args[]) throws IOException {
HashMap<Integer, Integer> vector = new HashMap<Integer, Integer>();
vector.put(1, 2);
Packet p = new Packet(10000,10001,"co2",0,vector);
byte[] serializedMessage = null;
try {
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
ObjectOutput oo = new ObjectOutputStream(bStream);
oo.writeObject(p);
serializedMessage = bStream.toByteArray();
oo.close();
} catch (Exception ex) {
System.out.println("error "+ex.toString());
}
// determine the IP address of a host, given the host's name
InetAddress address = InetAddress.getByName("localhost");
// create a datagram socket and bind it to any available
// port on the local host
DatagramSocket socket = new DatagramSocket(); //SOCKET
// create a datagram packet for sending data
DatagramPacket packet = new DatagramPacket(serializedMessage, serializedMessage.length,
address, PORT);
// send a datagram packet from this socket
socket.send(packet); //SENDTO
socket.close(); //CLOSE
}
}
Server code:
package hr.fer.tel.rassus.udp.server;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class UDPServer {
final static int PORT = 10001; // server port
/**
* #param args the command line arguments
*/
public static void main(String args[]) throws IOException {
byte[] rcvBuf = new byte[256]; // received bytes
// create a UDP socket and bind it to the specified port on the local
// host
DatagramSocket socket = new DatagramSocket(PORT); //SOCKET -> BIND
while (true) {
// create a DatagramPacket for receiving packets
DatagramPacket packet = new DatagramPacket(rcvBuf, rcvBuf.length);
// receive packet
socket.receive(packet); //RECVFROM
// construct a new String by decoding the specified subarray of
// bytes
// using the platform's default charset
ObjectInputStream iStream;
Packet p = null;
try {
iStream = new ObjectInputStream(new ByteArrayInputStream(packet.getData()));
p = (Packet) iStream.readObject();
iStream.close();
} catch (ClassNotFoundException ex) {
Logger.getLogger(UDPServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Packet class:
package hr.fer.tel.rassus.udp.server;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
/**
*
* #author adrianzgaljic
*/
public class Packet implements Serializable{
private int fromPort;
private int toPort;
private String co2;
private boolean flag;
private long timeStamp;
private HashMap<Integer, Integer> vector;
Set<Integer> keys;
public Packet(int from, int to, String co2, long time, HashMap<Integer, Integer> vector){
this.fromPort = from;
this.toPort = to;
this.co2= co2;
this.timeStamp = time;
this.vector = vector;
flag = false;
}
public Packet(int from){
this.fromPort = from;
this.flag = true;
}
public int getFromPort() {
return fromPort;
}
public int getToPort() {
return toPort;
}
public String getCo2() {
return co2;
}
public long getTimeStamp() {
return timeStamp;
}
public boolean isFlag() {
return flag;
}
public HashMap<Integer, Integer> getVector() {
return vector;
}
}
Stack trace:
Exception in thread "main" java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2325)
at java.io.ObjectInputStream$BlockDataInputStream.readUTFBody(ObjectInputStream.java:3063)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(ObjectInputStream.java:2864)
at java.io.ObjectInputStream.readUTF(ObjectInputStream.java:1072)
at java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:704)
at java.io.ObjectInputStream.readClassDescriptor(ObjectInputStream.java:830)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1601)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at hr.fer.tel.rassus.udp.server.UDPServer.main(UDPServer.java:48)
Java Result: 1
After running your code I realized that my previous answer was not solving the issue, however I will leave it along with the new one, because it describes an issue that may cause similar effect.
New answer:
Your server's datagram packet size is too small to receive all the data you are sending, increase its size by increasing the buffer size:
byte[] rcvBuf = new byte[256]; // received bytes
e.g. new byte[2048]
Old answer:
Swap these two lines in the client:
serializedMessage = bStream.toByteArray();
oo.close();
So you should have this:
oo.close();
serializedMessage = bStream.toByteArray();
The issue with your code is that you are getting the bytes, while ObjectOutputStream didn't actually flush all the data to your ByteArrayOutputStream.

Casting Exception while communicating with Serial Port

I am trying to communicate with the Serial Port. In the following program I listed the the available ports, it is giving me proper output but when I tried to establish a communication with serial port it gave me following exception.
java.lang.ClassCastException: gnu.io.LPRPort cannot be cast to gnu.io.SerialPort
Program:
import gnu.io.CommPortIdentifier;
import gnu.io.*;
import java.io.*;
import java.util.Enumeration;
public class PortList {
private static CommPortIdentifier port;
private SerialPort serialport;
private InputStream inputstream;
private OutputStream outputstream;
private static Enumeration ports;
public static void main(String args[]) {
System.out.println("fdsgfjh");
ports = CommPortIdentifier.getPortIdentifiers();
System.out.println(ports.nextElement());
while (ports.hasMoreElements()) {
port = (CommPortIdentifier)ports.nextElement();
String type;
switch (port.getPortType()) {
case CommPortIdentifier.PORT_PARALLEL:
type = "Parallel";
break;
case CommPortIdentifier.PORT_SERIAL:
type = "Serial";
break;
default: /// Shouldn't happen
type = "Unknown";
break;
}
System.out.println(port.getName() + ": " + type);
}
PortList objOfClass=new PortList();
objOfClass.readData();
}
public void readData(){
try{
if (port.isCurrentlyOwned()) {
System.out.println("Port Is In Use");
}
else {
serialport=(SerialPort)port.open(this.getClass().getName(), 2000);//Giving Exception on this line.
System.out.println("Port Is Opened now");
int baudRate=serialport.getBaudRate();
System.out.println(Integer.toString(baudRate));
serialport.setSerialPortParams(1200, 8, 1, serialport.PARITY_NONE);
System.out.println("Properties are set");
inputstream=serialport.getInputStream();
outputstream=serialport.getOutputStream();
byte[] write={12,45,78};
outputstream.write(write);//you have to write the data in the byte format for that status is given in the byte.
outputstream.flush();
byte[] read=new byte[30];
inputstream.read(read);
for(int i =0; i< read.length;i++){
System.out.println(i+" "+read);
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
Help Appreciated.
Thanks.
According to your implementation, port will be the last listed port. The last listed port may not be a Serial Port.
In your case, it appears that the last listed port is a parallel port.
In this way I selected the particular port which is available.
CommPortIdentifier.getPortIdentifier("/dev/ttyS0");

Java Server Non Blocking Query

I am using the following code to read some data from Android client. All is going fine. But now i am asked to make this server code non blocking. Is there any suggestions for this ? I was trying to use threads but dont know how ? I am beginner in Java :)
Thanks
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Calendar;
import java.util.Date;
import javax.imageio.ImageIO;
public class Server {
//Server Constructor
public Server()
{}
//Variables Initialization
private static ServerSocket server;
byte[] imagetemp;
private static Socket socket1;
private static boolean newImage;
private static Sdfdata data;
private static boolean cond;
public static int port;
private static int number = 0;
//Image Availability return method
public boolean imageAvailable()
{
return newImage;
}
public boolean clientchk()
{
return socket1.isClosed();
}
//Image Flag set by Vis group when image read.
public void setImageFlag(boolean set)
{
newImage = set;
}
// Send the data to the Vis Group
public Sdfdata getData()
{
return data;
}
//Starts the Server
public static boolean start(int port1)
{
try {
port=port1;
server = new ServerSocket(port1);
System.out.println("Waiting for Client to Connect");
//New thread here
socket1=server.accept();
} catch (IOException e) {
System.out.println("Cannot Connect");
e.printStackTrace();
return false;
}
return true;
}
//Stops the Server
public boolean stop()
{
try {
socket1.close();
}
catch (IOException e)
{
e.printStackTrace();
return false;
}
return true;
}
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
// Starts the server
start(4444);
// DataInput Stream for reading the data
DataInputStream in = null;
try {
in = new DataInputStream(socket1.getInputStream());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
cond=true;
do {
try
{
//Read Image Data
int length = in.readInt();
//Create an ByteArray of length read from Client for Image transfer
Sdfdata data = new Sdfdata(length);
//for (int i=0; i<length; i++)
//{ data.image[i] = in.readbyte(); }
if (length > 0) {
in.readFully(data.image);
}
//Read Orientation
data.orientation[0] = in.readFloat(); //Orientation x
data.orientation[1] = in.readFloat(); //Orientation y
data.orientation[2] = in.readFloat(); //Orientation z
//Read GPS
data.longitude = in.readDouble();
data.latitude = in.readDouble();
data.altitude = in.readDouble();
//Display orientation and GPS data
System.out.println(data.orientation[0] + " " + data.orientation[1] + " " + data.orientation[2]);
System.out.println(data.longitude + " " + data.latitude + " " + data.altitude);
String fileName = "IMG_" + Integer.toString(++number) + ".JPG";
System.out.println("FileName: " + fileName);
FileOutputStream fos = new FileOutputStream(fileName);
fos.write(data.image);
fos.close();
/*InputStream ins = new ByteArrayInputStream(data.image);
BufferedImage image = ImageIO.read(ins);
ImageIO.write(image, "JPG", new File (fileName));
*/
//set image flag
newImage = true;
} catch (Exception e) {
//System.out.println("EOF Or ? " + e);
cond =false;
socket1.close();
server.close();
start(port);
}
}while (cond);
}
}
Your code starts a server, waits for a connection, reads some data from the first connected client, and then exits after writing this data to a file.
Being asked to make your server "non-blocking" could mean that you are being asked to change it to use asynchronous IO (probably unlikely), or it could mean that you're being asked to handle more than one client at a time - because currently you can only serve one client and then your program exits.
This question is hard to answer because your current code is very far away from where you need it to be and it seems like some reading up on networking, sockets, and Java programming in general would be a good way to start.
I'd recommend Netty for doing anything network-related in Java and their samples and documentation are good and easy to follow. Good luck!

Categories