I just started coding a proxy for TCP Socket Connections and although i'm checking if the Sockets are still open i'm getting a IOException.
This is the LOC which is causing it. Anybody has an idea why this can happen?
while (!from.isClosed() && !to.isClosed() && (numOfBytes = in.read(byteBuffer)) != -1)
I've already debugged the code; from & to are not closed when they are checked.
for context:
Proxy.java
public class Proxy
{
public static void main(String[] args)
{
try (ServerSocket proxyServer = new ServerSocket(5432))
{
int i = 0;
while (true)
{
Socket client = proxyServer.accept();
System.out.println(i++);
Socket server = new Socket("localhost", 5000);
ProxyHandler clientToServer = new ProxyHandler(client, server);
ProxyHandler serverToClient = new ProxyHandler(server, client);
clientToServer.setName("client->server"+i);
serverToClient.setName("server->client"+i);
clientToServer.start();
serverToClient.start();
System.out.println("proxy started");
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ProxyHandler.java
public class ProxyHandler extends Thread
{
private Socket from;
private Socket to;
public ProxyHandler(Socket from, Socket to)
{
this.from = from;
this.to = to;
}
#Override
public void run()
{
try (DataInputStream in = new DataInputStream(from.getInputStream());
DataOutputStream out = new DataOutputStream(to.getOutputStream()))
{
byte[] byteBuffer = new byte[1024];
int numOfBytes = 0;
while (!from.isClosed() && !to.isClosed() && (numOfBytes = in.read(byteBuffer)) != -1)
{
out.write(byteBuffer, 0, numOfBytes);
out.flush();
System.out.println(getName() + "(" + numOfBytes + ") ");
System.out.println(new String(byteBuffer, "UTF-8"));
}
System.out.println("left : " + getName());
}
catch (IOException io)
{
System.out.println("IOException: " + io.getMessage() + " " + getName());
io.printStackTrace();
}
}
}
isClosed() only returns true if you, yourself, have explicitly closed the socket. It can not be used to detect unexpected disconnects.
Related
I am currently working on a REST server in Spring Boot that also communicates with external hardware via USB or TCP/IP. A command is sent to the external device, then I wait 2 seconds for the response and return it to the RestController.
For the USB communication I am currently using jSerialComm. For the TCP/IP communication I use sockets.
The whole thing also works so far when I use Thread.sleep. However, I would prefer it to be more dynamic, i.e. without the sleep, because TCP/IP can cause delays.
For me Java and REST are still new. Is there a way to let the server communicate asynchronously with the hardware?
#RestController
#RequestMapping("/api/v1")
public class CommController {
#GetMapping("/Version")
public String getVersion() {
Serial serial = new Serial();
String s_response = null;
s_response = serial.getVersion();
return s_response;
}
#GetMapping("/VersionTCPIP")
public String getVersionTCPIP() {
Serial serial = new Serial();
String s_response = null;
s_response = serial.getVersionTCPIP();
return s_response;
}
}
USB/serial-class:
public class Serial {
private static SerialPort port;
private static List<Byte> l_readBuffer;
private static final class MessageListener implements SerialPortDataListener
{
#Override
public int getListeningEvents()
{
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
#Override
public void serialEvent(SerialPortEvent event)
{
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE)
return;
byte[] newData = new byte[port.bytesAvailable()];
int numRead = port.readBytes(newData, newData.length);
for (int i = 0; i < numRead; i++)
{
l_readBuffer.add(newData[i]);
}
System.out.println("Read " + numRead + " bytes.");
}
}
public String getVersion() {
SerialPort[] ports = SerialPort.getCommPorts();
port = null;
for (SerialPort currentPort :
ports)
{
if (currentPort.getDescriptivePortName().contains("XXX"))
{
port = currentPort;
break;
}
}
Objects.requireNonNull(port).setBaudRate(9600);
port.setParity(SerialPort.NO_PARITY);
port.setNumStopBits(SerialPort.ONE_STOP_BIT);
port.setNumDataBits(8);
port.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
//port.clearRTS();
port.setComPortTimeouts(SerialPort.LISTENING_EVENT_DATA_AVAILABLE, 5000, 5000);
port.openPort();
MessageListener listener = new MessageListener();
port.addDataListener(listener);
l_readBuffer = new ArrayList<>();
byte[] sendBuffer = new byte[5];
// fill sendBuffer
port.writeBytes(sendBuffer, sendBuffer.length);
try
{
Thread.sleep(2000);
} catch (Exception e)
{
e.printStackTrace();
}
System.out.println("Data raw: " + l_readBuffer.toString());
byte[] ba_responseBuffer = new byte[l_readBuffer.size()];
for (int i = 0; i < l_readBuffer.size(); i++)
{
ba_responseBuffer[i] = l_readBuffer.get(i);
}
String s_version = new String(ba_responseBuffer);
System.out.println("Version: " + s_version);
port.removeDataListener();
port.closePort();
return s_version;
}
public String getVersionTCPIP()
{
Socket socket;
String s_versionString = null;
try
{
socket = new Socket();
socket.connect(new InetSocketAddress(s_hostnameTCPIP, i_port), 1000);
byte[] ba_sendBuffer = new byte[1024];
Arrays.fill(ba_sendBuffer, (byte) 0x00);
// fill sendBuffer
// send data
DataOutputStream dOut = new DataOutputStream(socket.getOutputStream());
dOut.write(ba_sendBuffer); // write the message
dOut.writeInt(i_sendLength); // write length of the message
dOut.flush();
try
{
Thread.sleep(2000);
} catch (Exception e)
{
e.printStackTrace();
}
byte[] ba_responseBuffer = new byte[0];
if (socket.isConnected())
{
try
{
InputStream inFromServer = socket.getInputStream();
DataInputStream dIn = new DataInputStream(inFromServer);
synchronized (dIn)
{
int length = dIn.available();
ba_responseBuffer = new byte[length];
// receive data
dIn.readFully(ba_responseBuffer);
}
} catch (IOException ex)
{
ex.printStackTrace();
}
String s_version = new String(ba_responseBuffer);
System.out.println("Version: " + s_version);
s_versionString = s_version;
socket.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
return s_versionString;
}
}
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;
}
}
I have to write a socket program to communicate with a server on a given port and DNS. The communication can be a single message or a list of messages; against every message a response is generated from the server. Once a connection is made I receive a response for the first message, but on the next message receive a response of -1. The following is the class handling client server communication:
public class SocketCommunication {
static String[] adresses = null;
final static int port = 1234;
final static int timeout = 60000;
static long pbmId;
private static int count = 0;
private static void loadPBMDNS()
{
DynamicQuery pbmQuery = PH_PBM_SwitchLocalServiceUtil.dynamicQuery();
pbmQuery.add(RestrictionsFactoryUtil.eq("Activated", true));
try
{
List<PH_PBM_Switch> pbmList = PH_PBM_SwitchLocalServiceUtil.dynamicQuery(pbmQuery);
if(pbmList != null && pbmList.size() > 0)
{
if(pbmList.get(0).getServer_DNS() != null
&& !pbmList.get(0).getServer_DNS().equals(""))
{
pbmId = pbmList.get(0).getPBM_Switch_Id();
if(pbmList.get(0).getServer_DNS().contains(";"))
{
String[] tokens = pbmList.get(0).getServer_DNS().split(";");
System.out.println(tokens.toString());
adresses = tokens;
}
else
{
adresses[0] = pbmList.get(0).getServer_DNS();
}
}
}
}
catch (SystemException e)
{
e.printStackTrace();
}
}
public static ArrayList<BatchClaimVO> ConnectSendAndReadResponse
(int addressNumber, ArrayList<BatchClaimVO> batchClaimVOs)
{
try
{
loadPBMDNS();
System.out.println("Connecting to " + adresses[addressNumber] + " on port " + port);
SocketFactory sslsocketfactory = SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket();
sslsocket.connect(new InetSocketAddress(adresses[addressNumber], port), timeout);
System.out.println("Just connected to " + sslsocket.getRemoteSocketAddress());
for (int i = count; i < batchClaimVOs.size(); i++)
{
sendClaim(
sslsocket,
batchClaimVOs.get(i).getCb(),
batchClaimVOs.get(i).getUniqueIdentifier()
);
if(addressNumber <= 2)
{
batchClaimVOs.get(i).setResponse
(readResponse(sslsocket, addressNumber, batchClaimVOs.get(i).getCb()));
}
}
System.out.println("Closing socket");
count = 0;
sslsocket.close();
return batchClaimVOs;
}
catch (IOException e)
{
if(addressNumber < 2)
{
System.out.println("connection timedout trying again on new DNS");
ConnectSendAndReadResponse(++addressNumber, batchClaimVOs);
}
else
{
System.out.println
("unable to connect to server or server did not responed intime");
e.printStackTrace();
}
}
return null;
}
public static void sendClaim(SSLSocket sslSocket, ClaimBuilder cb, long uniqueIdentifier)
throws IOException
{
System.out.println("sending claim");
OutputStream outToServer = sslSocket.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeBytes(cb.getClaim());
System.out.println("claim sent");
SaveRequestLog(uniqueIdentifier, cb.getClaim(), pbmId);
}
public static void SaveRequestLog(long uniqueIdentifier, String claim, long pbmId)
{
if(uniqueIdentifier > 0)
{
try
{
PH_Request_Transaction_Log log = PH_Request_Transaction_LogLocalServiceUtil.getPH_Request_Transaction_Log(uniqueIdentifier);
log.setPBM_Switch_Id(pbmId);
log.setRequest_Log(claim);
log.setCreated_By(LiferayFacesContext.getInstance().getUserId());
log.setCreated_Date(Calendar.getInstance().getTime());
PH_Request_Transaction_LogLocalServiceUtil.updatePH_Request_Transaction_Log(log);
}
catch (PortalException e)
{
e.printStackTrace();
}
catch (SystemException e)
{
e.printStackTrace();
}
}
}
public static String readResponse(SSLSocket sslSocket, int addressNumber, ClaimBuilder cb)
throws IOException
{
sslSocket.setSoTimeout(timeout);
InputStream inFromServer = sslSocket.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
byte[] data = new byte[1048];
int count = in.read(data);
System.out.println(count);
System.out.println(new String(data));
String response = fixString(new String(data), count);
System.out.println("Verifying checksum");
if(verifyTransmissionCheckSum(response))
{
System.out.println("checksum verified");
System.out.println(response);
}
else
{
System.out.println("transmission corrupted");
}
sendAcknowledgement(sslSocket, cb);
return response;
}
public static void sendAcknowledgement(SSLSocket sslSocket, ClaimBuilder cb)
throws IOException
{
System.out.println("sending Acknowledgement");
OutputStream outToServer = sslSocket.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeBytes(cb.buildClaimAcknowledgement());
System.out.println("Acknowledgement Sent");
count++;
}
public static String fixString(String toFix, int count)
{
return toFix.substring(0, count);
}
public static boolean verifyTransmissionCheckSum(String str)
{
return (Integer.parseInt((String) str.subSequence(0, 4))
== (str.subSequence(4, str.length())).length())
? true : false;
}
}
The given server do not support batch communication.
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());
}
}
}
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