Single Threaded Server Implementation to Multi Threaded - java

Guys I want to convert my server implementation into multi thread so that it can handle multiple requests. Basically the server is connected with an android application and it is recieving an image from android application. I want to add a thread so that it can handle multiple requests and the thread should start when the request is recieved. Kindly help me out.
This is the Server Code.
public static void main(String[] args) throws UnknownHostException, IOException, MatlabInvocationException, MatlabConnectionException {
while (true) {
try {
serverSocket = new ServerSocket(4001); // Server socket
} catch (IOException e) {
System.out.println("Could not listen on port: 4001");
}
System.out.println("Server started. Listening to the port 4001");
clientSocket = serverSocket.accept();
DataInputStream inputFromClient = new DataInputStream(clientSocket.getInputStream());
int count = inputFromClient.readInt();
int available = inputFromClient.available();
System.out.println("Length of Image in Bytes:" + count);
System.out.println("available:" + available);
image = new byte[count];
inputFromClient.readFully(image);
System.out.println(image.length);
System.out.println(image);
final BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(image));
ImageIO.write(bufferedImage, "jpg", new File("image.jpg"));
System.out.println("Image has been wriiten in the directory.");
MatlabProxyFactory mpf = new MatlabProxyFactory();
MatlabProxy proxy = mpf.getProxy();
proxy.eval("conclusion=DetectColorL");
Object[] obj = proxy.returningEval("conclusion", 1);
String Message = obj[0].toString();
DataOutputStream outTo = new DataOutputStream(clientSocket.getOutputStream());
outTo.writeUTF(Message.toString());
System.out.println(Message);
proxy.disconnect();
serverSocket.close();

To make it multithreaded you want to be able to have multiple clients connected at the same time, to handle multiple requests instead of one at a time.
To do so, your server will have to permanently accept new clients.
public static void main(String[] args) {
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(4001); // Server socket
System.out.println("Server started. Listening to the port 4001");
while (true) {
// Always accept new clients
Socket clientSocket = serverSocket.accept();
new RequestHandlingClass(clientSocket).start(); // Make a new thread and call it's run procedure
}
} catch (IOException e) {
System.out.println("Could not listen on port: 4001");
}
}
Now our server accepts multiple clients we have to implement the RequestHandlingClass class. You want that class to listen for client requests and handle them.
public class RequestHandlingClass() extends Thread {
Socket clientSocket;
DataInputStream inputFromClient;
RequestHandlingClass(Socket clientSocket) {
this.clientSocket = clientSocket;
this.inputFromClient = new DataInputStream(clientSocket.getInputStream());
// ...
}
public void run() {
// Handle client requests
}
}
Based on your question I suppose you want to execute the "image handling" code in the run method.

Related

Is this the correct way to implement multithreading on Server side of concurrent client/server setup?

I have created this code snippet in both a single threaded version and multithreaded for a client/server setup I have going. I have tested both (recording the avg turn around time) and have gotten EXTREMELY similar results within margin of error when running multiple simple server commands at once. have I implememnted my client handler wrong?
This is my first time trying to implement a multithreaded server and from my understanding it just a matter of putting in a client handler being
`
class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
`
below is the snippet of the whole server code.
`
public class Server {
public static void main(String[] args) {
if (args.length < 1) return;
int port = Integer.parseInt(args[0]);
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server is listening on port " + port);
while (true) {
Socket socket = serverSocket.accept();
System.out.println("New client connected");
new ServerThread(socket).start();
}
} catch (IOException ex) {
System.out.println("Server exception: " + ex.getMessage());
ex.printStackTrace();
}
}
}
class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
String text;
do {
text = reader.readLine(); // reads text from client
Process p = Runtime.getRuntime().exec(text);
BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream()));
String outputLine;
while ((outputLine = stdout.readLine()) != null) { // while serverMsg is not empty keep printing
writer.println(outputLine);
}
stdout.close();
writer.println("ENDCMD");
// Text here should just write back directly what the server is reading...?
}
while (!text.toLowerCase().equals("exit"));
socket.close();
} catch (IOException ex) {
System.out.println("Server exception: " + ex.getMessage());
ex.printStackTrace();
}
}
}
`
I have tested both (recording the avg turn around time) and have gotten EXTREMELY similar results within margin of error when running multiple simple server commands at once. have I implememnted my client handler wrong?
If you are not making a new connection for each command that you send, then this would be expected. Since each connection runs on one thread, a multi-threaded approach, as you have shown, would have the same speed as if you didn't make a new thread for each connection. The difference is that, without multi-threading, you can only have one connection at a time.

