My server is listening to 2 ports ,and it should execute separate functions on each port simultaneously.
my problem is ,that the server blocks until the client of the first port is connected first.
For example: if a second client tried to connect to the 2nd port before a client connects to the 1st port ,it won't let it connect.
I created 2 classes that extends to thread class,so they should wait to any client in parallel instead of blocking what's after them.
But it doesn't seem to work as i'm expecting.
public static void main(String[] args) throws Exception {
System.out.println("server is running.");
int clientNumber = 0;
ServerSocket listenerTrans = new ServerSocket(9899);
ServerSocket listenerDeter = new ServerSocket(9898);
try {
while (true) {
new Deteriment(listenerDeter.accept(), clientNumber++).start();
new Transpose(listenerTrans.accept(), clientNumber++).start();
}
} finally {
listenerTrans.close();
listenerDeter.close();
}
}
Deteriment and Transpose are my classes that extend to thread class.
I want that the listenerDeter.accept() not to block the listenerTrans.accept(), i want that both of the thread's accept() happen in parallel.
Also why isn't it happening in parallel in my code?
The answer is to use a ServerSocketChannel and a Selector. The Selector allows your application to multiplex I/O on multiple channels using a single thread. It can be used in clocking or non-blocking mode
Here is an example (borrowed from How java nio ServerSocketChannel accept works? and adapted for your use-case):
// Create the 2 server socket channels
ServerSocketChannel server1 = ServerSocketChannel.open();
ServerSocketChannel server2 = ServerSocketChannel.open();
// Configure channels for nonblocking I/O
server1.configureBlocking(false);
server2.configureBlocking(false);
// Bind channels' IP and port
server1.socket().bind(new java.net.InetSocketAddress(host, 9899));
server2.socket().bind(new java.net.InetSocketAddress(host, 9898));
// Create the selector
Selector selector = Selector.open();
// Register channels to selector (type OP_ACCEPT)
SelectionKey key1 = server1.register(selector, SelectionKey.OP_ACCEPT);
SelectionKey key2 = server2.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select(); // blocks until one or more of the registered channels
// has actionable I/O
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey selKey = (SelectionKey) it.next();
if (selKey.isAcceptable()) {
ServerSocketChannel ssc = (ServerSocketChannel) selKey.channel();
SocketChannel sc = ssc.accept();
if (selKey.equals(key1)) {
new Deteriment(sc.socket() ...).start();
} else {
new Transpose(sc.socket(), ...).start();
}
}
}
}
(Caveats: 1: not tested, 2: could be more elegant, 3: possible resource leaks, 4: you really should be using a thread pool / executor rather than firing off new threads by hand)
So, first of all if you like it to be async you need to use separate thread for every ServerSocket what u declare. Why? Becouse by the conception java.net was blocking not scalable way of dealing with net thinks. If you like it to be non-blocking more scalable but less abstrac (I mean you will allocate buffers ^^) you should look for java nio instead.
**EDIT: **
I little modyf your code it should make job done but its improvable i mean its not the most elegent version ^^
public static void main(String[] args) throws Exception {
System.out.println("server is running.");
final int[] clientNumber = {0};
ServerSocket listenerTrans = new ServerSocket(9899);
ServerSocket listenerDeter = new ServerSocket(9898);
try {
ExecutorService ex = Executors
.newFixedThreadPool(2);
ex.execute(
() -> {
try {
Socket s = listenerDeter.accept();
new Deteriment(s, clientNumber[0]++).start();
} catch (IOException e) {
e.printStackTrace();
}
}
);
ex.execute(
() -> {
try {
Socket s = listenerDeter.accept();
new Transpose(s, clientNumber[0]++).start();
} catch (IOException e) {
e.printStackTrace();
}
}
);
} finally {
//listenerTrans.close();
//listenerDeter.close();
}
}
Related
I am working on a program where I have a Server and Client class, but at the moment it only handles only one client at a time.
I need the server to be able to handle multiple clients concurrently (simultaneously), using multithreading.
Here is my Server code; how can I change it to handle multiple clients concurrently?
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket(8945);
Server serverInstance = new Server();
System.out.println("Server is running. Waiting for client.");
while(true) {
server.socket = s.accept();
System.out.println("Client connected");
serverInstance.run();
System.out.println("Client disconnected. Waiting for new client.");
}
}
public void run() {
try {
try {
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
RequestHandlingMethod();
} finally {
socket.close();
}
} catch (IOException e) {
System.err.println(e);
}
}
Create a separate class that handles the client. Make it implement Runnable so that you can just start a separate Thread with it.
public class ClientHandler implements Runnable {
private final Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
public void run() {
try (Socket socket = this.socket;
Scanner in = new Scanner(socket.getInputStream();
PrintWriter out = new PrintWriter(socket.getOutputStream()) {
//todo: do whatever you need to do
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.println("Client disconnected.");
}
}
Then in your server you do:
System.out.println("Waiting for new client connection");
Socket clientSocket = s.accept();
System.out.println("Client connected");
new Thread(new ClientHandler(clientSocket)).start();
If you don't want to create a lot of disposable Threads, you might want to consider using an ExecutorService with a cached thread pool (or another thread pool of your choice if you prefer).
You would just create a new ExecutorService with ExecutorService executor = ExecutorService.newCachedThreadPool() and then inside your loop you do:
System.out.println("Waiting for new client connection");
Socket clientSocket = s.accept();
System.out.println("Client connected");
executor.submit(new ClientHandler(clientSocket));
If you think you are going to have a lot of concurrent clients, you might want to look at using a non-blocking server with NIO instead. It will have 1 single event loop thread instead (doesn't block on the accept) and handles all I/O events in there, and you can have a pool of worker threads that do the client handling logic.
I am implementing a multi-threaded client-server application in java. I want to implement JDBC in this program and I want my server to retrieve data from the database whenever it is started. I will store that data in my collection instances, perform manipulations on data and when server completes execution, I need to store the data back to the database. The problem is that the server is in an infinite loop waiting for clients and I am not able to figure out how to make the server stop.
This is my server program:
import java.io.*;
import java.text.*;
import java.util.*;
import java.net.*;
public class Server
{
public static void main(String[] args) throws IOException
{
// server is listening on port 5056
ServerSocket ss = new ServerSocket(5056);
// running infinite loop for getting
// client request
while (true)
{
Socket s = null;
try {
// socket object to receive incoming client requests
s = ss.accept();
System.out.println("A new client is connected : " + s);
// obtaining input and out streams
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
System.out.println("Assigning new thread for this client");
// create a new thread object
Thread t = new ClientHandler(s, dis, dos);
// Invoking the start() method
t.start();
}
catch (Exception e) {
s.close();
e.printStackTrace();
}
}
}
}
// ClientHandler class
class ClientHandler extends Thread
{
DateFormat fordate = new SimpleDateFormat("yyyy/MM/dd");
DateFormat fortime = new SimpleDateFormat("hh:mm:ss");
final DataInputStream dis;
final DataOutputStream dos;
final Socket s;
// Constructor
public ClientHandler(Socket s, DataInputStream dis, DataOutputStream dos)
{
this.s = s;
this.dis = dis;
this.dos = dos;
}
#Override
public void run()
{
String received;
String toreturn;
while (true) {
try {
// Ask user what he wants
dos.writeUTF("What do you want?[Date | Time]..\n"+
"Type Exit to terminate connection.");
// receive the answer from client
received = dis.readUTF();
if(received.equals("Exit"))
{
System.out.println("Client " + this.s + " sends exit...");
System.out.println("Closing this connection.");
this.s.close();
System.out.println("Connection closed");
break;
}
// creating Date object
Date date = new Date();
// write on output stream based on the
// answer from the client
switch (received) {
case "Date" :
toreturn = fordate.format(date);
dos.writeUTF(toreturn);
break;
case "Time" :
toreturn = fortime.format(date);
dos.writeUTF(toreturn);
break;
default:
dos.writeUTF("Invalid input");
break;
}
}
catch (IOException e) {
e.printStackTrace();
}
}
try
{
// closing resources
this.dis.close();
this.dos.close();
}
catch(IOException e){
e.printStackTrace();
}
}
}
Here is my client program:
import java.io.*;
import java.net.*;
import java.util.Scanner;
// Client class
public class Client
{
public static void main(String[] args) throws IOException
{
try
{
Scanner scn = new Scanner(System.in);
// getting localhost ip
InetAddress ip = InetAddress.getByName("localhost");
// establish the connection with server port 5056
Socket s = new Socket(ip, 5056);
// obtaining input and out streams
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
// the following loop performs the exchange of
// information between client and client handler
while (true)
{
System.out.println(dis.readUTF());
String tosend = scn.nextLine();
dos.writeUTF(tosend);
// If client sends exit,close this connection
// and then break from the while loop
if(tosend.equals("Exit"))
{
System.out.println("Closing this connection : " + s);
s.close();
System.out.println("Connection closed");
break;
}
// printing date or time as requested by client
String received = dis.readUTF();
System.out.println(received);
}
// closing resources
scn.close();
dis.close();
dos.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}
Overview
Great question! To reiterate what was stated in the above comments, you are looking for a server-side shutdown. There are some way of handling this situation, and I can explain it with a brief example.
ExecutorServer
I will run through a modified example based off this example. Below find the server implementation.
class NetworkService implements Runnable {
private final ServerSocket serverSocket;
private final ExecutorService pool;
private final AtomicBoolean shouldExit;
public NetworkService(int port, int poolSize) throws IOException {
serverSocket = new ServerSocket(port);
pool = Executors.newFixedThreadPool(poolSize);
shouldExit = new AtomicBoolean(false); // Thread-safe boolean
}
public void run() { // run the service
try {
// While we should not exit
while(!shouldExit.get()) {
try {
pool.execute(new ClientHandler(serverSocket.accept()));
} catch (SocketException e) {
if(shouldExit.get()) break; // Poison pill has been delivered, lets stop
// Error handling
}
}
} catch (IOException ex) {
pool.shutdown();
}
// Clean up the thread pool
shutdownAndAwaitTermination();
}
}
class ClientHandler implements Runnable {
private final Socket socket;
ClientHandler (Socket socket) { this.socket = socket; }
public void run() {
...
}
...
}
Here you will modify your current Server code to intimidate this structure. You have a similar make up currently but here we have added ExecutorService.
An Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.
By dispatching your ClientHandler to an ExecutorService, you are utilizing a ThreadPool. Although this comes with plenty of benefits, the most significant ones are that you have more control over your multi-threaded service, the ThreadPool will manage thread utilization, and the application efficiency will increase tremendously.
Below is how you would attempt to shutdown and terminate all remaining threads:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
Now, the question remains how do we shutdown the server? The above code shows a improved structure, but still have the issue of blocking on a serverSocket.accept()!
Solution
There are two ideas that come to mind when thinking of this scenario; a CLI or a GUI. Both have the same semantics, and the decision is ultimately up to you. For purposes of explaining, I will refer to a CLI approach.
Poison Pill
If you implement a new Thread() that handled all incoming commands from the CLI, this thread would act as a poison pill. The idea is to deliver a poison pill to the target such that can wake up/execute and die. The thread will change the shouldExit atomic boolean to true and create a new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort()).close(); to connect to the ServerSocket and immediately close it. In the above code, the application will no longer be blocking on the serverSocket.accept(). Instead, it will enter the try catch for SocketExceptions and test if a poison pill was utilized; If it was then lets clean up, if not lets error handle.
Timeout
You could also set a timeout on the ServerSocket such that it will throw an exception each time it cannot get a connection in that time interval with myServer.setSoTimeout(2000);. This will throw an InterruptedIOException and can be handled similarly to the poison pill where the flag is changed via a CLI command and it checks if it should exit in the catch block. If it should exit, lets clean up, if not lets error handle.
You can use pattern flag with volatile boolean variable, and you should place it in 'while' - when processing would be finished, turn it to false and the server would stop.
Another way - use thread pools and wait for them to finish in the main thread of your server.
I'm attempting to move my networking over from standard IO to NIO and following the few tutorials that there are to attempt to figure it out, while me, myself, and I decided it'd be a great idea to spend my first week rewriting the core for all of the applications logic handling, I never would have imagined that I wouldn't be able to set up the basic networking.
Currently the networking is at a very basic stage, everything is tossed inside of a while-loop and I can't honestly say I've put any attempt into it to make it look nice, considering I haven't a clue what I'm doing my goal was to figure out how to do it first, then go back and give it a makeover.
Here's the code I use to initialize my server:
// Initializes the TCP Server and all of its components.
private void initTcpServer(int port) {
try {
// Create a new selector
Selector socketSelector = SelectorProvider.provider()
.openSelector();
// Create a new non-blocking server socket channel;
this.serverSocketChannel = ServerSocketChannel.open();
this.serverSocketChannel.configureBlocking(false);
// Bind the server socket to the specified address and port
this.serverSocketChannel.socket().bind(
new InetSocketAddress("127.0.0.1", port));
// Register the server socket channel, indicating an interest in
// accepting new connections
this.serverSocketChannel.register(socketSelector,
SelectionKey.OP_ACCEPT);
// Set the selector for the server instance.
this.selector = socketSelector;
} catch (IOException e) {
e.printStackTrace();
}
}
Then this class implements the Runnable interface, and a new thread is started directly after this method completes, in this thread we contain the following code:
public void run() {
while (isRunning) {
try {
selector.selectNow();
} catch (IOException io) {
return;
}
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
if (!key.isValid()) {
it.remove();
continue;
}
try {
if (key.isAcceptable()) {
this.handleConnection(key);
} else if (key.isReadable()) {
Connection connection = (Connection) key.attachment();
if (connection != null) {
try {
connection.getMasterProtocol()
.decode(connection,
connection.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
} finally {
it.remove();
}
}
}
}
This, from my understanding is what allows us to handle our connections and data based off of a SelectionKey.. and is what all of the NIO based networking runs from, you'll see that I'm calling two different methods to make this not so much of a mess, the first one is #handleConnection and the other one is a decode function.
The handle connection method creates a new instance of my Connection class and attatches it to the SelectionKey, like so:
public Connection(SelectionKey key) {
try {
// For an accept to be pending the channel must be a server socket channel.
ServerSocketChannel serverSocketChannel = (ServerSocketChannel)key.channel();
// Accept the connection and make it non-blocking.
this.socketChannel = serverSocketChannel.accept();
this.socketChannel.configureBlocking(false);
// Set up other user data.
this.inputStream = new DataInputStream(socketChannel.socket().getInputStream());
this.masterProtocol = new MasterProtocol();
// Register the new SocketChannel with our Selector, indicating
// we'd like to be notified when there's data waiting to be read.
key = this.socketChannel.register(OGServer.getInstance().getSelector(), SelectionKey.OP_READ);
key.attach(this);
// Add the current <SelectorKey, Connection> to the current connections collection.
connections.put(key, this);
Log.debug(getClass(), "Connection constructed successfully.");
} catch(IOException e) {
e.printStackTrace();
}
}
The error is called when I attempt to call the MasterProtocol#decode method, which looks like this:
public Object decode(Connection connection, DataInputStream dataInputStream) throws IOException {
if(connection.getState() == ConnectionState.CONNECTED) {
byte[] bytes = ByteStreams.toByteArray(dataInputStream);
if(bytes.length < 4) {
System.out.println("Not enough bytes read.");
return null;
}
int bufferSize = dataInputStream.readInt();
System.out.println("Buffer Size: " + bufferSize);
while(bytes.length < bufferSize) {
return null;
}
int test = dataInputStream.readInt();
System.out.println("Test: " + test);
return null;
}
return null;
}
The error seems to be called when the DataInputStream tries to read from the network, more specifically on this line of code:
byte[] bytes = ByteStreams.toByteArray(dataInputStream);
The error:
Exception in thread "Thread-0" java.nio.channels.IllegalBlockingModeException
at sun.nio.ch.SocketAdaptor$SocketInputStream.read(SocketAdaptor.java:190)
at sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
at java.io.DataInputStream.read(DataInputStream.java:100)
at com.google.common.io.ByteStreams.copy(ByteStreams.java:70)
at com.google.common.io.ByteStreams.toByteArray(ByteStreams.java:115)
at net.ogserver.framework.net.protocol.MasterProtocol.decode(MasterProtocol.java:29)
at net.ogserver.framework.net.OGServer.run(OGServer.java:146)
at java.lang.Thread.run(Thread.java:745)
The 'IllegalBlockingModeException' exception is what's throwing me off, as all of the information I've found was for setting up a Non-blocking server, but the DataInputStream implementation was my own, so I must have done something wrong somewhere. NIO is a completely different world from IO, but learning is learning, eh?
EDIT: I guess it'd help to know how I'm sending the data from the client, it's just a very basic test application that does this:
socket = new Socket("127.0.0.1", 5055);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeBoolean(false);
If you're moving to NIO in non-blocking you can't keep using streams. If you want to use streams there is no advantage to using NIO at all. I would just stop the migration project now.
I'm developing an app in android that will act as a server, this is, there will be an tablet that will be the "server" and there will be other tablets that will connect to the "server".
I'm trying to use the java NIO with a selector, to save on threads. But my problem is, I have the java code running in a thread in android, but when the thread runs it don't happen nothing. On the client side it gives and exception of Connection Refused.
The code is running in a java application, but in android not.
I also have the internet permission.
The java selector:
Thread t = new Thread(new Runnable() {
private Selector selector;
private ServerSocketChannel sChan;
private List<SocketChannel> sockets;
public void run() {
try {
selector = SelectorProvider.provider().openSelector();
sChan = ServerSocketChannel.open();
InetSocketAddress iaddr = new InetSocketAddress(InetAddress.getLocalHost(), 8000);
sChan.configureBlocking(false);
sChan.socket().bind(iaddr);
System.out.println("Running on port:" + sChan.socket().getLocalPort());
sChan.register(selector, SelectionKey.OP_ACCEPT);
sockets = new LinkedList<SocketChannel>();
}
catch (IOException e) {
e.printStackTrace();
}
Iterator<SelectionKey> it;
try {
while (true) {
selector.select();
it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
if (!key.isValid()) {
continue;
}
// Finish connection in case of an error
if (key.isConnectable()) {
SocketChannel ssc = (SocketChannel) key.channel();
if (ssc.isConnectionPending()) {
ssc.finishConnect();
}
}
if (key.isAcceptable()) {
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel newClient = ssc.accept();
newClient.configureBlocking(false);
newClient.register(selector, SelectionKey.OP_READ);
sockets.add(newClient);
System.out.println("new client: " + newClient.socket().getInetAddress().getHostAddress());
}
if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer data = ByteBuffer.allocate(sc.socket().getSendBufferSize());
System.out.println("new message: " + sc.socket().getInetAddress().getHostAddress());
if (sc.read(data) == -1) {
continue;
}
data.flip();
Teste m = (Teste) UdpUtil.byteToMessage(data.array());
System.out.println("message: " + m);
System.out.println("\n\n" + m.cenas);
sc.close();
}
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
And the Client application:
InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName("192.168.2.102"), 8000);
SocketChannel sc = null;
try {
// Connect
sc = SocketChannel.open();
sc.connect(isa);
// Read the time from the remote host. For simplicity we assume
// that the time comes back to us in a single packet, so that we
// only need to read once.
byte[] message = UdpUtil.messageToByteMessage(new messages.Teste("hello there"));
ByteBuffer buf = ByteBuffer.wrap(message);
sc.write(buf);
}
finally {
// Make sure we close the channel (and hence the socket)
if (sc != null) {
sc.close();
}
}
Note: the Teste class its just an class that will be used as the message between the androids.
I had even tried this code and all went well, but with the selector not.
I hope that I made my self clear on what the problem is.
Thanks in advance :)
Remove the first argument to new InetSocketAddress(), the one you use for binding the ServerSocketChannel. At present you are only binding to 127.0.0.1, which cannot be seen from other hosts. By omitting the argument you are binding to 0.0.0.0, which means 'listen at all interfaces'.
Make sure you have requested the internet permission in Android by going into your AndroidManifest.xml file and putting:
uses-permission android:name="android.permission.INTERNET" />
Am trying to build a chat application.i have a code that sends the data from client to server. when one or more client login(when the client program runs one or more time).server will not accepting the rest of connection other than first connected.
please help me to resolve this
here is my code:
public class Server
{
//Creating non blocking socket
public void non_Socket() throws Exception {
ServerSocketChannel ssChannel = ServerSocketChannel.open();
int port = 80;
int i=0;
ssChannel.socket().bind(new InetSocketAddress(port));
ssChannel.configureBlocking(false);
while(true)
{
SocketChannel sc = ssChannel.accept();`
if (sc == null)
{
System.out.println("Socket channel is null");
Thread.sleep(5000);
}
else
{
System.out.println("Socket channel is not null");
System.out.println("Received an incoming connection from " +
sc.socket().getRemoteSocketAddress());
new PrintRequest(sc,i).start();
i++;
}
}
}
public static void main(String [] abc) throws Exception
{
new Server().non_Socket();
}
}
class PrintRequest extends Thread {
public PrintRequest(SocketChannel sc,int i) throws Exception
{
WritableByteChannel wbc = Channels.newChannel(System.out);
ByteBuffer b = ByteBuffer.allocateDirect(1024); // read 1024 bytes
int numBytesRead = sc.read(b);
while (numBytesRead != -1)
{
b.flip();
while (b.hasRemaining())
{
wbc.write(b);
System.out.println();
//System.out.println("Stream "+i);
// System.out.println(" KKK "+b.toString());
}
//b.clear();
}
}
}
Client code:
public class Client extends Thread {
public void non_Client_Socket() throws Exception
{
SocketChannel sChannel = SocketChannel.open();
sChannel.configureBlocking(false);
sChannel.connect(new InetSocketAddress("localhost", 80));
while (!sChannel.finishConnect())
{
System.out.println("Channel is not connected yet");
}
System.out.println("Channel is ready to use");
/* ---------- going to send data to server ------------*/
System.out.println("please enter the text");
BufferedReader stdin=new BufferedReader(new InputStreamReader(System.in));
while(true)
{
System.out.println("Enter the text");
String HELLO_REQUEST =stdin.readLine().toString();
if(HELLO_REQUEST.equalsIgnoreCase("end"))
{
break;
}
System.out.println("Sending a request to HelloServer");
ByteBuffer buffer = ByteBuffer.wrap(HELLO_REQUEST.getBytes());
sChannel.write(buffer);
}
}
/* ---------- the data is written to sChannel server
will read from this channel ------------ */
public static void main(String [] args) throws Exception
{
new Client().non_Client_Socket();
}
}
There are numerous issues here.
You are putting your ServerSocketChannel into non-blocking mode and then calling accept() without using a Selector. That means 99.9999% of the time accept() will return null, so you are burning CPU cycles. This is pointless. Either accept in blocking mode or use a Selector.
You are putting your client SocketChannel into non-blocking mode, calling connect(), and the calling finishConnect() without using a Selector. That means 99% of the time finishConnect() will return false, so you are burning CPU cycles. This is pointless. Either connect in blocking mode or use a Selector.
You are ignoring the result of SocketChannel.write(). You can't do that. It returns information you need to know about.
In short, your code doesn't make much sense.
I don't have time to look into your code in detail, but some initial observations:
When using NIO, I suggest you use Selector (as I suggested in your previous question) instead of one thread per client.
Remember to bind each client in order to allow the server socket to accept new connections.