How to implement TCP connection pooling in java? [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Here, I managed to get a connection between a single server and single client but now my new hurdle is how to achieve a pool of TCP connections on client side in Java. I have gone through many sites, but at the end no fruitful solution was found. Here the class which I had used for obtaining connection to a server:
public class TCPIPCommunicator {
private final String MODULE="TCPIPCommunicator :";
//private DeviceEntity deviceEntity;
private static InetAddress inetServer = null;
private static int devicePort = -1;
private Socket clientSocket;
private BufferedOutputStream outputStream;
private BufferedInputStream inputStream;
private static boolean isLinkActive = false;
private String IP="";
public TCPIPCommunicator(String IP, int devicePort) {
this.IP=IP;
this.devicePort=devicePort;
initialize();
}
public static boolean isLinkActive(){
return isLinkActive;
}
public static void setLinkStatus(boolean status){
isLinkActive = status;
}
private void initialize() {
System.out.println(MODULE+ "Inside initialize()" );
setLinkStatus(false);
try{
inetServer = InetAddress.getByName(IP);
}catch (UnknownHostException uhe) {
System.out.println(MODULE+ "Error while creating inetaddress, Reason:"+uhe.getMessage());
}
System.out.println(MODULE+ "Connecting to - " +inetServer.getHostAddress() + ":" + devicePort);
establishConnection();
if(!isLinkActive()){
//sendNotification(TCPIPConstants.LINK_DOWN);
releaseResources();
//resumeLinkSanityHelper();
}
System.out.println(MODULE+ "out of initialize(), isLinkActive :" + isLinkActive() );
}
public boolean establishConnection(){
boolean isConnected = false;
//Get the Connection to PMS Server.
if(inetServer != null && devicePort > 0){
try{
clientSocket = new Socket(inetServer, devicePort);
clientSocket.setKeepAlive(true);
}catch(ConnectException ce){
ce.printStackTrace();
setLinkStatus(false);
System.out.println(MODULE+ "Exception in initialize() " + "Couldnot Connect Server. Reason:"+ce.getMessage());
}catch(Exception e){
e.printStackTrace();
setLinkStatus(false);
System.out.println(MODULE+ "Exception in initialize() " + "while creating socket ,Reason: " + e.getMessage());
}
//If got connection, Get the streams.
if(clientSocket != null && !clientSocket.isClosed()){
System.out.println(MODULE+ "in initialize(), Got Socket Connection." );
try{
outputStream = new BufferedOutputStream(clientSocket.getOutputStream());
}catch(Exception e){
e.printStackTrace();
outputStream=null;
setLinkStatus(false);
System.out.println(MODULE+ "Exception in initialize() while getting socket outputStream : " + e.getMessage());
}
if(outputStream != null){
try{
inputStream = new BufferedInputStream(clientSocket.getInputStream());
}catch(Exception e){
setLinkStatus(false);
System.out.println(MODULE+ "Exception in initialize() " + "while getting socket inputStream : " + e.getMessage());
}
setLinkStatus(true);
}
if(outputStream != null && inputStream != null){
isConnected = true;
}
}else{
System.out.println(MODULE+ "in initialize(), Connection is closed or null." );
setLinkStatus(false);
}
}
return isConnected;
}
public int writeData(byte[] msg){
int retValue = -1;
try{
if(isLinkActive() && (outputStream !=null)){
System.out.println(MODULE+ "Writting data ::::" + new String(msg)+ "::::");
outputStream.write(msg);// ed
outputStream.flush();
retValue = 1;
}else{
System.out.println(MODULE+ " in writeData() link is down so status:" + retValue );
}
}catch(Exception e){
e.printStackTrace();
retValue = -1;
System.out.println(MODULE+ "Exception in write() < message to be sent was = " + new String(msg) + " > : " + e.getMessage());
}
if(retValue == -1 && isLinkActive()){
setLinkStatus(false);
//sendNotification(TCPIPConstants.LINK_DOWN);
//releaseResources();
//resumeLinkSanityHelper();
}
System.out.println(MODULE+ " in writeData() Write status for ::"+ new String(msg) + ":: -->" +retValue);
return retValue;
}
public String readData() {
System.out.println(MODULE+"\tInside readDAta");
String response = null;
int bytesReceived=-1;
byte[] readBuffer = new byte[1024];
try{
long timetoread = System.currentTimeMillis();
if(inputStream == null || !(isLinkActive())){
System.out.println(MODULE+"Inputstream is null or link is down, returning null");
return null;
}
try{
System.out.println("Waiting to read data");
bytesReceived = inputStream.read(readBuffer);
System.out.println(MODULE+"# Byte Receieved #" + bytesReceived);
}catch(Exception e){
e.printStackTrace();
System.out.println(MODULE+"Error in readData() , Reason:"+e.getMessage());
if(isLinkActive()){
setLinkStatus(false);
//sendNotification(TCPIPConstants.LINK_DOWN);
releaseResources();
//resumeLinkSanityHelper();
}
}
if(bytesReceived > 0){
response = new String(readBuffer,0,bytesReceived); // ed
timetoread = System.currentTimeMillis() - timetoread;
System.out.println(MODULE + "Total Bytes Received: " + bytesReceived);
System.out.println(MODULE+ "Total Time Taken : " + timetoread);
System.out.println(MODULE+ "Length of data received : " + response.length());
System.out.println(MODULE+ "Data Received : ####" + response + "####");
}else{
////////// HERE MEANS TCP CONNECTION STATUS WILL CLOSE_WAIT
////////// SO RELEASING CONNECTION.
System.out.println(MODULE+ " Releasing Resource. bytesReceived is <= 0 : Total Bytes Received :"+ bytesReceived );
if(isLinkActive()){
setLinkStatus(false);
//sendNotification(TCPIPConstants.LINK_DOWN);
releaseResources();
//resumeLinkSanityHelper();
}
System.out.println(MODULE+ " Resource has been released.");
}
}catch(Exception e){
e.printStackTrace();
System.out.println(MODULE+ "In catch : Data Received : ####" + response + "####");
System.out.println(MODULE+ "Exception in readdata() : " + e);
}finally{
readBuffer=null;
}
return response;
}
public void releaseResources(){
System.out.println(MODULE+ "Releasing Resources....");
try{
if(clientSocket !=null)
clientSocket.close();
}catch(Exception e){
System.out.println(MODULE+ "In releaseResources() :Error closing socket."+e.getMessage());
}
try{
if(inputStream !=null )
inputStream.close();
}catch(Exception e){
System.out.println(MODULE+ "In releaseResources() :Error closing inputStream."+e.getMessage());
}
try{
if(outputStream != null){
outputStream.close();
}
}catch(Exception e){
System.out.println(MODULE+ "in releaseResources() :Error closing outputStream.");
}
System.out.println(MODULE + "Resources Relased...");
}
}
Here establishConnection() method will be establish the connection to the server.
Note: I was thinking on using ThreadPoolExecutor, but as the requirement is for synchronous, I dropped this idea of using it.

The sample code is like below,I use a Map ,the key is "host-port" ,and the value is a LinkedList containing the sockets related to the same url.
public class SocketPool{
Map<String,LinkedList<Socket>> sockets;
public boolean establishConnection(String inetServer , int devicePort){
boolean result = false;
try {
Socket clientSocket = new Socket(inetServer, devicePort);
String socketKey = inetServer + "-" + devicePort;
if(clientSocket.isConnected()&&sockets.containsKey(socketKey)){
sockets.get(socketKey).add(clientSocket);
}else if(clientSocket.isConnected()&&!sockets.containsKey(socketKey)){
LinkedList<Socket> socketSet = new LinkedList<Socket>();
socketSet.add(clientSocket);
sockets.put(socketKey, socketSet);
}
result = true;
} catch (UnknownHostException e) {
result = false;
} catch (IOException e) {
result = false;
}
return result;
}
public Socket fetchSocket(String inetServer , int devicePort){
String socketKey = inetServer + "-" + devicePort;
Socket clientSocket =null;
if(sockets.containsKey(socketKey)&&!sockets.get(socketKey).isEmpty()){
clientSocket = sockets.get(socketKey).removeLast();
int size = sockets.get(socketKey).size();
if(size==0){
sockets.remove(socketKey);
}
}
return clientSocket;
}
//other functions
}

You can create a variable Set<Socket> to store all the client Sockets you created. Every time you connect to the server socket you can put the client
socket into this set. This set works as the pool.

Related

Python Socket Only get information when the socket is closed

I am creating a program to play chess through the socket. My client is written in Python which is using socket to send data to the server. I receive information only when client program gets closed. Below mentioned is the client code. I am using python socket https://docs.python.org/3/library/socket.html
def youSecond(board):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.11.46', 9999))
run = True
turn = 1
new_msg = True
while run:
renderMap(board)
move = s.recv(1024).decode("utf-8")
if new_msg:
new_msg = False
print("SERVER: ", move)
players[0].play(board, move)
new_msg = True
turn +=1
renderMap(board)
print("Black machine is thinking.....")
myTurn = players[1].play(board, turn).encode("utf-8")
s.send(myTurn)
turn += 1
and my server using Java
public class ClientHandler implements Runnable {
BufferedReader reader;
Socket sock;
PrintWriter client;
public ClientHandler(Socket clientSocket, PrintWriter user) {
client = user;
try {
sock = clientSocket;
InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(isReader);
System.out.println("tren helllo");
} catch (Exception ex) {
ta_chat.append("Unexpected error... \n");
}
}
#Override
public void run() {
String message, connect = "Connect", disconnect = "Disconnect", chat = "Chat";
String[] data;
try {
while ((message = reader.readLine()) != null) {
System.out.println("duoi helllo");
ta_chat.append("Received: " + message + "\n");
data = message.split(":");
for (String token : data) {
ta_chat.append(token + "\n");
}
if (data[2].equals(connect)) {
tellEveryone((data[0] + ":" + data[1] + ":" + chat));
userAdd(data[0]);
} else if (data[2].equals(disconnect)) {
tellEveryone((data[0] + ":has disconnected." + ":" + chat));
userRemove(data[0]);
} else if (data[2].equals(chat)) {
tellEveryone(message);
try {
FileWriter fw = new FileWriter("C:\\Users\\Admin\\Desktop\\FixCoTuong\\moves.txt");
fw.write(data[1]);
fw.close();
} catch (Exception e) {
System.out.println(e);
}
System.out.println("sucess");
} else {
ta_chat.append("No Conditions were met. \n");
}
}
} catch (Exception ex) {
ta_chat.append("Lost a connection. \n");
ex.printStackTrace();
clientOutputStreams.remove(client);
}

Java Socket programming: Client receives " " instead of id

I'm writing a simple chat program using sockets. The program works as clients connect to the server and before they start chatting, they send their name to the server and receive an unique id on the return. This is where my code doesn't work properly.
Here's my code in Client class which sends name and receives id:
private void exchangeInformation() {
String temp;
try {
writer.println(name);
temp = reader.readLine();
System.out.println(temp);
temp = reader.readLine();
System.out.println("id has been received : "
+ temp);
this.id = Integer.parseInt(temp);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't get id from server\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
And here's the code in server side which receives name and sends id:
private void exchangeInformation() {
try {
String n = reader.readLine();
setUserName(n);
System.out.println("name has been received");
writeMessage("Server: Welcome " + userName + "\n");
writeMessage(userId);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't receive client's name\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
and this is writeMessage method on the server side:
public synchronized void writeMessage(String message) {
writer.println(message);
}
In both sides, writer is an object of PrintWriter and reader is an object of BufferedReader.
Well, the problem is, when I send userId to the client, client receives "" instead of proper data. the other parts of code work fine.
What is the problem and how can I fix it?
Regards
EDIT: As suggested in comments, All code:
Client class:
public class Client {
private String name;
private int id;
private boolean isConnected;
private BufferedReader reader;
//private BufferedWriter writer;
private PrintWriter writer;
private Socket socket;
public Client(String name) {
this.name = name;
}
public boolean getIsConnected() {
return isConnected;
}
public BufferedReader getReader() {
return reader;
}
public void start() {
connect();
exchangeInformation();
new ReceiveFromServer(this).start();
String output;
Scanner in = new Scanner(System.in);
while (isConnected) {
System.out.println("YOU: ");
output = in.nextLine();
writer.print(name + " : " + output);
}
try {
socket.close();
reader.close();
writer.close();
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't close content(s)\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
private void connect() {
System.out.println("Trying to connect to the server...\n");
try {
socket = new Socket("localhost", 4444);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: User " + name + " couldn't connetct to the server\n"
+ "Cause: " + e.getMessage() + "\n");
}
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't get socket's InputStream or OutputStream\n"
+ "Cause: " + e.getMessage());
}
System.out.println("You have cnnected to the server successfully");
}
private void exchangeInformation() {
String temp;
try {
writer.println(name);
temp = reader.readLine();
System.out.println(temp);
temp = reader.readLine();
System.out.println("id has been received : "
+ temp);
this.id = Integer.parseInt(temp);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't get id from server\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
}
Server class:
public class Server {
private static Server server = new Server(4444);
private final int PORT;
private List<ClientThread> clients;
private static int counter;
private ServerSocket ss;
private boolean isListening;
private Server(int port) {
this.PORT = port;
clients = new ArrayList<>();
counter = 0;
}
public static Server getServerInstance() {
return server;
}
private int generateId() {
return ++counter;
}
public void start() {
establishConnection();
while (isListening) {
System.out.println("Server is Listening...");
Socket s = null;
try {
s = ss.accept();
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: An error occured while accepting a request\n"
+ "Cause: " + e.getMessage());
}
System.out.println("New connection request has been accepted\n");
ClientThread client = new ClientThread(s, this.generateId());
clients.add(client);
client.start();
}
try {
ss.close();
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't close Server Socket\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
public static synchronized void broadcastMessage(String message) {
Server s = getServerInstance();
for (int i = 0; i < s.clients.size(); i++) {
s.clients.get(i).writeMessage(message);
}
}
private void establishConnection() {
try {
ss = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't establish server socket for connection\n"
+ "Cause: " + e.getMessage() + "\n");
}
System.out.println("Server Socket has been created Successfully\n");
isListening = true;
}
public static void removeClient(int id) {
Server s = getServerInstance();
for (int i = 0; i < s.clients.size(); i++) {
if (id == s.clients.get(i).getId()) {
s.clients.remove(i);
break;
}
}
}
}
ClientThread class:
public class ClientThread extends Thread {
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
private int userId;
private String userName;
private boolean isConnected;
public ClientThread(Socket socket, int id) {
this.socket = socket;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't get socket's InputStream or OutputStream\n"
+ "Cause: " + e.getMessage());
}
this.userId = id;
}
public void setUserName(String name) {
this.userName = name;
}
public void setIsConnected(boolean flag) {
isConnected = flag;
}
public BufferedReader getReader() {
return reader;
}
public int getUserId() {
return userId;
}
#Override
public void run() {
exchangeInformation();
isConnected = true;
String input;
while (isConnected) {
try {
input = reader.readLine();
if (input != null) {
if (input.equalsIgnoreCase("logout")) {
logout();
} else {
Server.broadcastMessage(input);
}
}
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't receive message from client\n"
+ "Cause: " + e.getMessage() + "\n");
isConnected = false;
}
}
}
public synchronized void writeMessage(String message) {
writer.println(message);
}
public void writeMessage(int message) {
writer.println(message);
}
private void logout() {
setIsConnected(false);
try {
socket.close();
reader.close();
writer.close();
System.out.println("User " + this.userId + " has loggedout"
);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't close content(s)\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
private void exchangeInformation() {
try {
String n = reader.readLine();
setUserName(n);
System.out.println("name has been received");
writeMessage("Server: Welcome " + userName + "\n");
writeMessage(userId);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't receive client's name\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
}

Socket and InputStream => Connection reset by peer exception

I'm trying to stream an InputStream's data to a socket that acts as proxy. The reason for that is, that I want to play InputStreams via the android MediaPlayer.
The problem is I always get a endto failed: ECONNRESET (Connection reset by peer) exception:
com.prom.gallery.classes.VideoProxy: [VideoProxy-172] sendto failed: ECONNRESET (Connection reset by peer)
java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer)
at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
at libcore.io.IoBridge.sendto(IoBridge.java:515)
at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
at com.prom.gallery.classes.VideoProxy.processRequest(VideoProxy.java:168)
at com.prom.gallery.classes.VideoProxy.run(VideoProxy.java:110)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.ErrnoException: sendto failed: ECONNRESET (Connection reset by peer)
at libcore.io.Posix.sendtoBytes(Native Method)
at libcore.io.Posix.sendto(Posix.java:176)
at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
at libcore.io.IoBridge.sendto(IoBridge.java:513)
at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504) 
at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37) 
at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266) 
at com.prom.gallery.classes.VideoProxy.processRequest(VideoProxy.java:168) 
at com.prom.gallery.classes.VideoProxy.run(VideoProxy.java:110) 
at java.lang.Thread.run(Thread.java:818) 
Question
How can I solve that? My solution is appended and is based on https://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java... I found out I may need a header to keep the socket open, but I don't really know if that's true and how to add that to my solution...
My custom class IDownloadableMedia just directly returns a simple stream...
I have multiple sources with videos, some of them allow streams only. For testing I use a source that works with urls as well and I create an InputStream like following in the download function: new URL(url).openStream(). The url is valid and working!
Code
Here's my VideoProxy class:
public class VideoProxy implements Runnable
{
public static String createProxyString(VideoProxy proxy, int folderIndex, int mediaIndex, String uniqueId)
{
return String.format("http://127.0.0.1:%d/%s", proxy.getPort(), folderIndex + "-" + mediaIndex + "-" + uniqueId);
}
private int port = 0;
public int getPort()
{
return port;
}
private boolean mIsRunning = true;
private ServerSocket mSocket;
private Thread mThread;
public void init()
{
try
{
mSocket = new ServerSocket(port, 0, InetAddress.getByAddress(new byte[] {127, 0, 0, 1}));
mSocket.setSoTimeout(5000);
port = mSocket.getLocalPort();
L.d(this, "Port " + port);
}
catch (UnknownHostException e)
{
L.e(this, e);
}
catch (IOException e)
{
L.e(this, e);
}
}
public void start()
{
if (mSocket == null)
throw new IllegalStateException("Proxy has not been initialized!");
mThread = new Thread(this);
mThread.start();
}
public void stop()
{
mIsRunning = false;
if (mThread != null)
{
mThread.interrupt();
try
{
mThread.join(5000);
}
catch (InterruptedException e)
{
L.e(this, e);
}
}
}
#Override
public void run()
{
L.d(this, "Run...");
while (mIsRunning)
{
try
{
Socket client = mSocket.accept();
if (client == null)
continue;
L.d(this, "client connected");
// get data
String data = readData(client);
L.d(this, "data: " + data);
String splitted[] = data.split("-");
int folderIndex = Integer.parseInt(splitted[0]);
int mediaIndex = Integer.parseInt(splitted[1]);
String uniqueId = splitted[2];
L.d(this, "data splitted: " + folderIndex + ", " + mediaIndex + ", " + uniqueId);
// get media file
IDownloadableMedia media = (IDownloadableMedia)RXManager.get().createLoadedSingleFolderObservable(null, null, folderIndex).toBlocking().first().getMedia().get(mediaIndex);
L.d(this, "media: " + media.getMediaFolder().getName() + " | " + media.getName());
// download media file
processRequest(client, media);
}
catch (SocketTimeoutException e)
{
// Do nothing
}
catch (IOException e)
{
L.e(this, e);
}
}
L.d(this, "Proxy interrupted - shutting down...");
}
private String readData(Socket client)
{
InputStream is;
String firstLine;
try
{
is = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
firstLine = reader.readLine();
}
catch (IOException e)
{
L.e(this, e);
return null;
}
if (firstLine == null)
{
L.d(this, "Proxy client closed connection without a request.");
return null;
}
StringTokenizer st = new StringTokenizer(firstLine);
String method = st.nextToken();
String uri = st.nextToken();
L.d(this, uri);
String realUri = uri.substring(1);
L.d(this, realUri);
return realUri;
}
private void processRequest(Socket client, IDownloadableMedia downloadableMedia) throws IllegalStateException, IOException
{
if (downloadableMedia == null)
return;
L.d(this, "downloading...");
InputStream data = downloadableMedia.download();
try
{
int readBytes = -1;
// Stream content...
byte[] buff = new byte[1024 * 50];
while (mIsRunning && (readBytes = data.read(buff, 0, buff.length)) != -1)
client.getOutputStream().write(buff, 0, readBytes);
}
catch (Exception e)
{
L.e(this, e);
}
finally
{
if (data != null)
data.close();
client.close();
}
}
}

JAVA TCP client not printing and disconnecting

I have a TCP server and client, but the client never prints the last system.out and disconnects from server socket.
My client message loop:
for (int i = 1; i <= Integer.parseInt(args[2]); i++) {
long messageTimeStart = System.currentTimeMillis();
outToServer.write(MSG.getBytes());
outToServer.flush();
Thread.sleep((long) messageTimePerSecond);
long messageTimeEnd = System.currentTimeMillis();
long totalMessageTime = messageTimeEnd - messageTimeStart; //Meassure total packet transfer time.
System.out.println("Message " + i + ": '" + MSG + "' sent in: " + totalMessageTime);
elapsedTime += totalMessageTime;
}
while (true) {
try {
int msgLength = serverEcho.read(buf);
if (msgLength == -1) {
break;
}
String echoMessage = new String(buf);
System.out.println("ECHO MESSAGE: " + echoMessage);
} catch (IOException e) {
System.out.println("Hot damn");
}
}
System.out.printf(args[2] + " Messages sent in: " + elapsedTime + " milliseconds.");
outToServer.close();
serverEcho.close();
socket.close();
It never gets to the four last lines for some reason. And I have no Idea why.
If it matters, here is my Server class run method:
public void run() {
try {
while (true) {
try {
inFromClient = new DataInputStream(clientSocket.getInputStream());
outToClient = new DataOutputStream(clientSocket.getOutputStream());
//InputStream in = clientSocket.getInputStream();
//DataInputStream dis = new DataInputStream(in);
int msgLength = 0;
msgLength = inFromClient.read(dataBuffer);
String message = new String(dataBuffer);
System.out.println("Message recieved: " + message);
outToClient.write(message.getBytes(), 0, msgLength);
outToClient.flush();
System.out.println("Echo message sent: " + message);
} catch (SocketException e) {
System.out.println("Connection terminated by client.");
break;
}
}
clientSocket.close();
} catch (IOException e) {
System.out.println("Could not listen on port: " + clientSocket.getLocalPort());
System.out.println("Client thread terminated.");
}
}
You already know the amount of data that the server will return to you since the server is returning the same information that the client is sending to him.
Therefore, you could try this approach:
Server
#Override
public void run() {
ServerSocket serverSocket = null;
Socket clientSocket = null;
DataInputStream inFromClient = null;
DataOutputStream outToClient = null;
try {
serverSocket = new ServerSocket(4321);
} catch (IOException ioe) {
System.out.println("Could not listen on port 4321. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Server#listening on port 4321!");
try {
clientSocket = serverSocket.accept();
} catch (IOException ioe) {
System.out.println("Accept failed on port: 4321. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Server#accepting connections on port 4321!");
try {
inFromClient = new DataInputStream(clientSocket.getInputStream());
outToClient = new DataOutputStream(clientSocket.getOutputStream());
} catch (IOException ioe) {
System.out.println("Input and output streams creation failed. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Server#created input and output streams!");
byte[] dataBuffer = new byte[1024];
try {
while (true) {
try {
int msgLength = 0;
msgLength = inFromClient.read(dataBuffer);
String message = new String(dataBuffer);
System.out.println("Message recieved: " + message);
outToClient.write(message.getBytes(), 0, msgLength);
outToClient.flush();
System.out.println("Echo message sent: " + message);
} catch (SocketException e) {
System.out.println("Connection terminated by client.");
break;
}
}
clientSocket.close();
} catch (IOException e) {
System.out.println("Could not listen on port: " + clientSocket.getLocalPort());
System.out.println("Client thread terminated.");
} finally {
try {
outToClient.close();
inFromClient.close();
clientSocket.close();
serverSocket.close();
} catch (IOException ioe) {
System.out.println("Unable to close streams and sockets. Cause: " + ioe);
System.exit(-1);
}
}
}
Client
#Override
public void run() {
String MSG = "Hello from client, mister server!";
Socket socket = null;
DataOutputStream outToServer = null;
DataInputStream inFromServer = null;
try {
socket = new Socket("localhost", 4321);
} catch (IOException ioe) {
System.out.println("Unable to connect with host: localhost. Cause: " + ioe);
System.exit(1);
}
System.out.println("#Client#connected with server localhost on port 4321!");
try {
outToServer = new DataOutputStream(socket.getOutputStream());
inFromServer = new DataInputStream(socket.getInputStream());
} catch (IOException ioe) {
System.out.println("Input and output streams creation failed. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Client#created input and output streams!");
long messageTimePerSecond = 3000;
long elapsedTime = 0;
try {
for (int it = 0; it < 5; it++) {
long messageTimeStart = System.currentTimeMillis();
outToServer.write(MSG.getBytes());
outToServer.flush();
Thread.sleep((long) messageTimePerSecond);
long messageTimeEnd = System.currentTimeMillis();
// Measure total packet transfer time.
long totalMessageTime = messageTimeEnd - messageTimeStart;
System.out.println("Message " + it + ": '" + MSG + "' sent in: " + totalMessageTime);
elapsedTime += totalMessageTime;
}
byte[] dataBuffer = new byte[1024];
String echoMessage = "";
int msgLength = 0;
int totalData = MSG.length();
boolean finish = false;
while (!finish) {
try {
msgLength = inFromServer.read(dataBuffer);
echoMessage += new String(dataBuffer, 0, msgLength);
if (echoMessage.length() == totalData) {
finish = true;
}
System.out.println("ECHO MESSAGE: " + echoMessage);
} catch (IOException e) {
System.out.println("Hot damn");
}
}
} catch (IOException | InterruptedException e) {
System.out.println("Something bad happened. Cause: " + e);
System.exit(-1);
} finally {
System.out.printf("5 Messages sent in: " + elapsedTime + " milliseconds.");
try {
inFromServer.close();
outToServer.close();
socket.close();
} catch (IOException ioe) {
System.out.println("Unable to close streams and socket. Cause: " + ioe);
System.exit(-1);
}
}
}
Both Server and Client implement Runnable and your main class can be like this:
public class ClientServerMain {
public static void main(String[] args) {
Thread server = new Thread(new Server());
server.start();
Thread client = new Thread(new Client());
client.start();
}
}

Send array via a socket using ObjectInputStream

I'm trying to send the contents of a string array via a socket and then print the array items out at the other end.
I've been trying to use ObjectInputStream but have had no luck. If I'm honest I've scoured the web but I still don't really know what I'm doing.
Client
Putting objects into the array
String[] sendServer = new String [4];
{
sendServer[0] = txtUsername.getText();
sendServer[1] = dateFormat.format(date);
sendServer[2] = txtMessageOut.getText();
sendServer[3] = "I HOPE THIS WORKS!!!";
}
The socket has been created in another method and I can out, just unsure if if this is correct?
ObjectOutputStream objectStream = new ObjectOutputStream(clientSocket.getOutputStream());
objectStream.writeObject(sendServer);
System.out.println(sendServer[0]);
System.out.println(sendServer[1]);
System.out.println(sendServer[2]);
And for the server I have no clue. I've been trying with the ObjectInputStream with no luck. The socket on the server is just called socket.
Any help or pointers would be greatly appreciated.
I want to give you a code snippet. Sender and reveiver use socket to communicate. Replace Request with your data structure and eliminate the code lines you don't need.
This is sender :
private Response doUnicastTCP(Server remoteServer, Request request) throws ServerException {
Socket clientSocket = null;
ObjectOutputStream outToServer = null;
ObjectInputStream inFromServer = null;
try {
if (isStarted()) {
request.setRequestType(RequestType.UNICAST_TCP);
// LOGGER.debug("Sending " + request.getRequestType() + " "
// + request);
clientSocket = new Socket(remoteServer.getHost(), remoteServer.getUnicastTCPPort());
clientSocket.setSoTimeout(request.getTimeout());
outToServer = new ObjectOutputStream(clientSocket.getOutputStream());
inFromServer = new ObjectInputStream(clientSocket.getInputStream());
outToServer.writeObject(request);
Response response = (Response) inFromServer.readObject();
// LOGGER.debug("Received " + request.getRequestType() + " "
// + response);
if (response.getReturnValue() instanceof Exception) {
throw new ServerException((Exception) response.getReturnValue());
}
return response;
} else {
throw new ServerNotStartedException();
}
} catch (SocketTimeoutException e) {
throw new ServerException("cant execute request " + request + " on server " + remoteServer + " "
+ e.toString());
} catch (ClassNotFoundException | IOException e) {
throw new ServerException("cant execute request " + request + " on server " + remoteServer + " "
+ e.toString());
} finally {
try {
if (clientSocket != null) {
clientSocket.close();
}
} catch (IOException e) { //
LOGGER.trace("socket couldn't be closed");
}
}
}
This is receiver :
public void run() {
Request r = null;
try {
ObjectInputStream inFromClient = new ObjectInputStream(s.getInputStream());
ObjectOutputStream outToClient = new ObjectOutputStream(s.getOutputStream());
while (isStarted()) {
final Object receivedObject = inFromClient.readObject();
// LOGGER.debug("Receiving "
// + ((Request) receivedObject).getRequestType() + " "
// + receivedObject);
r = (Request) receivedObject;
processId.set(r.getProcessId());
Response rs = new Response();
rs.setRequest(r);
rs.setServerFrom(GoldenNodeServer.this);
if (getOperationBase() != null) {
try {
Object s = ReflectionUtils.callMethod(getOperationBase(), r.getMethod(), r.getParams());
rs.setReturnValue(s);
} catch (Exception e) {
rs.setReturnValue(e);
}
outToClient.writeObject(rs);
} else {
rs.setReturnValue(new NoClientProxySetException());
}
}
} catch (EOFException e) {
// LOGGER.trace("eof occured");
} catch (SocketException e) {
if (e.toString().contains("Socket closed") || e.toString().contains("Connection reset")
|| e.toString().contains("Broken pipe")) {
} else {
stop();
LOGGER.error("Error occured" + (r == null ? "" : " while processing " + r) + " ", e.toString());
}
} catch (IOException | ClassNotFoundException e) {
stop();
LOGGER.error("Error occured" + (r == null ? "" : " while processing " + r) + " ", e.toString());
} finally {
tcpProcessors.remove(this);
}
}

Categories