ServerSocket does not accept new connection/requests from clients - java

I have a ServerSocket that does not accept new requests from client while there's an ongoing process. I've been debugging this for quite some time now and I don't know where my error is. As far as i'm concerned I've followed all the initialization for creating new threads.
Below is my code:
public class CService
{
boolean decision = false;
public void otherConnect() throws Exception {
synchronized (_SYNC_){
ServerSocket server = new ServerSocket(14344, 1000);
IsoServerBean isoServerBean = new IsoServerBean();
log.info("Waiting for connections...");
byte[] lenbuf = new byte[4];
while(true){
Socket clientSocket = null;
clientSocket = server.accept();
int otherLen = isoServerBean.getOtherHeaderLength();
int size = 352;
byte[] buf = new byte[size];
clientSocket.getInputStream().read(buf);
HexDump.hexDump(buf,1,size);
byte[] targetBuf = new byte[size-2];
System.arraycopy(buf, 4, targetBuf, 0, size-4);
setMyConnectionClient(clientSocket);
new Thread(new CProcessorForClient(targetBuf, clientSocket, 4), "resp").start();
}
}
}
private class CProcessorForClient extends Thread{
private volatile boolean stopFlag;
private volatile boolean stopped;
private byte[] msg;
private Socket clientSocket;
private Socket socket;
private int millis;
private int ctr =0;
CProcessorForClient(byte[] buf, Socket s, int waitMillis) {
stopFlag = false;
stopped = false;
msg = buf;
socket = s;
millis = waitMillis;
}
public void killMe()
{
stopFlag = true;
synchronized (_SYNC_)
{
this.interrupt();
}
}
public boolean killed()
{
return stopped;
}
public void run() {
try {
Thread.sleep(millis);
log.debug("Parsing incoming: [" + new String(msg) + "]");
IsoMessage request = null;
//OMITTED THE PROCESS OF THE CREATION OF ISO TO BE THROWN TO ANOTHER SERVER
msgFactory.print(request);
try {
this.socket = getMyConnection();//Connection to another server
this.clientSocket = getMyConnectionClient();//Connection from client
request.write(socket.getOutputStream(), 0, 0);
int i = 0;
Integer sleepTime = 500;
Integer waitTime = 5000;
decision = true;
while(decision){
i = i + 1;
Thread.sleep(sleepTime);
if (i * sleepTime >= waitTime) {
this.clientSocket.close();
decision = false;
}
}
} catch (IOException ex) {
log.debug("IO Exception encountered: " + ex.getMessage());
} catch (Exception ex) {
java.util.logging.Logger.getLogger(CService.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
} catch (ParseException ex) {
log.error("Error in parsing incoming message:", ex);
log.debug("ex.getMessage: " + ex.getMessage());
} catch (InterruptedException ex) {
log.error("Interrupted!", ex);
} finally{
if (log != null) log.debug("Thread has finished processing txn.");
}
}
}
public static void main(String[] args) throws IOException
{
System.out.println("RANDOM PRINT OUTS");
}
}
I hope someone can help me with this.
EDIT 1: Is it ok if I did not put the ServerSocket initialization in the main method?
EDIT 2: Updated my otherConnect() method and still same result. I transferred all processing of request inside the thread to be created and it still cannot process new request while there is an ongoing process. See below code.
public void otherConnect() throws Exception {
synchronized (_SYNC_){
ServerSocket server = new ServerSocket(14344, 1000);
IsoServerBean isoServerBean = new IsoServerBean();
log.info("Waiting for connections...");
byte[] lenbuf = new byte[4];
while(true){
Socket clientSocket = null;
clientSocket = server.accept();
int size = 352;
byte[] targetBuf = new byte[size-2];
setMyConnectionClient(clientSocket);
new Thread(new CProcessorForClient(targetBuf, clientSocket, 4), "resp").start();
}
}
}
Below is the code for the Thread
private class CProcessorForClient extends Thread{
private volatile boolean stopFlag;
private volatile boolean stopped;
private byte[] msg;
private Socket clientSocket;
private Socket socket;
private int millis;
private int ctr =0;
CProcessorForClient(byte[] buf, Socket s, int waitMillis) {
stopFlag = false;
stopped = false;
msg = buf;
socket = s;
millis = waitMillis;
}
public void killMe()
{
stopFlag = true;
synchronized (_SYNC_)
{
this.interrupt();
}
}
public boolean killed()
{
return stopped;
}
public void run() {
try {
Thread.sleep(millis);
int isoSize = 352;
byte[] buf = new byte[isoSize];
socket.getInputStream().read(buf);
HexDump.hexDump(buf,1,isoSize);
System.arraycopy(buf, 4, msg, 0, isoSize-4);
IsoMessage request = null;
//OMITTED THE PROCESS OF THE CREATION OF ISO TO BE THROWN TO ANOTHER SERVER
msgFactory.print(request);
try {
this.socket = getMyConnection();//Connection to another server
this.clientSocket = getMyConnectionClient();//Connection from client
request.write(socket.getOutputStream(), 0, 0);
int i = 0;
Integer sleepTime = 500;
Integer waitTime = 5000;
decision = true;
while(decision){
i = i + 1;
Thread.sleep(sleepTime);
if (i * sleepTime >= waitTime) {
this.clientSocket.close();
decision = false;
}
}
} catch (IOException ex) {
log.debug("IO Exception encountered: " + ex.getMessage());
} catch (Exception ex) {
java.util.logging.Logger.getLogger(CService.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
} catch (ParseException ex) {
log.error("Error in parsing incoming message:", ex);
log.debug("ex.getMessage: " + ex.getMessage());
} catch (InterruptedException ex) {
log.error("Interrupted!", ex);
} finally{
if (log != null) log.debug("Thread has finished processing txn.");
}
}
}

Related

Java Socket how to simulate disconection from server

I have a Java program with a client and server sockets, there I want to test that an exception is raised after the server is down.
This is the server:
public class SocketServer implements Runnable {
private bool serverRuns = false;
private int timeout = 10000;
private DataInputStream in;
private DataOutputStream out;
private Socket client;
private ServerSocket server;
private String message = "Ok";
private waitForInstruction = true;
public SocketServer() throws IOException {
ServerSocket server = new ServerSocket(tcpPort,0,ipAdress);
serverRuns = true;
server.setSoTimeout(timeout)
}
private void waitForClient() {
try {
client = server.accept();
client.setSoTimeout(timeout);
in = new DataInputStream(client.getInputStream());
out = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
fail("I/O Error " + e.getMessage());
}
}
public void run() {
waitForClient();
while (serverRuns) {
if (clientSocket.isClosed()) {
waitForClient();
}
try {
while (waitForInstruction == false) {
// Read input message
String inputStreamString = "";
while (in.available() > 0) {
int c = in.read();
inputStreamString += (char) c;
}
out.write(message.getBytes());
System.out.println("Sent bytes: " + out.size());
setWaitForInstruction(true);
}
} catch (IOException E) {
fail("I/O Error " + E.getMessage());
}
}
}
public void closeServerSocket() {
try {
serverRuns = false;
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
void setWaitForInstruction(boolean waitForInstruction) {
this.waitForInstruction = waitForInstruction;
}
public void startServerSocket() {
serverRuns = true;
}
}
This is the client:
public class SocketClient extends Socket {
private InetAddress address;
private short tcpPort;
private DataInputStream in;
private DataOutputStream out;
private static final int timeOut = 10000;
public SocketClient(InetAddress address, short tcpPort) {
this.tcpPort = tcpPort;
this.address = address;
}
public void connect() throws IOException, SocketTimeoutException {
super.connect(new InetSocketAddress(address, tcpPort), timeOut);
}
public void doStuff() throws IOException {
String request = "Ok?";
String InputStreamString = "";
super.setSoTimeout(timeOut);
this.setSoTimeout(timeOut);
out = new DataOutputStream(super.getOutputStream());
in = new DataInputStream(super.getInputStream());
out.writeBytes(requestString);
int c;
do {
if (in.available() > 0) {
c = in.read();
InputStreamString += (char) c;
}
} while (!InputStreamString.equals("Ok"));
System.out.println(InputStreamString);
}
}
I start the server socket thread with:
#BeforeClass
public static void startSocket() throws IOException {
testServer = new SocketServer();
monitor = new Thread(testServer);
monitor.setName("Test Server Thread");
monitor.setDaemon(true);
monitor.start();
}
And the JUnit test is this:
#Before
public void createSocket() throws Exception {
ipAdress = InetAddress.getLocalHost();
SystemConfig.setLoggerConfigFilePath("LoggerConfig.xml");
socketClient = new SocketClient(ipAdress, 5000);
}
#Test
public void checkServerisDown() {
try {
socketClient.connect();
} catch (IOException e) {
fail("IO Error");
}
testServer.closeServerSocket();
monitor.interrupt();
try {
testServer = new SocketServer();
monitor = new Thread(testServer);
monitor.setName(" Test Server Thread");
monitor.setDaemon(true);
// monitor.start();
testServer.startServerSocket();
testServer.setWaitForInstruction(false);
System.out.print("Test (1/1) CHECK SERVER IS DOWN.....\n");
socketClient.doStuff();
System.out.println("NOT OK!");
} catch (IOException e) {
fail("IO Error " + e.getMessage() + " OK");
}
try {
drEstimControlInterface.close();
testServer.getSocket().close();
} catch (IOException e) {
fail("IO Error");
}
}
#AfterClass
public static void closeSocket() throws IOException {
testServer.closeSocket();
}
However the test is not performing as I intended, I thought that this should return an IOException since the server socket has been closed and the thread has been interrupted, but the client socket still gets the answer from the server socket and prints the "NOT OK!". Could anybody tell me why?
You have to close not only ServerSocket but client socket with streams too.
public void closeServerSocket() {
try {
serverRuns = false;
serverSocket.close();
in.close();
out.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}

Java socket server cannot receive many data at the same time, how to make java socket server accept data at the same time?

my java socket server cannot accept more than one data at the same time in one client
Thread t1 = new Thread(() -> {
ServerSocket ss = null;
try {
ss = new ServerSocket(9000);
} catch (IOException e) {
e.printStackTrace();
}
try {
while(true) {
System.out.println("Waiting Transaction ..");
Socket clientSocket = ss.accept();
InetAddress inet = clientSocket.getInetAddress();
try{
while (clientSocket.getInputStream().available() == 0) {
Thread.sleep(100L);
}
byte[] data;
int bytes;
data = new byte[clientSocket.getInputStream().available()];
bytes = clientSocket.getInputStream().read(data,0,data.length);
String dataDB = new String(data, 0, bytes, "UTF-8");
System.out.println("received data\n time : "+ new Date() +"length data : " + dataDB.length());
System.out.println(dataDB);
String dataFrom = getFromServer(dataDB);
clientSocket.getOutputStream().write(dataFrom.getBytes("UTF-8"));
}catch (BindException be){
be.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally {
clientSocket.close();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t1.start();
i try using thread but it not working, this code only accept the first data otherwise anoter data will be decline. how to server accept many data at the same time?
Let me tell you how I did it, while playing around with sockets, so I created a SocketServer class
public class Server {
public static final Integer port = 9000;
private final ServerSocket server;
private final ExecutorService service = Executors.newFixedThreadPool(10);
private final AtomicInteger idGenerator = new AtomicInteger(0);
public Server() throws IOException {
this.server = new ServerSocket(port);
}
public void start() {
try {
while (true) {
Worker worker = new Worker(idGenerator.incrementAndGet(), server.accept());
service.execute(worker);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Now every time, a client joins, I create a worker thread and submit it to ExecutorService (Executor service has pool of threads and run the passed worker by allocating a thread to it, you can read about it).
The worker class looks like this
public class Worker implements Runnable {
private final Socket client;
private final Logger log = LoggerFactory.getLogger(this.getClass());
public Worker(Integer id, Socket client) {
this.id = id; //Ignore it, it was for logging purpose, how many joined
this.client = client;
}
#Override
public void run() {
listenClientMessages();
closeConnection();
}
private void listenClientMessages() {
final int MAX_INPUT = 1024;
int read;
try (InputStream is = client.getInputStream()) {
byte[] buf = new byte[MAX_INPUT];
while ((read = is.read(buf)) != -1) {
String line = new String(buf, 0, read);
log.info(line);
if (line.equals("bye")) break;
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void closeConnection() {
try{
client.close();
}catch (IOException ex) {
ex.printStackTrace();
}
}
}
So, you can see, I am reading bytes in while look
byte[] buf = new byte[MAX_INPUT];
while ((read = is.read(buf)) != -1) {
String line = new String(buf, 0, read);
log.info(line);
if (line.equals("bye")) break;
}
that's why when MAX_INPUT or less is processed, it would wait from client to send next input.
Let me know if it helps.
Edit: As commented by #user207421 in comments, closeConnection function is redundant as inputstream is closed with try-wit-resources block above in listenClientMessages function, so it is not needed.

Java SocketServer Connected to a AccessGuard 1000 Solution

I have the following issue connecting to a AccessGard (newnet) solution that forwards TPC messages to my application from a POS.
Basically the AG automatically connects from an ip "X.X.X.2" to my pooled server but it never sends any data.
When the POS send the message for some reason the AG sends the TPC request from another IP "X.X.X.132" but it never triggers the serverSocket.accept()
With wiresharck I can see Keep Alive messages from the X.X.X.2 to my server every second. Also I can see the request incoming from ip "X.X.X.132" but it never reaches the server. All the incoming transmissions come to the same port.
here is my server :
public class Server2 {
protected int serverPort = 8005;
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread= null;
protected ExecutorService threadPool = Executors.newFixedThreadPool(10);
public Server2()
{}
public void run(){
openServerSocket();
while(! isStopped()){
Socket clientSocket = null;
try {
clientSocket = this.serverSocket.accept();
} catch (IOException e) {
if(isStopped()) {
System.out.println("Server Stopped.") ;
break;
}
throw new RuntimeException(
"Error accepting client connection", e);
}
this.threadPool.execute(
new WorkerRunnable(clientSocket,
"Thread Pooled Server"));
}
this.threadPool.shutdown();
System.out.println("Server Stopped.") ;
}
private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort);
} catch (IOException e) {
throw new RuntimeException("Cannot open port 8005", e);
}
}
private synchronized boolean isStopped() {
return this.isStopped;
}
}
here the worker:
public class WorkerRunnable implements Runnable
{
private static final Logger logger = Logger.getLogger(WorkerRunnable.class);
protected Socket connectionSocket = null;
protected String serverText = null;
public WorkerRunnable(Socket connectionSocket, String serverText) {
this.connectionSocket = connectionSocket;
this.serverText = serverText;
}
public void run() {
try {
System.out.println(read());
} catch (IOException e) {
//report exception somewhere.
e.printStackTrace();
}
}
private String read() throws IOException
{
InputStream in = connectionSocket.getInputStream();
byte[] m = new byte[2];
in.read(m,0,2);
ByteBuffer wrapped = ByteBuffer.wrap(m);
short num = wrapped.getShort();
logger.info("IN message length:" + num +" Hexa:" + String.format("%02x", m[0]) + String.format("%02x", m[1])); System.out.println("IN message length:" + num +" Hexa:" + String.format("%02x", m[0]) + String.format("%02x", m[1]));
byte[] message = new byte[num];
in.read(message,0,num);
String inMessage = Util.bytesToHex(message);
logger.info("Full message:" + inMessage); System.out.println("Full message:" + inMessage );
return inMessage;
}
}

my proxy server doesn't work as expected

I developed a simple, multi-threaded proxy server. Note that this program is a proxy for one specific server. Here is my code :
public class Proxy {
int remotePort;
InetAddress remoteHost;
public Proxy(InetAddress remoteHost, int remotePort) {
this.remotePort = remotePort;
this.remoteHost = remoteHost;
}
public void go() {
ExecutorService pool = Executors.newCachedThreadPool();
try (ServerSocket server = new ServerSocket(2015);) {
System.out.println("Proxy is running....!");
while (true) {
Socket socketClient = server.accept();
System.out.println("client connected...!");
Socket socketServer = new Socket(remoteHost, remotePort);
System.out.println("connection established with the server...!");
Worker p1 = new Worker(socketClient, socketServer);
Worker p2 = new Worker(socketServer, socketClient);
pool.execute(p1);
pool.execute(p2);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
class Worker implements Runnable {
Socket from, to;
public Worker(Socket from, Socket to) {
this.from = from;
this.to = to;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName());
try (BufferedInputStream bis = new BufferedInputStream(from.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(to.getOutputStream());) {
while (true) {
int octet = bis.read();
if (octet == -1) {
break;
}
bos.write(octet);
}
bos.flush();
from.close();
to.close();
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
public static void main(String[] args) {
InetAddress adr = null;
try {
adr = InetAddress.getLocalHost();
} catch (UnknownHostException ex) {
System.out.println(ex.getMessage());
}
new Proxy(adr, 2020).go();
}
}
I would like to test this proxy server with a client and a server. the client sends an array of integers to find the maximum. the server of his turn, returns the maximum of a received array.
the problem is the following: the proxy server is not playing its role. the array is not sent to the server and the client not received the maximum value of its array.
The code of my Server is as follow:
public class ServerTCPMax {
static void display(int[] tab) {
for (int u : tab) {
System.out.print(u + " ");
}
System.out.println();
}
static int searchMax(int[] t) {
int max = t[0];
for (int i = 1; i < t.length; i++) {
if (t[i] > max) {
max = t[i];
}
}
return max;
}
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(2020);
System.out.println("server is running .......! ");
while (true) {
try (Socket sclient = server.accept()) {
System.out.println("Proxy connected...!");
ObjectInputStream ois = new ObjectInputStream(sclient.getInputStream());
int[] tab = (int[]) ois.readObject();
display(tab);
int max = searchMax(tab);
try (DataOutputStream dos = new DataOutputStream(sclient.getOutputStream())) {
dos.writeInt(max);
dos.flush();
}
}
}
} catch (IOException | ClassNotFoundException ex) {
System.out.println(ex.getMessage());
}
}
}
The following code represents my client:
public class ClientTCPMax {
public static void main(String[] args) {
int[] A = {3, -7, 9, 22, 0, 7, 11, 2};
try {
try (Socket socket = new Socket("127.0.0.1", 2015)) {
System.out.println("connection established with the Proxy ...!");
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(A);
oos.flush();
DataInputStream dis = new DataInputStream(socket.getInputStream());
int max = dis.readInt();
System.out.println(" the max is : " + max);
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}

TCP server madness - Slow and Merged data

I recently started to make a 2d java game, now I began the TCP server, though the server runs insanely slow (Average of 2 seconds) and I can't figure out how to stop the input stream from metering all the data into one string. I would greatly appreciate it if someone is able to help me.
ServerCode:
package com.diedericksclan.main.network;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class ServerThread extends Thread {
private ServerHandler server;
private ServerSocket dataSocket;
private Socket socket;
private InetSocketAddress address;
private int megabyte = 1024 * 1024;
private int dedicated = 1024;
public int RAM = megabyte * dedicated;
private WriteData send;
private ReadData read;
public ServerThread(ServerHandler server, String serverIP, int ram, int backlog) throws Exception {
this.server = server;
this.dedicated = ram;
//System.out.println(serverIP);
String ip = "localhost";
int port = 2048;
if(serverIP.contains(":")) {
ip = serverIP.split(":")[0];
port = Integer.parseInt(serverIP.split(":")[1]);
} else {
ip = serverIP;
port = 2048;
}
//System.out.println("Makin' the server");
this.dataSocket = new ServerSocket(port, backlog, InetAddress.getByName(ip));
this.address = new InetSocketAddress(dataSocket.getInetAddress(), port);
this.send = new WriteData();
this.read = new ReadData();
//System.out.println("Makin' the data handlers");
//System.out.println("Server has been made, details: " + address.getAddress() + ":" + address.getPort());
}
public ServerThread(ServerHandler server, String ip) throws Exception {
this(server, ip, 1024, 0);
}
public void run() {
//System.out.println("made");
this.send.start();
this.read.start();
while(true) {
try {
socket = dataSocket.accept();
socket.setReceiveBufferSize(megabyte);
socket.setSendBufferSize(megabyte);
socket.setTcpNoDelay(true);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void sendData(byte[] data, InetAddress IPaddress, int port) {
this.send.sendData(data, IPaddress, port);
}
public void serverShutdown() {
try {
this.dataSocket.close();
if(this.socket != null) this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public class WriteData extends Thread {
public WriteData() {}
public void sendData(byte[] data, InetAddress IPaddress, int port) {
try {
System.out.println("[" + System.currentTimeMillis() + "] Sending... " + new String(data));
socket.getOutputStream().write(data);
socket.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ReadData extends Thread {
public ReadData() {}
public void run() {
try {
this.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
byte[] data;
while(true) {
try {
data = new byte[megabyte];
socket.getInputStream().read(data);
System.out.println("[" + System.currentTimeMillis() + "] Server has read, " + new String(data) + ", details: " + socket.getLocalAddress().getHostName() + ":" + socket.getLocalPort());
server.parsePacket(data, socket.getInetAddress(), socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
ClientCode:
package com.diedericksclan.main.network;
import java.io.*;
import java.net.*;
public class ClientThread extends Thread {
private ClientHandler client;
private Socket socket;
private InetSocketAddress address;
private int megabyte = 1024 * 1024;
private WriteData send;
private ReadData read;
public ClientThread(ClientHandler client) {
this.client = client;
this.address = new InetSocketAddress("192.168.1.2", 2048);
socket = new Socket();
try {
socket.setSendBufferSize(megabyte);
socket.setSendBufferSize(megabyte);
socket.setTcpNoDelay(true);
socket.connect(address);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//System.out.println("Made client");
this.send = new WriteData();
this.read = new ReadData();
//System.out.println("Client has been made, details: " + socket.getLocalAddress() + ":" + socket.getLocalPort());
}
public void run() {
//System.out.println("made");
this.send.start();
this.read.start();
}
public void sendData(byte[] data) {
this.send.sendData(data);
}
public void serverShutdown() {
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public class WriteData extends Thread {
public WriteData() {}
public void sendData(byte[] data) {
try {
//System.out.println("[" + System.currentTimeMillis() + "] Sending... " + new String(data) + " to: " + socket.getInetAddress() + ":" + socket.getPort());
socket.getOutputStream().write(data);
socket.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ReadData extends Thread {
public ReadData() {}
public void run() {
byte[] data;
while(true) {
try {
data = new byte[megabyte];
socket.getInputStream().read(data);
System.out.println("[" + System.currentTimeMillis() + "] Server data recived, " + new String(data).trim());
client.parsePacket(data, socket.getInetAddress(), socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I did try to improve speed by making 2 separate threads for reading and writing data, in both the client and server, yet there was no improvement,
You have a few problems.
you allow any number of threads to write to the same socket at the same time. This makes developing a protocol very hard.
you need a protocol so you know where a message starts and end. e.g. you send the length first.
you ignore how many bytes where read. The minimum will be 1 and you can get any number of messages up to the size of the buffer at once. TCP is a stream protocol, not a messaging protocol.
If you have a reader and writer process on the same machine you should be able to get the latency to around 10 micro-seconds. (0.000010 seconds)
EDIT here is a simple example
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class PlainIOSample {
static final int RUNS = 1000000;
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(0);
DataSocket ds = new DataSocket(new Socket("localhost", ss.getLocalPort()));
DataSocket ds2 = new DataSocket(ss.accept());
long start = System.nanoTime();
for (int i = 0; i < RUNS; i++) {
// send a small message
ds.write(new byte[64]);
// receive the same message
byte[] bytes = ds2.read();
if (bytes.length != 64)
throw new AssertionError();
}
long time = System.nanoTime() - start;
System.out.printf("Average time to send/recv was %.1f micro-seconds%n",
time / RUNS / 1e3);
ds.close();
ds2.close();
}
static class DataSocket implements Closeable {
private final DataOutputStream dos;
private final DataInputStream dis;
private final Socket socket;
public DataSocket(Socket socket) throws IOException {
dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
this.socket = socket;
}
public void write(byte[] message) throws IOException {
synchronized (dos) {
dos.writeInt(message.length);
dos.write(message);
dos.flush();
}
}
public byte[] read() throws IOException {
synchronized (dis) {
int length = dis.readInt();
byte[] bytes = new byte[length];
dis.readFully(bytes);
return bytes;
}
}
#Override
public void close() throws IOException {
socket.close();
}
}
}
prints
Average time to send/recv was 3.3 micro-seconds

Categories