Server doesn't listen to requests

as a part of my homework I have to build two classes one listener and one that is making the requests to the server (the server is already written by my teacher and I don't know how code looks like). In theory: The server that I'm connected to should reply with the exact same requests I sent to him. But in practice I get nothing back.
public class Listenerthread extends Thread {
Socket s;
Scanner answerServer;
public Listenerthread(Socket socket) {
this.s = socket;
this.answerServer = new Scanner(new BufferedReader(new InputStreamReader(s.getInputStream())));
}
public void run() {
System.out.println("Listening to the responses from the server......");
while (true) {
if (answerServer.hasNext()) {
System.out.println(answerServer.nextLine());
}
}
}
}
public class Mainthread {
public static void main(String[] args) throws ParseException {
Socket s = new Socket("someServer", 9999);
Listenerthread server = new Listenerthread(s);
server.start();
if (s.isConnected()) {
System.out.println("Connected");
}
String req = "Heyyy mate"; // server should sent me this back
PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
pw.println(req);
pw.flush();
//pw.close();
//s.close();
}
}
Update: A comment that OP left on the question after I started writing this answer shows that OP does not actually need to handle the server side of the communications. I will leave this answer for now in case it could still be useful.
When you have a client/server model, you should use a ServerSocket on the server side, as you alluded to in your question but then do not appear to have done in your code.
ServerSocket
Here is a ServerSocket example that may clear that up.
ServerSocket serverSocket;
public void serverSocketTest()
{
serverSocket = new ServerSocket(9999);
// each of the below methods will happen on separate threads
new Thread(this::serverSideAcceptConnectionFromClient).start();
new Thread(this::clientSideConnectToServer).start();
}
public void clientSideConnectToServer()
{
try {
System.out.println("Client is trying to connect to server...");
Socket connectionToServer = new Socket("localhost", 9999);
OutputStream thisGoesToTheServer = connectionToServer.getOutputStream();
InputStream thisIsDataComingFromServer = connectionToServer.getInputStream();
System.out.println("Client successfully connected to server.");
} catch(IOException ex) {
System.out.println("Connection to server failed. (" + ex + ")");
}
}
public void serverSideAcceptConnectionFromClient()
{
try {
System.out.println("Server is listening for potential clients...");
Socket connectionFromClient = serverSocket.accept();
InputStream thisIsDataComingFromClient = connectionFromClient.getInputStream();
OutputStream thisIsGoesBackOutToClient = connectionFromClient.getOutputStream();
System.out.println("Server accepted a client");
} catch(IOException ex) {
System.out.println("Error while listening for clients. (" + ex + ")");
}
}

java Socket programming Server Client

I'm trying to program a Server Client program where the CLIENT will be prompt if the SERVER closes or loses connection. What happens is once I connect the server and the client then disconnects the server it doesn't go to the ConnectException part
example: I opened the Server and Client connects, in the Client it will show that "You are connected to the Server", then if the Server disconnects there should be a "Server is disconnected". and when the Server reopens it will prompt the Client that he's connected to the Server
How can I continuously check if the Server is open or disconnected
here's my code:
SERVER
public class Server
{
private static Socket socket;
public static void main(String[] args)
{
try
{
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
//Server is running always. This is done using this while(true) loop
while(true)
{
//Reading the message from the client
socket = serverSocket.accept();
System.out.println("Client has connected!");
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number = br.readLine();
System.out.println("Message received from client is "+number);
//Multiplying the number by 2 and forming the return message
String returnMessage;
try
{
int numberInIntFormat = Integer.parseInt(number);
int returnValue = numberInIntFormat*2;
returnMessage = String.valueOf(returnValue) + "\n";
}
catch(NumberFormatException e)
{
//Input was not a number. Sending proper message back to client.
returnMessage = "Please send a proper number\n";
}
//Sending the response back to the client.
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage);
System.out.println("Message sent to the client is "+returnMessage);
bw.flush();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
CLIENT
public class Client
{
private static Socket socket;
public static void main(String args[])
{
Scanner input=new Scanner(System.in);
try
{
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
System.out.println("Connected to the Server");
}
catch (ConnectException exception)
{
System.out.println("Server is still offline");
}
catch(IOException ex)
{
System.out.println("Server got disconnected");
}
}
}
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
you can do like this
try
{
Socket s = new Socket("address",port);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
or you can simply et connection time out like this socket.setSoTimeout(timeout); to check connectivity
or you can use
socket.getInputStream().read()
makes the thread wait for input as long as the server is connected and therefore makes your program not do anything - except if you get some input and
returns -1 if the client disconnected
or what you can do is structure your code in this way
while(isConnected())
{
// do stuffs here
}

(Java) Getting two threads to communicate with each other whilst running?

I'm learning java. I'm trying to make a simple client/server chat system. What I have so far is a program where the server accepts multiple client connections by giving them each a seperate thread.
My problem now, is that I can't figure out how to get an input from one client, and then have it be sent amongst all of the clients, thus essentially have a very very simple chat mechanic. How would I go about accomplishing this? What would be the simpler way?
My code so far is here;
class Client {
public static void main(String argv[]) throws Exception {
String sentMessage; //variable for input
String receivedMessage; //variable for output
String status;
boolean running;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("127.0.0.1", 5622); //name of computer to connect with and port number to use
DataOutputStream outToServer =
new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer =
new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Client Side\n");
running = true;
while(running)
{
sentMessage = inFromUser.readLine(); //user inputs text to variable 'xInput'
outToServer.writeBytes(sentMessage + '\n'); //the variable is sent to the server
status = inFromServer.readLine();
System.out.println("FROM SERVER: " + status); //display to user
}
clientSocket.close();
}
}
The server code.
class Server {
public static void main(String argv[]) throws Exception {
String clientMessage;
boolean listening = true;
int portNumber = 5622;
try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
while (listening) {
new ServerThread(serverSocket.accept()).start();
}
} catch (IOException e) {
System.err.println("Could not listen on port " + portNumber);
System.exit(-1);
}
}
}
The thread that handles the client connections.
public class ServerThread extends Thread {
private Socket socket = null;
public ServerThread(Socket socket) {
super("ServerThread");
this.socket = socket;
}
public void run () {
int msgCnt = 0;
try (
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
) {
//something needs to go here
} catch (IOException e) {
e.printStackTrace();
}
}
If you are looking for a simple client-server communication samples then please have a look at below posts where I have described it step by step.
Multiple clients access the server concurrently
Java Server with Multiclient communication.

Cannot communicate with server in Java

I am trying to write server to client program but I cannot communicate with the server in Java.
Here is the code block in my main.
InetAddress addr = InetAddress.getLocalHost();
ipAddress = "78.162.206.164";
ServerSocket serverSocket = new ServerSocket(0);
String randomStringForPlayerName = RandomStringGenerator.generateRandomString();
baseForReqOpp += ipAddress + " " + serverSocket + " " + randomStringForPlayerName;
Socket socket = new Socket(host,2050);
socket.setSoTimeout(100);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
out.write(baseForReqOpp);
out.flush();
System.out.println(in.read());
I know that there is no problem in the server code and all the communication ports are ok.
But I cannot read anything from the server.
What can be the problem?
you have to create an output stream before the input stream
Here is some working code with communicating client and server sockets. Hopefully you can adapt it for your specific problem.
public class SocketTest {
public void runTest() {
try {
// create the server
new SimpleServer().start();
// connect and send a message
InetAddress addr = InetAddress.getLocalHost();
Socket sock = new Socket(addr, 9090);
ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
out.writeObject("Hello server");
out.flush();
ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
System.out.println("from server: " + in.readObject());
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// server has to run in a separate thread so the code doesn't block
private class SimpleServer extends Thread {
#Override
public void run() {
try {
ServerSocket sock = new ServerSocket(9090);
Socket conn = sock.accept();
// the code blocks here until a client connects to the server
ObjectInputStream in = new ObjectInputStream(conn.getInputStream());
System.out.println("from client: " + in.readObject());
ObjectOutputStream out = new ObjectOutputStream(conn.getOutputStream());
out.writeObject("Hello client");
out.flush();
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
To run it:
new SocketTest().runTest();
Your code will never work because you don't use threads. In order to start the server, you need to call accept at some point in your code
myServerSocket.accept();
this is a blocking call, ie the code flow stops until a client connects. But since you can't execute any statement (remember accept is blocking?) how can a client connect? This chicken and egg problem is resolved through threads. See Howard's answer for a code sample.
I don't see any call to accept(), so I wonder what your client connects to...

Categories