Java Error: Exception in thread "Thread-5423" java.lang.ArrayIndexOutOfBoundsException [duplicate] - java

I'm creating two program files (one client one server).
Each file has one thread (one thread for server, one thread for client)
At runtime, there is supposed to be only one server, and there is supposed to be multiple and/or potentially infinite number of clients connecting to the server at the same time)
In order to get multiple clients to run, the user opens multiple command prompt / mac terminal windows (each window being one client) (one window being the server, so it requires at least two windows to run)
Once a client is connected, it can send messages (utf-8 strings) to the server. It will also receive from the server all messages sent from the other connected clients (it will not receive messages sent from itself).
Screenshot of exception in thread / array index out of bounds error (eclipse):
Screenshot of Socket Exception error (server):
Screenshot of error on client side:
Code of Server (ChatServer.java):
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatServer
{
ChatServer chatserver = new ChatServer();
private static Socket socket;
public static void main(String args[])
{
Thread ChatServer1 = new Thread ()
{
public void run ()
{
System.out.println("Server thread is now running");
try
{
int port_number1 = 0;
int numberOfClients = 0;
boolean KeepRunning = true;
if(args.length>0)
{
port_number1 = Integer.valueOf(args[0]);
}
System.out.println("Waiting for connections on port " + port_number1);
try
{
ServerSocket serverSocket = new ServerSocket(port_number1);
socket = serverSocket.accept();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println( "Listening for connections on port: " + ( port_number1 ) );
while(KeepRunning)
{
//create a list of clients
ArrayList<String> ListOfClients = new ArrayList<String>();
//connect to client
// socket = serverSocket.accept();
//add new client to the list, is this the right way to add a new client? or should it be in a for loop or something?
ListOfClients.add("new client");
numberOfClients += 1;
System.out.println("A client has connected. Waiting for message...");
ListOfClients.add("new client" + numberOfClients);
//reading encoded utf-8 message from client, decoding from utf-8 format
String MessageFromClientEncodedUTF8 = "";
BufferedReader BufReader1 = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
String MessageFromClientDecodedFromUTF8 = BufReader1.readLine();
byte[] bytes = MessageFromClientEncodedUTF8.getBytes("UTF-8");
String MessageFromClientDecodedUTF8 = new String(bytes, "UTF-8");
//relaying message to every other client besides the one it was from
for (int i = 0; i < ListOfClients.size(); i++)
{
if(ListOfClients.get(i)!="new client")
{
String newmessage = null;
String returnMessage = newmessage;
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");
System.out.println("Message sent to client: "+returnMessage);
bw.flush();
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (socket != null)
{
socket.close ();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
};
ChatServer1.start();
}
}
Code of ChatClient.java:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatClient
{
static int numberOfClients = 0;
public static void main(String args[])
{
ChatClient chatclient = new ChatClient();
//If I wanted to create multiple clients, would this code go here? OR should the new thread creation be outside the while(true) loop?
while (true)
{
String host = "localhost";
int numberOfClients = 0;
Thread ChatClient1 = new Thread ()
{
public void run()
{
try
{
//Client begins, gets port number, listens, connects, prints out messages from other clients
int port = 0;
int port_1number1 = 0;
int numberofmessages = 0;
String[] messagessentbyotherclients = null;
System.out.println("Try block begins..");
System.out.println("Chat client is running");
String port_number1= args[0];
System.out.println("Port number is: " + port_number1);
if(args.length>0)
{
port = Integer.valueOf(port_number1);
}
System.out.println("Listening for connections..");
System.out.println( "Listening on port: " + port_number1 );
boolean KeepRunning = true;
while(KeepRunning)
{
for(int i = 0; i < numberOfClients; i++)
{
System.out.println(messagessentbyotherclients);
}
try
{
Socket clientSocket = new Socket("localhost", port);
InetAddress inetlocalhost = InetAddress.getByName("localhost");
SocketAddress localhost = new InetSocketAddress(inetlocalhost, port);
clientSocket.connect(localhost, port);
System.out.println("Client has connected");
//client creates new message from standard input
OutputStream os = clientSocket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
}
catch (IOException e)
{
e.printStackTrace();
}
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input encoded in UTF-8 string format
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line = "";
System.out.println( "Standard input (press enter then control D when finished): " );
while( (line= input.readLine()) != null )
{
newmessage += line + " ";
input=null;
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
//Sending the message to server
String sendMessage = newmessage;
try
{
Socket clientSocket = new Socket("localhost", port);
SocketAddress localhost = null;
clientSocket.connect(localhost, port);
OutputStream os = clientSocket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(sendMessage + "\n");
bw.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("Message sent to server: "+sendMessage);
}
}
finally
{
}
}
};
ChatClient1.start();
}
}
}
My question is: How should I go about resolving all three errors (it seems like if I change one part of the code, then the other errors will either still exist or be resolved due to that but I could be wrong)? I would also like to know if there's a way to list the number of clients in an arraylist in the server code so that when a client closes their window I can keep the server up by just removing them from the list.

Related

How to assign four threads to four methods from different files? (multithreaded java socket programming)

I am trying to create a text messaging program with three files (main function file, client file, server file) where text messages can be sent and received at the same time, multiple times (ability to send multiple messages by pressing enter after each message, ability to receive multiple messages after connection after the other side presses enter after each message)
There are four threads (one thread for receiving messages on server, one thread for sending messages on server, one thread for receiving messages on client, one thread for sending messages on client)
If "-l" is present on the command line, it will run as a server, otherwise it will run as a client
Command line arguments to run server:
java DirectMessengerCombined -l 3000
Command line arguments to run client:
java DirectMessengerCombined 3000
The command line arguments (String[] args) should be accessible to all 3 files.
Here is the code where the threads are created:
Code of main function file:
import java.io.IOException;
public class DirectMessengerCombined implements Runnable
{
public static void main(String[] args) throws IOException
{
DirectMessengerClient client1 = null;
DirectMessengerServer server1 = null;
Thread ServerRead = new Thread ();
Thread ServerWrite = new Thread ();
Thread ClientRead = new Thread ();
Thread ClientWrite = new Thread ();
for (int i = 0; i < args.length; i++)
{
if (args.length == 1)
{
client1 = new DirectMessengerClient(args);
client1.ClientRun(args);
ClientRead.start();
ClientWrite.start();
}
else if (args.length == 2)
{
server1 = new DirectMessengerServer(args);
server1.ServerRun(args);
ServerRead.start();
ServerWrite.start();
}
i=args.length + 20;
}
}
#Override
public void run()
{
//This method is just to get rid of the "implements" error
//There are four threads, so which one is accessing this method??
}
}
In the following code there are comments such as "//I would like this to be the ServerRead thread method". I would like to know how to make that comment viable or put it into real code somehow to make it work with the corresponding threads in the main function file
Code of Server file:
import java.io.*;
import java.net.*;
import java.util.*;
import javax.imageio.IIOException;
public class DirectMessengerServer implements Runnable
{
private String[] serverArgs;
private static Socket socket;
public boolean keepRunning = true;
int ConnectOnce = 0;
public DirectMessengerServer(String[] args) throws IOException
{
// set the instance variable
this.serverArgs = args;
run();
}
public String[] ServerRun(String[] args) throws IOException
{
serverArgs = args;
serverArgs = Arrays.copyOf(args, args.length);
return serverArgs;
}
//I would like this to be the ServerRead thread method
public void run()
{
try
{
if(ConnectOnce == 0)
{
int port_number1 = Integer.valueOf(serverArgs[1]);
ServerSocket serverSocket = new ServerSocket(port_number1);
socket = serverSocket.accept();
ConnectOnce = 4;
}
while(keepRunning)
{
//Reading the message from the client
//BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String MessageFromClient = br.readLine();
System.out.println("Message received from client: "+ MessageFromClient);
// ServerSend.start();
runSend();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
}
}
//I would like this to be the ServerWrite thread method
public void runSend()
{
while(keepRunning)
{
System.out.println("Server sending thread is now running");
try
{
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input
BufferedReader input= new BufferedReader(
new InputStreamReader(System.in));
String line = "";
line= input.readLine();
newmessage += line + " ";
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.flush();
System.out.println("Message sent to client: "+sendMessage);
ConnectOnce = 4;
// run();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
}
}
}
}
Client file code:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class DirectMessengerClient
{
private String[] clientArgs;
private static Socket socket;
public boolean keepRunning = true;
public DirectMessengerClient(String[] args) throws IOException
{
// set the instance variable
this.clientArgs = args;
run(args);
}
public String[] ClientRun(String[] args)
{
clientArgs = args;
clientArgs = Arrays.copyOf(args, args.length);
return clientArgs;
}
//I would like this to be the ServerWrite thread method
public void run(String args[]) throws IOException
{
System.out.println("Client send thread is now running");
while(keepRunning)
{
String port_number1= args[0];
System.out.println("Port number is: " + port_number1);
int port = Integer.valueOf(port_number1);
String host = "localhost";
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input
BufferedReader input= new BufferedReader(new InputStreamReader(System.in));
String line = "";
line= input.readLine();
newmessage += line + " ";
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.flush();
System.out.println("Message sent to server: "+sendMessage);
runClientRead(args);
}
}
//I would like this to be the ClientRead thread method
public void runClientRead(String args[]) throws IOException
{
System.out.println("Client recieve/read thread is now running");
//Integer port= Integer.valueOf(args[0]);
//String host = "localhost";
//InetAddress address = InetAddress.getByName(host);
//socket = new Socket(address, port);
//Get the return message from the server
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String MessageFromServer = br.readLine();
System.out.println("Message received from server: " + MessageFromServer);
}
}
My question is how to make those methods work with the threads inside the main function file and/or how to turn the comments into real code for the corresponding threads in the main file?
EDIT: I am able to get it to send one message at a time successfully now, is there a way to make it so I can send and receive multiple messages at a time?

How to prevent socket from becoming null in a program with multiple threads (java socket thread programming)

Error message:
Exception in thread "Thread-1" java.lang.NullPointerException
at DirectMessengerServer$2.run(DirectMessengerServer.java:72)
Screenshot of error
Line 72:
OutputStream os = socket.getOutputStream();
I am trying to get the same socket from the previous thread (ServerRecieve) but the socket is null at this point, I'm not sure how to prevent socket from being null or if there is a way to set the socket to something non-null globally that would work too if possible.
I am trying to create the server side of a program where messages are being sent and received simultaneously (like two people using a text messenger app on a phone)
Code of Server:
import java.io.*;
import java.net.*;
import java.util.*;
import javax.imageio.IIOException;
//import static java.nio.charset.StandardCharsets.*;
public class DirectMessengerServer
{
private static Socket socket;
boolean KeepRunning = true;
void ServerRun(String[] args)
{
Thread ServerRecieve = new Thread ()
{
public void run ()
{
System.out.println("Server recieve thread is now running");
try
{
System.out.println("Try block begins..");
int port_number1= Integer.valueOf(args[1]);
System.out.println("Port number is: " + port_number1);
ServerSocket serverSocket = new ServerSocket(port_number1);
//SocketAddress addr = new InetSocketAddress(address, port_number1);
System.out.println( "Listening for connections on port: " + ( port_number1 ) );
while(KeepRunning)
{
//Reading the message from the client
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String MessageFromClient = br.readLine();
System.out.println("Message received from client: "+ MessageFromClient);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};ServerRecieve.start();
Thread ServerSend = new Thread ()
{
public void run ()
{
System.out.println("Server sending thread is now running");
//if(socket!=null)
//{
try
{
// int port_number1= Integer.valueOf(args[1]);
// ServerSocket serverSocket = new ServerSocket(port_number1);
//socket = serverSocket.accept();
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input
BufferedReader input= new BufferedReader(
new InputStreamReader(System.in));
String line = "";
line= input.readLine();
newmessage += line + " ";
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.flush();
System.out.println("Message sent to client: "+sendMessage);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
}
// }
}
};ServerSend.start();
}
}
Full code of Client and Server and main file (more context):
Server unable to send messages to client (java thread socket programming)
My question is: How do I resolve the error on line 72 while keeping the socket the same as the one in the previous thread (ServerRecieve)?
You are assuming that System.in() is thread safe. You should put this section in a synchronized block like this
synchronized(input){
line= input.readLine();
}
You will have to move the declaration
BufferedReader input= new BufferedReader(
new InputStreamReader(System.in));
to your master thread, and then pass the reference of input to your worker threads.

Java thread client Null pointer exception: Do I need to use socket.connect() or socket.connect(null) in order to connect a client to a server?

I'm creating two program files (one client one server).
Each file has one thread (one thread for server, one thread for client)
At runtime, there is supposed to be only one server, and there is supposed to be multiple and/or potentially infinite number of clients connecting to the server at the same time)
In order to get multiple clients to run, the user opens multiple command prompt / mac terminal windows (each window being one client) (one window being the server, so it requires at least two windows to run)
Once a client is connected, it can send messages (utf-8 strings) to the server. It will also receive from the server all messages sent from the other connected clients (it will not receive messages sent from itself).
The port number I am using to connect is 5344 (localhost).
Screenshot of client error:
Screenshot of server (no errors):
The error message is:
Exception in thread “Thread-75562” java.lang.NullPointerException at ChatClient$1.run(ChatClient.java:39)
The "39" is the line of code (I think) that the error is pointing at.
Screenshot of line 39 in ChatClient.java:
I have notice that some people use
Socket socket = new Socket(host, portNumber);
without calling any Socket.connect(host, portNumber); to connect to a server.
Does socket.connect() ever need to be used to connect a client to a server?
Code of ChatClient.java:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatClient
{
private static Socket Socket;
static int numberOfClients = 0;
public static void main(String args[])
{
//If I wanted to create multiple clients, would this code go here? OR should the new thread creation be outside the while(true) loop?
while (true)
{
String host = "localhost";
int numberOfClients = 0;
Thread ChatClient1 = new Thread ()
{
public void run()
{
try
{
//Client begins, gets port number, listens, connects, prints out messages from other clients
int port = 0;
int port_1number1 = 0;
int numberofmessages = 0;
String[] messagessentbyotherclients = null;
System.out.println("Try block begins..");
System.out.println("Chat client is running");
String port_number1= args[0];
System.out.println("Port number is: " + port_number1);
if(args.length>0)
{
port = Integer.valueOf(port_number1);
}
System.out.println("Listening for connections..");
System.out.println( "Listening on port: " + port_number1 );
try
{
Socket.connect(null);
}
catch (IOException e1)
{
e1.printStackTrace();
}
System.out.println("Client has connected to the server");
boolean KeepRunning = true;
while(KeepRunning)
{
for(int i = 0; i < numberOfClients; i++)
{
System.out.println(messagessentbyotherclients);
}
try
{
//client creates new message from standard input
OutputStream os = Socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
}
catch (IOException e)
{
e.printStackTrace();
}
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input encoded in UTF-8 string format
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line = "";
System.out.println( "Standard input (press enter then control D when finished): " );
while( (line= input.readLine()) != null )
{
newmessage += line + " ";
input=null;
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
//Sending the message to server
String sendMessage = newmessage;
try
{
OutputStream os = Socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(sendMessage + "\n");
bw.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("Message sent to server: "+sendMessage);
}
}
finally
{
}
}
};
ChatClient1.start();
}
}
}
Code of ChatServer.java:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatServer
{
private static Socket socket;
public static void main(String args[])
{
Thread ChatServer1 = new Thread ()
{
public void run ()
{
System.out.println("Server thread is now running");
try
{
int port_number1 = 0;
int numberOfClients = 0;
boolean KeepRunning = true;
if(args.length>0)
{
port_number1 = Integer.valueOf(args[0]);
}
System.out.println("Waiting for connections on port " + port_number1);
try
{
ServerSocket serverSocket = new ServerSocket(port_number1);
socket = serverSocket.accept();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println( "Listening for connections on port: " + ( port_number1 ) );
while(KeepRunning)
{
//create a list of clients
ArrayList<String> ListOfClients = new ArrayList<String>();
//connect to client
// socket = serverSocket.accept();
//add new client to the list, is this the right way to add a new client? or should it be in a for loop or something?
ListOfClients.add("new client");
numberOfClients += 1;
System.out.println("A client has connected. Waiting for message...");
ListOfClients.add("new client" + numberOfClients);
//reading encoded utf-8 message from client, decoding from utf-8 format
String MessageFromClientEncodedUTF8 = "";
BufferedReader BufReader1 = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
String MessageFromClientDecodedFromUTF8 = BufReader1.readLine();
byte[] bytes = MessageFromClientEncodedUTF8.getBytes("UTF-8");
String MessageFromClientDecodedUTF8 = new String(bytes, "UTF-8");
//relaying message to every other client besides the one it was from
for (int i = 0; i < ListOfClients.size(); i++)
{
if(ListOfClients.get(i)!="new client")
{
String newmessage = null;
String returnMessage = newmessage;
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");
System.out.println("Message sent to client: "+returnMessage);
bw.flush();
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (socket != null)
{
socket.close ();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
};
ChatServer1.start();
}
}
My question is: How to resolve the error and/or should I delete the socket.connect() while somehow still being able to connect to the server as a client?

Java thread program stops running with no error message (mac terminal/command prompt)

The purpose of this program is to send text messages (strings) between a client and a server (using java threads) like two phones would send text messages to each other.
If "-l" is present in the command line arguments, then it will run the server thread. If "-l" is not present on the command line arguments, then it will run the client thread.
In the screenshot below, the left window is the server and the right is the client.
The problem with the screenshot is that the left window (server) is supposed to output "Message received from client: Hello", and then proceed to output "Standard input (press enter then control D when finished):"
I used "ok1, ok2, ok3, ok4" as standard output for debugging purposes (you will notice what lines it stops at in the code)" so it can be deleted in the future.
There are three files: The main function file, the server file, the client file.
Code of Server (DirectMessengerServer.java):
import java.io.*;
import java.net.*;
import java.util.*;
//import static java.nio.charset.StandardCharsets.*;
public class DirectMessengerServer
{
private static Socket socket;
boolean KeepRunning = true;
void ServerRun(String[] args)
{
Thread Server = new Thread ()
{
public void run ()
{
System.out.println("Server thread is now running");
try
{
System.out.println("Try block begins..");
int port_number1= Integer.valueOf(args[1]);
System.out.println("Port number is: " + port_number1);
ServerSocket serverSocket = new ServerSocket(port_number1);
//SocketAddress addr = new InetSocketAddress(address, port_number1);
System.out.println("Listening for connections..");
System.out.println( "Listening on port: " + ( port_number1 ) );
while(KeepRunning)
{
System.out.println("While loop run");
//Reading the message from the client
socket = serverSocket.accept();
System.out.println("ok1");
InputStream is = socket.getInputStream();
System.out.println("ok2");
InputStreamReader isr = new InputStreamReader(is);
System.out.println("ok3");
BufferedReader br = new BufferedReader(isr);
System.out.println("ok4");
String MessageFromClient = br.readLine();
System.out.println("ok5");
System.out.println("Message received from client: "+ MessageFromClient);
//creating message to server send from standard input
String newmessage = "";
try {
// input the message from standard input
BufferedReader input= new BufferedReader(
new InputStreamReader(System.in));
String line = "";
System.out.println( "Standard input (press enter then control D when finished): " );
while( (line= input.readLine()) != null && KeepRunning==true )
{
newmessage += line + " \n ";
}
}
catch ( Exception e ) {
System.out.println( e.getMessage() );
}
//Writing return message back to client
String returnMessage = newmessage;
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage);
System.out.println("Message sent to client: "+returnMessage);
bw.flush();
//shutdown with zero-length message
if(MessageFromClient.equals("") || MessageFromClient.equals(null) || returnMessage.equals(""))
{
KeepRunning=false;
System.out.println("Shutting down");
System.exit(0);
socket.close();
serverSocket.close();
}
}
}
catch ( Exception e )
{
e.printStackTrace();
}
finally
{
//Closing the socket
try
{
socket.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
};
Server.start();
}
}
Code of Client (DirectMessengerClient.java):
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class DirectMessengerClient
{
boolean KeepRunning = true;
private static Socket socket;
//static String[] arguments;
//public static void main(String[] args)
//{
// arguments = args;
//}
public DirectMessengerClient()
{
//System.out.println("test.");
}
public void ClientRun(String[] args)
{
Thread Client = new Thread ()
{
public void run()
{
System.out.println("Client thread is now running");
try
{
System.out.println("Try block begins..");
String port_number1= args[0];
System.out.println("Port number is: " + port_number1);
int port = Integer.valueOf(port_number1);
System.out.println("Listening for connections..");
System.out.println( "Listening on port: " + port_number1 );
while(KeepRunning)
{
String host = "localhost";
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input
BufferedReader input= new BufferedReader(
new InputStreamReader(System.in));
String line = "";
System.out.println( "Standard input (press enter then control D when finished): " );
while( (line= input.readLine()) != null )
{
newmessage += line + " ";
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.flush();
System.out.println("Message sent to server: "+sendMessage);
//Get the return message from the server
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String messageFromServer = br.readLine();
System.out.println("Message received from server: " + messageFromServer);
}
}
catch ( Exception e )
{
e.printStackTrace();
}
finally
{
//Closing the socket
try
{
socket.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
};
Client.start();
}
}
Code of main (DirectMessengerCombined.java):
public class DirectMessengerCombined
{
public static void main(String[] args)
{
DirectMessengerClient Client1 = new DirectMessengerClient();
DirectMessengerServer Server1 = new DirectMessengerServer();
for (int i = 0; i < args.length; i++)
{
if(!args[0].equals("-l"))
{
Client1.ClientRun(args);
}
switch (args[0].charAt(0))
{
case '-':
if(args[0].equals("-l"))
{
Server1.ServerRun(args);
}
}
i=args.length + 20;
}
}
}
My questions is: Why does the program stop running at the line where ok4 is outputted (server window)? There's no error message so I am also wondering how to find the error message if I'm missing it somehow?
In your DirectMessengerClient class, you are never sending the message to the server. Add a line to your code to do that:
String sendMessage = newmessage;
bw.write(sendMessage + "\n"); // <--- ADD THIS LINE
bw.flush();
System.out.println("Message sent to server: "+sendMessage);
Also note, in the server class, you are sending a return message. But the call to BufferedWriter.write does not add a newline to the end of the message (unlike System.out.println), so you need to add that yourself if you want to be able to read the line using BufferedReader.readLine:
bw.write(returnMessage + "\n");

Production ready Socket server in Java

There are many tutorials where explains about socket server/client sides, but all them are very trivial. Is there any tutorial for production ready code? I'm new in sockets. There is a client, that sends strings to server. I must create the server side. in server side I read string from client and after some manipulation saves them in db. I must response to client only IF I get string like "Error" for example. and if there are no any daya from client in 30 secs, I must close client connection, but server side must works. this is my test Client side:
public class ClientSideSocket2 {
public static void main(String[] args) {
String serverName = "localhost";
int port = 5555;
String line = "";
Socket client = null;
try {
System.out.println("Connecting to " + serverName + " on port " + port);
client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
PrintWriter toServer = new PrintWriter(client.getOutputStream(), true);
BufferedReader fromServer = new BufferedReader(new InputStreamReader(client.getInputStream()));
List<String> messages = new ArrayList<>();
for (int i = 0; i < 6; i++) {
messages.add("Message " + i+1);
}
messages.add("abc");
for (int i = 0; i < messages.size(); i++) {
toServer.println(messages.get(i));
if ((line = fromServer.readLine()) != null) {
System.out.println("Responce from server: " + line);
}
}
toServer.close();
fromServer.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
and my server side:
public class TRSServerInterface implements Runnable {
private ServerSocket serverSocket = null;
private Socket socket = null;
boolean runner = true;
String message = "";
public TRSServerInterface() {}
#Override
public void run() { // default run method of Thread class and Runnable interface
try {
int serverPort = 5555;
ServerSocket serverSocket = new ServerSocket(serverPort);
while(true) {
System.out.println("Waiting for connection...");
socket = serverSocket.accept();
System.out.println("Connected to " + socket.getRemoteSocketAddress());
//get the input and output streams
PrintWriter toClient = new PrintWriter(socket.getOutputStream(), true);
BufferedReader fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
do {
message = fromClient.readLine();
System.out.println("From client > " + message);
if (message.equals("abc")) {
toClient.println("Message from server");
}
else {
toClient.println("");
}
} while (!message.equals(""));
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
// try {
// objectOut.close();
// objectIn.close();
// socket.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
}
is my solution corrent and how I can close connection with client if there are no any data in 30 secs.
There are several production ready frameworks that should be used instead of rolling your own. Socket timeouts can be used to control how long different operations are allowed to take before an exception is thrown.

Categories