I am not talking about threading or anything to make this more complicated.
Most server programs I saw are like this or while(true){...} (same concept).
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.io.DataOutputStream;
import java.io.IOException;
public class TCPServer {
ServerSocket welcomeSocket;
public TCPServer(int port) throws IOException {
welcomeSocket = new ServerSocket(port);
}
public void go() throws IOException {
// This is not a valid way to wait for a socket connection, You should
// not have a forever loop or while(true)
**for (; ;) {**
Socket connectionSocket = welcomeSocket.accept();
Scanner clientIn = new Scanner(connectionSocket.getInputStream());
DataOutputStream clientOut = new DataOutputStream(connectionSocket.getOutputStream());
String clientLine = clientIn.nextLine();
String modLine = clientLine.toUpperCase();
clientOut.writeBytes(modLine + "\n");
}
}
public static void main(String[] args){
try {
TCPServer server = new TCPServer(6789);
server.go();
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
It is not looping permanently, your code blocks on line welcomeSocket.accept() until someone connects and only after that next lines are executed then it waits for a new connection on welcomeSocket.accept(). In other words it loops as many times as it needs( per each connection ).
If you just want to allow only one client to connect, remove for (; ;) statement. But it will require to restart your server every time.
The while(!finished) option might be a better solution than the "empty" for loop. When the exit event occurs, you just set finished to true.
You can run a scheduler with any number of thread in the pool
and prevent the main thread from termination. Here I've used input stream but you can do it in different ways. Here you can use multiple threads to get connections and customize the frequency of the scheduler.
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
public class MyTest {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(4);
#Test
public void hello() {
final Runnable helloServer = new Runnable() {
public void run() {
// handle soket connection here
System.out.println("hadling connection");
}
};
final ScheduledFuture<?> helloHandle = scheduler.scheduleAtFixedRate(helloServer, 1000, 1000, TimeUnit.MILLISECONDS);
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Related
Hi programmer all over the world
In order to understand what's the difference between Concurrency vs Parallelism, I was given this problem to solve but I fall off in this problem that I couldn't solve and it took me a lot of time , so I came here and I home someone could help me .
I have a problemm here I have built a program that has 4 classes , 2 of them are "Client" (Agsrq to send generates squares numbers and AgFibo so send sequence of number of fibonacci) used to send number to the server (agclassserver recieve data from Agsqr and Agfibo to order and display them in form of list ) , and I add other class to make server accepts many clients (Multithreading) in this case ,Agsqr and AgFibo are taking the role of client.
So here is my problem , when I execute the classes (agclassserver "server" , Agsqr & AgFibo "Clients") the result is giving me only the fist client lets say "Agsqr" and when I execute the AgFibo it doesn't executes but it gives me another execution of Agsqr "so I have the result of two Agsqr "
Here is all the class I vae used in this program
Agclassserver
package smatp2;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.*;
public class agclassserver {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
ArrayList<Integer> array = new ArrayList<Integer>();
ArrayList<ClassesHandler> classes_handler = new ArrayList<ClassesHandler>();
ExecutorService service= Executors.newFixedThreadPool(10);
boolean var=true;
int message;
try {
while(true) {
ServerSocket server = new ServerSocket(9090);
System.out.println("I waiting for the client ");
Socket socket = server.accept();// waiting for client to connect with server
ClassesHandler client = new ClassesHandler(socket);
classes_handler.add(client);
service.execute(client);
}
}catch (Exception e) {
}
}
}
Agsqr
package smatp2;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Agsqr {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
try {
Socket socket = new Socket ("localhost", 9090);
int n=0;
OutputStream output = socket.getOutputStream();
DataOutputStream stream = new DataOutputStream(output);
while(true) {
int result = n*n;
stream.writeInt(result);
n++;
Thread.sleep(1000);
}
}catch(Exception e) {
}
}
}
AgFibo
package smatp2;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class AgFibo extends Thread {
public synchronized void run() {
}
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
// TODO Auto-generated method stub
try {
int number ;
int previousNumber = 0;
int nextNumber = 1;
boolean variable=false ;
Socket socket = new Socket ("localhost", 9090);
int n=0;
OutputStream output = socket.getOutputStream();
DataOutputStream stream = new DataOutputStream(output);
while(!variable){
stream.writeInt(previousNumber);
int sum = previousNumber + nextNumber;
previousNumber = nextNumber;
nextNumber = sum;
Thread.sleep(1000);
}
}catch(Exception e) {
}
}
}
ClassesHandler
package smatp2;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Collections;
public class ClassesHandler implements Runnable {
private Socket socket;
private int message;
ArrayList<Integer> array = new ArrayList<Integer>();
private DataInputStream dataInputStream;
public ClassesHandler(Socket socket) throws IOException{
this.socket = socket;
dataInputStream = new DataInputStream(socket.getInputStream());
}
#Override
public void run() {
// TODO Auto-generated method stub
try {
while(true) {
message = dataInputStream.readInt();
array.add(message);// waiting for client to connect with server
Collections.sort(array);
System.out.println(message);
System.out.println(array);
//Thread.sleep(500);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
agclassserver /* Sorry I forgot to post the classserver Class */
package smatp2;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.*;
public class agclassserver {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
ArrayList<Integer> array = new ArrayList<Integer>();
ArrayList<Integer> arraySQR = new ArrayList<Integer>();
ArrayList<Integer> arrayFibo = new ArrayList<Integer>();
ArrayList<ClassesHandler> classes_handler = new ArrayList<ClassesHandler>();
ExecutorService service= Executors.newFixedThreadPool(10);
boolean var=true;
int message;
try {
ServerSocket server = new ServerSocket(9090);
while(true) {
System.out.println("I waiting for the client ");
Socket socket = server.accept();// waiting for client to connect with server
String hostName = socket.getInetAddress().getHostName();
ClassesHandler client = new ClassesHandler(socket,array,arraySQR,arrayFibo,hostName);
classes_handler.add(client);
service.execute(client);
}
}catch (Exception e) {
}
}
}
Concurrent vs Parallel.
Imagine you need to get a new passport and you need to prepare a presentation for work.
Not parallel and not concurrent: first you go get your passport and then you prepare a presentation.
Not parallel, but concurrent: you go to the embassy and wait on a chair for you turn. While you are waiting, you work on your presentation. As soon as it is your turn, you close your laptop and fill in the passport papers and later you will complete your presentation.
Parallel and concurrent: you go work on your presentation while you send your wife/husband to the embassy to get your passport.
There is also a possibility to do parallel and not concurrent. But that doesn't fit with the above example. And example would calculating the sum of 2 huge integer arrays. Using SIMD multiple integer adds can be executed in parallel, but there is no concurrency since there is just a single request.
I'm new to Netty and I wrote based on an example I found a Netty http server, that keeps http connections open to send server-sent-events to the browser client.
Problem is that it only accepts up to about ~5 connections and after that blocks new connections. I googled and found most answers said to set SO_LOGBACK to a higher value. Tried different values and while I saw no difference. I even set it to MAX_INTEGER value and still had only 5 connections.
Server code (Using Netty version 4.1.6.Final):
package server;
import static io.netty.buffer.Unpooled.copiedBuffer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpVersion;
public class NettyHttpServer {
private ChannelFuture channel;
private final EventLoopGroup masterGroup;
public NettyHttpServer() {
masterGroup = new NioEventLoopGroup(100);
}
public void start() {
try {
final ServerBootstrap bootstrap = new ServerBootstrap().group(masterGroup)
.channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer < SocketChannel > () {
#Override
public void initChannel(final SocketChannel ch) throws Exception {
ch.pipeline().addLast("codec", new HttpServerCodec());
ch.pipeline().addLast("aggregator", new HttpObjectAggregator(512 * 1024));
ch.pipeline().addLast("request", new ChannelInboundHandlerAdapter() {
#Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg)
throws Exception {
System.out.println(msg);
registerToPubSub(ctx, msg);
}
#Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.INTERNAL_SERVER_ERROR,
copiedBuffer(cause.getMessage().getBytes())));
}
});
}
}).option(ChannelOption.SO_BACKLOG, Integer.MAX_VALUE)
.childOption(ChannelOption.SO_KEEPALIVE, true);
channel = bootstrap.bind(8081).sync();
// channels.add(bootstrap.bind(8080).sync());
} catch (final InterruptedException e) {}
}
public void shutdown() {
masterGroup.shutdownGracefully();
try {
channel.channel().closeFuture().sync();
} catch (InterruptedException e) {}
}
private void registerToPubSub(final ChannelHandlerContext ctx, Object msg) {
new Thread() {
#Override
public void run() {
while (true) {
final String responseMessage = "data:abcdef\n\n";
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
copiedBuffer(responseMessage.getBytes()));
response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/event-stream");
response.headers().set(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
response.headers().set("Cache-Control", "no-cache");
ctx.writeAndFlush(response);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
public static void main(String[] args) {
new NettyHttpServer().start();
}
}
Client js code (I run it more than 5 times from my browser in different tabs, and the not all of them get:
var source = new EventSource("http://localhost:8081");
source.onmessage = function(event) {
console.log(event.data);
};
source.onerror= function(err){console.log(err); source.close()};
source.onopen = function(event){console.log('open'); console.log(event)}
You need to let the browser know that you are done sending the response, and for that you have three options.
Set a content length
Send it chunked
Close the connection when you are done
You aren't doing any of those. I suspect your browser is still waiting for the full response to each request you send, and is using a new connection for each request in your testing. After 5 requests your browser must be refusing to create new connections.
Another thing I noticed is that you are creating a new thread for each request in your server, and never letting it die. That will cause problems down the line as you try to scale. If you really want that code to run in a different thread then I suggest looking at overloaded methods for adding handlers to the pipeline; those should let you specify a thread pool to run them in.
I have a multi threaded server in which server is waiting for all possible clients to be connected.As soon as client is connected it sends an int(12345) to server and server reads and display it now server uses a specific IPaddress of a client using hash map architecture sends a message to that client to which ipaddress is matched.but my code is stuck in while loop and it isn't go to the function messagetospecificclient() and if it goes it displays null. Sorry for my bad English
My code is
Server
public class ServerStart implements Runnable
{
#Override
public void run()
{
try
{
HandleMultipleClients hmc=new HandleMultipleClients();
hmc.connect();
hmc.messagetospecificclients("172.20.3.122");
}
}
HandleMultipleClients
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package zeeshannisar210;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
*
* #author Zeeshan Nisar
*/
public class HandleMultipleClients{
Map<Integer, java.net.Socket> clients = new HashMap<Integer, java.net.Socket> ();
Socket sock;
ServerSocket serverSock;
DataOutputStream dos;
DataInputStream dis;
String ip;
public HandleMultipleClients()
{
}
public void connect()
{
try
{
serverSock = new ServerSocket(2101);
while (true)
{
sock = serverSock.accept();
clients.put(sock.getPort(), sock);
dis=new DataInputStream(sock.getInputStream());
int s=dis.readInt();
System.out.print(s);
messagetospecificclients(ip);
}
}
catch(Exception e)
{
}
}
public void messagetospecificclients(String ipaddress) throws IOException
{
System.out.print(ipaddress);
for (Iterator<Integer> iter = clients.keySet().iterator(); iter.hasNext(); )
{
int key = iter.next();
System.out.print("ok1");
ip=ipaddress;
System.out.print(ip);
System.out.print("ok2");
java.net.Socket client = clients.get(key);
InetAddress zee = client.getInetAddress();
String s = zee.getHostAddress();
System.out.print("ok3");
System.out.print(s);
if (s.equals(ipaddress))
{
System.out.print("ok4");
dos =new DataOutputStream(client.getOutputStream());
dos.writeUTF("Some message");
}
}
}
public static void main(String[] args) {
new HandleMultipleClients();
}
}
Client code is
public class messagefromserver implements Runnable
{
#Override
public void run()
{
try
{
sock = new Socket("localhost",2101);
System.out.println("Success");
dos=new DataOutputStream(sock.getOutputStream());
dos.writeInt(12345);
// Basicinfosend bis=new Basicinfosend(sock);
// Thread t1=new Thread(bis);
// t1.start();
// Thread.sleep(1000);
// Systeminfosend sis=new Systeminfosend(sock);
// Thread t2=new Thread(sis);
// t2.start();
// Thread.sleep(1000);
// Thread p = new Thread(new Process());
// p.start();
while(true)
{
String s=dis.readUTF();
System.out.print(s);
}
}
I wanted to practice a little on Network Programming and Thread Pools with Java. Here is a sample code I written:
/* User: koray#tugay.biz Date: 21/02/15 Time: 13:30 */
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class MyServer {
static List<ServerSocketThread> myThreadPool = new ArrayList<ServerSocketThread>();
static int numberOfCurrentConnections = 0;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
ServerSocketThread threadOne = new ServerSocketThread(null);
ServerSocketThread threadTwo = new ServerSocketThread(null);
myThreadPool.add(threadOne);
myThreadPool.add(threadTwo);
while (true) {
if(numberOfCurrentConnections < 2) {
Socket accept = serverSocket.accept();
ServerSocketThread thread = myThreadPool.get(numberOfCurrentConnections);
thread.setSocket(accept);
thread.start();
numberOfCurrentConnections++;
} else {
// I want to force the client to wait until a new Thread is available from the pool.
}
}
}
public static void informFinished() {
numberOfCurrentConnections--;
}
}
and the ServerSocketThread class is as follows:
/* User: koray#tugay.biz Date: 21/02/15 Time: 18:14 */
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class ServerSocketThread extends Thread {
Socket socket;
public ServerSocketThread(Socket accept) {
this.socket = accept;
}
#Override
public void run() {
try {
Scanner scanner = new Scanner(socket.getInputStream());
String readLine;
while (!(readLine = scanner.nextLine()).equals("bye")) {
System.out.println(readLine);
}
new PrintWriter(socket.getOutputStream()).write("Bye then..");
socket.close();
MyServer.informFinished();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
Well I can connect to my server with 2 different terminals like this just fine:
Korays-MacBook-Pro:~ koraytugay$ telnet localhost 8888
Trying ::1...
Connected to localhost.
Escape character is '^]'.
laylay
bombom
And the 3rd connection (if made) will not be served as there are 2 Threads only in the Thread Pool. But I can not find a way to make the 3rd client wait until a client says "bye". What I want to do is, after one of the 2 first connected clients disconnect, a Thread is allocated to the waiting 3rd Client, but how?
I will answer my own question, I made it work like this:
/* User: koray#tugay.biz Date: 21/02/15 Time: 21:12 */
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Stack;
public class MyConnectionAccepter {
private Stack<MySocketThread> mySocketThreads = new Stack<MySocketThread>();
private volatile int currentNumberOfConnections = 0;
public MyConnectionAccepter() {
MySocketThread mySocketThreadOne = new MySocketThread(this);
MySocketThread mySocketThreadTwo = new MySocketThread(this);
mySocketThreadOne.setDaemon(true);
mySocketThreadTwo.setDaemon(true);
mySocketThreadOne.start();
mySocketThreadTwo.start();
mySocketThreads.push(mySocketThreadOne);
mySocketThreads.push(mySocketThreadTwo);
}
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
while (currentNumberOfConnections < 2) {
System.out.println("Blocking now:");
Socket accept = serverSocket.accept();
System.out.println("Connection accepted..");
MySocketThread mySocketThread = mySocketThreads.pop();
mySocketThread.setSocket(accept);
System.out.println("Incrementing connections..");
currentNumberOfConnections++;
System.out.println("End of while..");
}
}
}
public void informIAmDone(MySocketThread mySocketThread) {
mySocketThreads.push(mySocketThread);
currentNumberOfConnections--;
}
}
and
/* User: koray#tugay.biz Date: 21/02/15 Time: 21:04 */
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
public class MySocketThread extends Thread {
private volatile Socket socket;
MyConnectionAccepter myConnectionAccepter;
public MySocketThread(MyConnectionAccepter myConnectionAccepter) {
this.myConnectionAccepter = myConnectionAccepter;
}
#Override
public synchronized void run() {
System.out.println("Started...");
serve();
}
public void setSocket(Socket socket) {
this.socket = socket;
System.out.println("Socket not null anymore..");
}
public void serve() {
while(socket == null) {
}
while (socket != null) {
Scanner scanner = null;
try {
scanner = new Scanner(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
String readLine;
while (!(readLine = scanner.nextLine()).equals("bye")) {
System.out.println(readLine);
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
socket = null;
myConnectionAccepter.informIAmDone(this);
}
serve();
}
}
and the Test Class:
/* User: koray#tugay.biz Date: 21/02/15 Time: 21:18 */
import java.io.IOException;
public class MyTestClass {
public static void main(String[] args) throws IOException {
MyConnectionAccepter myConnectionAccepter = new MyConnectionAccepter();
myConnectionAccepter.start();
}
}
I would suggest that you should create a threadpool as described in this article: http://tutorials.jenkov.com/java-concurrency/thread-pools.html
So basically in addition to the pool of threads you also maintain a queue of tasks. Each thread in the pool is continuously polling the task queue for tasks. Whenever a task is available (queue is not empty), it is picked up by a thread and executed. In your case the task would be handling the client connection. The the number of threads in the pool is limited ( 2 in this case). So at any time number of connections that can be processed simultaneously is 2. Only when one of two threads is done executing the current task will it pick the next one. Each time you receive a new connection request, you add a new task to the queue.
Hope this helps!
I am trying to implement a TCP Server in Java using nio.
Its simply using the Selector's select method to get the ready keys. And then processing those keys if they are acceptable, readable and so. Server is working just fine till im using a single thread. But when im trying to use more threads to process the keys, the server's response gets slowed and eventually stops responding, say after 4-5 requests.
This is all what im doing:(Pseudo)
Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
while (keyIterator.hasNext()) {
SelectionKey readyKey = keyIterator.next();
if (readyKey.isAcceptable()) {
//A new connection attempt, registering socket channel with selector
} else {
Worker.add( readyKey );
}
Worker is the thread class that performs Input/Output from the channel.
This is the code of my Worker class:
private static List<SelectionKey> keyPool = Collections.synchronizedList(new LinkedList());
public static void add(SelectionKey key) {
synchronized (keyPool) {
keyPool.add(key);
keyPool.notifyAll();
}
}
public void run() {
while ( true ) {
SelectionKey myKey = null;
synchronized (keyPool) {
try {
while (keyPool.isEmpty()) {
keyPool.wait();
}
} catch (InterruptedException ex) {
}
myKey = keyPool.remove(0);
keyPool.notifyAll();
}
if (myKey != null && myKey.isValid() ) {
if (myKey.isReadable()) {
//Performing reading
} else if (myKey.isWritable()) {
//performing writing
myKey.cancel();
}
}
}
My basic idea is to add the key to the keyPool from which various threads can get a key, one at a time.
My BaseServer class itself is running as a thread. It is creating 10 Worker threads before the event loop to begin. I also tried to increase the priority of BaseServer thread, so that it gets more chance to accept the acceptable keys. Still, to it stops responding after approx 8 requests. Please help, were I am going wrong. Thanks in advance. :)
Third, you aren't removing anything from the selected-key set. You must do that every time around the loop, e.g. by calling keyIterator.remove() after you call next().
You need to read the NIO Tutorials.
First of all, you should not really be using wait() and notify() calls anymore since there exist good Standard Java (1.5+) wrapper classes in java.util.concurrent, such as BlockingQueue.
Second, it's suggested to do IO in the selecting thread itself, not in the worker threads. The worker threads should just queue up reads/and writes to the selector thread(s).
This page explains it pretty good and even provides working code samples of a simple TCP/IP server: http://rox-xmlrpc.sourceforge.net/niotut/
Sorry, I don't yet have time to look at your specific example.
Try using xsocket library. It saved me a lot of time reading on forums.
Download: http://xsocket.org/
Tutorial: http://xsocket.sourceforge.net/core/tutorial/V2/TutorialCore.htm
Server Code:
import org.xsocket.connection.*;
/**
*
* #author wsserver
*/
public class XServer {
protected static IServer server;
public static void main(String[] args) {
try {
server = new Server(9905, new XServerHandler());
server.start();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
protected static void shutdownServer(){
try{
server.close();
}catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}
Server Handler:
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.*;
import org.xsocket.*;
import org.xsocket.connection.*;
public class XServerHandler implements IConnectHandler, IDisconnectHandler, IDataHandler {
private Set<ConnectedClients> sessions = Collections.synchronizedSet(new HashSet<ConnectedClients>());
Charset charset = Charset.forName("ISO-8859-1");
CharsetEncoder encoder = charset.newEncoder();
CharsetDecoder decoder = charset.newDecoder();
ByteBuffer buffer = ByteBuffer.allocate(1024);
#Override
public boolean onConnect(INonBlockingConnection inbc) throws IOException, BufferUnderflowException, MaxReadSizeExceededException {
try {
synchronized (sessions) {
sessions.add(new ConnectedClients(inbc, inbc.getRemoteAddress()));
}
System.out.println("onConnect"+" IP:"+inbc.getRemoteAddress().getHostAddress()+" Port:"+inbc.getRemotePort());
} catch (Exception ex) {
System.out.println("onConnect: " + ex.getMessage());
}
return true;
}
#Override
public boolean onDisconnect(INonBlockingConnection inbc) throws IOException {
try {
synchronized (sessions) {
sessions.remove(inbc);
}
System.out.println("onDisconnect");
} catch (Exception ex) {
System.out.println("onDisconnect: " + ex.getMessage());
}
return true;
}
#Override
public boolean onData(INonBlockingConnection inbc) throws IOException, BufferUnderflowException, ClosedChannelException, MaxReadSizeExceededException {
inbc.read(buffer);
buffer.flip();
String request = decoder.decode(buffer).toString();
System.out.println("request:"+request);
buffer.clear();
return true;
}
}
Connected Clients:
import java.net.InetAddress;
import org.xsocket.connection.INonBlockingConnection;
/**
*
* #author wsserver
*/
public class ConnectedClients {
private INonBlockingConnection inbc;
private InetAddress address;
//CONSTRUCTOR
public ConnectedClients(INonBlockingConnection inbc, InetAddress address) {
this.inbc = inbc;
this.address = address;
}
//GETERS AND SETTERS
public INonBlockingConnection getInbc() {
return inbc;
}
public void setInbc(INonBlockingConnection inbc) {
this.inbc = inbc;
}
public InetAddress getAddress() {
return address;
}
public void setAddress(InetAddress address) {
this.address = address;
}
}
Client Code:
import java.net.InetAddress;
import org.xsocket.connection.INonBlockingConnection;
import org.xsocket.connection.NonBlockingConnection;
/**
*
* #author wsserver
*/
public class XClient {
protected static INonBlockingConnection inbc;
public static void main(String[] args) {
try {
inbc = new NonBlockingConnection(InetAddress.getByName("localhost"), 9905, new XClientHandler());
while(true){
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
Client Handler:
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import org.xsocket.MaxReadSizeExceededException;
import org.xsocket.connection.IConnectExceptionHandler;
import org.xsocket.connection.IConnectHandler;
import org.xsocket.connection.IDataHandler;
import org.xsocket.connection.IDisconnectHandler;
import org.xsocket.connection.INonBlockingConnection;
/**
*
* #author wsserver
*/
public class XClientHandler implements IConnectHandler, IDataHandler,IDisconnectHandler, IConnectExceptionHandler {
Charset charset = Charset.forName("ISO-8859-1");
CharsetEncoder encoder = charset.newEncoder();
CharsetDecoder decoder = charset.newDecoder();
ByteBuffer buffer = ByteBuffer.allocate(1024);
#Override
public boolean onConnect(INonBlockingConnection nbc) throws IOException {
System.out.println("Connected to server");
nbc.write("hello server\r\n");
return true;
}
#Override
public boolean onConnectException(INonBlockingConnection nbc, IOException ioe) throws IOException {
System.out.println("On connect exception:"+ioe.getMessage());
return true;
}
#Override
public boolean onDisconnect(INonBlockingConnection nbc) throws IOException {
System.out.println("Dissconected from server");
return true;
}
#Override
public boolean onData(INonBlockingConnection inbc) throws IOException, BufferUnderflowException, ClosedChannelException, MaxReadSizeExceededException {
inbc.read(buffer);
buffer.flip();
String request = decoder.decode(buffer).toString();
System.out.println(request);
buffer.clear();
return true;
}
}
I spent a lot of time reading on forums about this, i hope i can help u with my code.