Thread Pooled Concurrent Server (JAVA) - java

This is my 2nd ever Post I'm pretty new to Programming.
I'm working on making my Socket Server Concurrent (Multithreaded) on the Server side. I understand I have to use Threaded Pools after my Socket accepts but I'm just very confused what to do. currently the requests are slower then it was when it was only iterative because its not working correctly.
//MultiClient Class
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.net.*;
import java.io.*;
public class MultiServer {
public static void main(String[] args) throws IOException {
Scanner scnr = new Scanner(System.in);
System.out.println("What port should the server be using?");
int portNumber = scnr.nextInt();
while ((portNumber < 1025) ||(portNumber > 4998)) {
System.out.println("Please enter a Port Number between '1025' and '4998'.");
portNumber = scnr.nextInt();
}
try (ServerSocket serverSock = new ServerSocket(portNumber)){
System.out.println("Server listening on port " + portNumber);
while(true) {
Socket sock = serverSock.accept();
MultiServerHandler msh = new MultiServerHandler(sock);
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
executor.execute(msh);
}
} catch (IOException ex) {
System.out.println("Server exception: " + ex.getMessage());
ex.printStackTrace();
}
}
}
//MultiClientHandler Class
import java.io.*;
import java.net.*;
public class MultiServerHandler extends Thread{
private Socket sock;
public MultiServerHandler(Socket sock) {
this.sock = sock;
}
public void run() {
try {
System.out.println("New client connected");
InputStream input = sock.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
OutputStream output = sock.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
String command;
command = reader.readLine();
Process process = Runtime.getRuntime().exec(command);
BufferedReader read = new BufferedReader(new InputStreamReader(process.getInputStream()));
String result;
while((result = read.readLine()) != null) {
writer.println(result);
}
sock.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
So far I just know I have to implement it after the socket accepts but I'm not too sure yet.

Related

TCP Client/Server program getting stuck when

I have been working on creating a program where communication can be exchanged between a server and a client using to program files in java. However, when I try to send messages from server to client. I have been working on a project where I am trying to send a message from a server to a client. However, when I put in my message, from the server, the client seems to get stuck on sentence = inFromServer.readLine(); in the client portion of my code and I'm not sure why. I ran the debugger on this, and it seems that "sentence" takes in the value that was inputted from the client, so im not sure why it get stuck. Does anyone have an idea what the problem may be?
Here's my code for reference-
Server Code:
package com.company;
import java.io.*;
import java.net.*;
import java.util.Scanner;
import java.util.concurrent.*;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
class threading implements Runnable {
private int portnumbers;
Socket clientsocket;
ServerSocket connectorsocket;
public threading(Socket clientsocket)
{
this.clientsocket = clientsocket;
}
public void run(){
try {
Serverstuff(this.clientsocket);
}
catch(Exception ex)
{
System.out.print("I found exception" + ex);
}
}
public void Serverstuff(Socket socketlol)
{
// File h = null;
int width = 1536;
int height = 2048;
BufferedImage image = null;
File f = null;
while(true) {
try {
String sentence1;
//Wait on welcoming socket for client
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(socketlol.getInputStream()));
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream outToClient = new DataOutputStream(socketlol.getOutputStream());//create input stream, attached to socket
System.out.println("Flag1");
sentence1 = inFromUser.readLine();
System.out.println("Flag2");
System.out.println("Flag3");
outToClient.writeBytes(sentence1);
}
catch(Exception ex)
{
System.out.print("I found exception" + ex);
}
}
}
}
public class server{
public static void main(String argv[]) throws Exception {
String clientSentence;
String capitalizedSentence;
int portnumber;
Scanner scanney = new Scanner(System.in);
System.out.println("Enter the number of clients");
String arg1 = scanney.next();
int arg2 = Integer.parseInt(arg1);
int[] socketarray = new int[arg2];
for(int i = 0; i < arg2; i++) {
System.out.println("enter the port number");
String portnumberstr = scanney.next();
portnumber = Integer.parseInt(portnumberstr);
socketarray[i] = portnumber;
}
//ServerSocket welcomeSocket = new ServerSocket(5000);
int g = 0;
int whatever;
//ServerSocket welcomeSocket2 = new ServerSocket(5001);
while (true) {
if(g < arg2) {
System.out.println("Flagwhile1");
whatever = socketarray[g];
ServerSocket welcomeSocket = new ServerSocket(whatever);
System.out.println("Flagwhile2");
Socket clientsock = welcomeSocket.accept();
threading newthread = new threading(clientsock);
System.out.println("Flagwhile3");
new Thread(newthread).start();
g = g + 1;
}
}
}
}
Client Code:
package com.company;
import java.io.*;
import java.net.*;
import java.util.Scanner;
import java.util.concurrent.*;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class client2{
public static void main(String argv[]) throws Exception {
try {
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); //Create input stream
Socket clientSocket = new Socket("127.0.0.2", 5001); //Create client socket connect to server
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream()); //Create output stream, attached to socket
System.out.println("Flag19");
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); //Create input stream attached to socket
System.out.println("Flag20");
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n'); //send line to server
System.out.println("Flag21");
sentence = inFromServer.readLine();
System.out.println("Flag22");
System.out.println(sentence);
int test = 5;
clientSocket.close();
}
catch(IOException e){
System.out.println("Error: " + e);
}
}
}

How to broadcast messages to all clients using tcp in java

I am building a multithreaded chat server application which broadcasts a message sent by one client to all the clients.On most of the examples on internet and on Oracle's website too broadcasting is done using udp (Multicast Socket)but i am using tcp .
Does anyone know how to send a message to all the connected clients in a tcp conection?
Here is my current code which works fine and sends the message receieved from a client to that client only:
EchoServer
import java.net.*;
import java.io.*;
public class EchoServer
{
public static void main(String[] args)
throws IOException
{
if (args.length != 1) {
System.err.println("Usage: java EchoServer <port number>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);
ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[0]));
while (true) {
try {
Thread t = new Thread(new MultiServer(serverSocket.accept()));
t.start();
} catch(IOException e) {
System.out.println("Accept Failed:");
System.exit(-1);
}
}
}
}
EchoClient
import java.io.*;
import java.util.Scanner;
import java.net.*;
public class EchoClient
{
public static void main(String[] args) throws IOException
{
if (args.length != 2) {
System.err.println("Usage: java EchoClient <host name><portnumber>");
System.exit(1);
}
String hostName = "localhost";
int portNumber = Integer.parseInt(args[1]);
try (
Socket echoSocket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
) {
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo::" + in.readLine());
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " + hostName);
System.exit(1);
}
}
}
MultiServer
import java.io.*;
import java.net.*;
public class MultiServer implements Runnable
{
private Socket client;
public MultiServer(Socket m)
{
this.client = m;
}
#Override
public void run()
{
BufferedReader in = null;
PrintWriter out = null;
try {
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
} catch(IOException ignored) {
}
while (true) {
String line;
try {
while ((line = in.readLine()) != null)
out.println(line);
} catch (IOException e) {
System.out.println("Read Failed");
System.exit(-1);
}
}
}
}
Use the concurrent hashmap and maintain your list of clients in that.
The concurrent hashmap is safe and you won't need to use synchronization while adding / iterating / removing
// Create and main list of active clients based on their host name / ip address
ConcurrentHashMap<String, Socket> activeClients = new ConcurrentHashMap<String, Socket>();
// message received
activeClients.put(clientsocket.getInetAddress().getHostAddress(), clientsocket);
// broadcast message to all available clients
for(String clientHost : activeClients.keySet()) {
// get each socket here and send a message to them.
}
Vector is basically a thread safe one so you don't need to worry about that one.

Unable to receive data on server side (Java Socket Programming)

A single client connects to a single server.
I'm unable to display the text sent from the client.
Am I not sending the text properly from client or not receiving the text properly on Server?
Is there another way to check from the code? (on client side that the data has been sent) or (on server side that the data has been received)
package com.company;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
public class ChatServer {
public static void main(String[] args) throws IOException {
ChatServer chatServer = new ChatServer();
chatServer.go();
}
private void go() throws IOException {
//Generate a random number and write to a text file
Random randomGenerator = new Random();
int randomInt = 1024 + randomGenerator.nextInt(64511);
PrintWriter printWriter = new PrintWriter("port.txt");
printWriter.write(String.valueOf(randomInt));
printWriter.flush();
//Create Server on a port using that random number
ServerSocket serverSocket = new ServerSocket(randomInt);
System.out.println("Server on Port: "+randomInt);
//Start Accepting Clients
ClientHandler clientHandler= new ClientHandler(serverSocket);
Thread t = new Thread(clientHandler);
t.start();
}
private class ClientHandler implements Runnable {
ServerSocket serverSocket;
BufferedReader bufferedReader;
PrintWriter writer;
Socket socket;
public ClientHandler(ServerSocket sSocket) throws IOException {
serverSocket = sSocket;
}
public void run() {
while (true)
{
String message;
try {
//Accept A connection and assign a socket for this client
socket = serverSocket.accept();
System.out.println("Connection Established");
//Read Message
InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
while( (message = bufferedReader.readLine()) != null)
{
//Display it on the console
System.out.println("From Client: " + message);
//Send it back to the client
writer = new PrintWriter(socket.getOutputStream());
writer.println("Your message is: " + message);
writer.flush();
//Send your message
writer.write("This is default message");
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
This is Client Side Code
package com.company;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class ChatClient {
Socket socket;
public static void main(String[] args) throws IOException {
ChatClient chatClient = new ChatClient();
chatClient.go();
}
private void go() throws IOException {
//Read Port number from file
FileReader fileReader = new FileReader("port.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
int port = Integer.parseInt(bufferedReader.readLine());
//Connect to socket on the port number
System.out.println("Connecting to Server on: "+port);
socket = new Socket("127.0.0.1",port);
//Initiate sender thread
ChatSender chatSender = new ChatSender(socket);
Thread sender = new Thread(chatSender);
//Initiate receiver thread
ChatReceiver chatReceiver = new ChatReceiver(socket);
Thread receiver = new Thread(chatReceiver);
sender.start();
receiver.start();
}
public class ChatSender implements Runnable
{
BufferedWriter bufferedWriter;
public ChatSender(Socket socket) throws IOException {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(socket.getOutputStream());
bufferedWriter = new BufferedWriter(outputStreamWriter);
}
public void run()
{
while (true)
{
//get text from console
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
System.out.println("To Server: "+input);
try {
System.out.println("Sending data");
//write to server
bufferedWriter.write(input);
//flush the text
bufferedWriter.flush();
System.out.println("sent data");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class ChatReceiver implements Runnable
{
BufferedReader bufferedReader;
public ChatReceiver(Socket socket) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
}
public void run()
{
try {
while (true)
{
Thread.sleep(1000);
System.out.println("Receiving data");
String output = bufferedReader.readLine();
System.out.print("From Server: "+output);
System.out.println("Received data");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Usual problem. You're reading lines, but you aren't sending lines. Change write() to println().

Thread server/client stops after 2nd client joins

I have a server which uses multiple threads to accept multiple clients. I have it at the moment that when a client types something, it appears on the server as Client: text This works fine for 1 client. However the problem is when a second client joins.
They join fine and they can type fine. But the first client can only type 1 more thing then they stop, i.e their messages doesn't appear on the server. I presume they can do 1 as the method has been started but doesn't repeat. I've tried a while (true) loop (as seen in the code) and recalling the method at the end, neither work. I'm new to programming so don't have much expertise in this. Please find the code below :) (Note, indention is correct, just hasn't copied across properly)
Server:
package dod;
import java.net.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.io.*;
public class Server implements Runnable
{
PrintWriter out;
BufferedReader in;
Socket clientSocket;
ServerSocket serverSocket;
int portNumber;
AtomicInteger numClients = new AtomicInteger(0);
public static void main(String[] args)
{
Server s = new Server();
s.startup();
}
public void run()
{}
/**
* Start the server on the user picked port
*/
public void startup()
{
try
{
System.out.println("Enter a port");
Scanner dif = new Scanner(System.in);
portNumber = Integer.parseInt(dif.nextLine());
dif.close();
serverSocket = new ServerSocket(portNumber);
newThread();
}
catch (IOException e) {
System.out.println("Error");
System.exit(0);
}
}
public void newThread()
{
Thread thread =new Thread("C"+numClients.getAndIncrement())
{
public void run()
{
accept();
}
};
thread.start();
}
public void accept()
{
try
{
clientSocket = serverSocket.accept();
System.out.println("A new client has just connected.");
} catch(IOException e)
{
System.out.println("error");
System.exit(0);
}
newThread();
listenCommand();
}
public void listenCommand()
{
while (true)
{
try
{
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String userInput;
while ((userInput = in.readLine()) != null)
{
System.out.println("client: " + userInput);
}
} catch (IOException e)
{
System.out.println("Error");
System.exit(0);
}
}
}
}
Client:
package dod;
import java.io.*;
import java.net.*;
public class Client
{
public static void main(String[] args) throws IOException {
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);
try {
Socket serverSocket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(serverSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null)
{
out.println(userInput);
}
} catch(UnknownHostException e) {
System.out.println("error in host");
} catch(IOException e) {
System.out.println("error in IO");
}
}
}
Thank you! :)
*emphasized text*In the Server class you should have a Thread listening for new clients arriving and assigning them their own socket. You have the socket and the streams as a member variables, so everytime a new client comes you replace the socket. Also you open a new Thread for the accept connection, instead for the client itself.
Check the following (See that the client socket is another thread and I created a Runnable for it):
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
public class Server
{
ServerSocket serverSocket;
int portNumber;
AtomicInteger numClients = new AtomicInteger(0);
public static void main(String[] args)
{
Server s = new Server();
s.startup();
}
/**
* Start the server on the user picked port
*/
public void startup()
{
try
{
System.out.println("Enter a port");
Scanner dif = new Scanner(System.in);
portNumber = Integer.parseInt(dif.nextLine());
dif.close();
serverSocket = new ServerSocket(portNumber);
newThread();
}
catch (IOException e) {
System.out.println("Error");
System.exit(0);
}
}
public void newThread()
{
Thread thread =new Thread("C"+numClients.getAndIncrement())
{
public void run()
{
while(true) {
try {
accept();
} catch (Exception e) {
// lof the exception
}
}
}
};
thread.start();
}
public void accept()
{
try
{
Socket clientSocket = serverSocket.accept();
new Thread(new ClientSocket(clientSocket)).start();
System.out.println("A new client has just connected.");
} catch(IOException e)
{
System.out.println("User disconnected");
System.exit(0);
}
}
class ClientSocket implements Runnable {
Socket clientSocket;
public ClientSocket(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public void run() {
{
try
{
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String userInput;
while ((userInput = in.readLine()) != null)
{
System.out.println("client: " + userInput);
}
} catch (IOException e)
{
System.out.println("Error. Probably client disconnected");
// System.exit(0); do you want to exist when a client disconnects?
}
}
}
}
}

TCP socket communication failed after the first trial

I have received error message after the client side successful received one message from server side. The error message is: Exception in thread "main" java.net.SocketException: Software caused connection abort: recv failed
It seems in client class, line = inFromserver.readLine(); would not receive any message from server, making it become "null". But I dont know why. Could somebody please help me?
Server class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class ConcurrentServer {
public static void main(String args[]) throws IOException
{
int portNumber = 20020;
ServerSocket serverSocket = new ServerSocket(portNumber);
while ( true ) {
new ServerConnection(serverSocket.accept()).start();
}
}
}
class ServerConnection extends Thread
{
Socket clientSocket;
PrintWriter outToClient;
ServerConnection (Socket clientSocket) throws SocketException
{
this.clientSocket = clientSocket;
setPriority(NORM_PRIORITY - 1);
}
public void run()
{
BufferedReader inFromClient;
try{
inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
OutputStream outToClient = clientSocket.getOutputStream();
PrintWriter printOutPut = new PrintWriter(new OutputStreamWriter(outToClient),true);
String request= inFromClient.readLine();
if(request !=null)
{
if(!request.equalsIgnoreCase("finished"))
{
printOutPut.write("Receving data");
}
else
{
printOutPut.write("file received");
}
}
}catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
try
{
clientSocket.close();
}catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
client class
import java.io.*;
import java.net.*;
import java.util.concurrent.TimeUnit;
public class client{
public static void main(String[] args) throws Exception{
final int PORT=20020;
String serverHostname = new String("127.0.0.1");
Socket socket;
PrintWriter outToServer;
BufferedReader inFromServer;
BufferedReader inFromUser;
byte[] dataToTransfer;
String line;
int counter=0;
int i=0;
socket = new Socket(serverHostname, PORT);
outToServer = new PrintWriter(socket.getOutputStream(),true);
inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
inFromUser = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Simulation of file transferring");
System.out.println("Enter the file size you want to transfer (Max Size 50MB)");
int userInput = Integer.parseInt(inFromUser.readLine());
System.out.println("Transferring start");
boolean connection = true;
while(connection)
{
//set transfer rate at 1MB/s
dataToTransfer = new byte[1000000];
Thread.sleep(1000);
if(i<userInput)
{
outToServer.println(dataToTransfer);
counter++;
System.out.println(counter + "MB file has been transferred");
}
else
{
outToServer.println("Finished");
}
line = inFromServer.readLine();
System.out.println(line);
if(!line.equalsIgnoreCase("file received"))
{
}
else
{
System.out.println("Transfer completed");
break;
}
i++;
}
outToServer.close();
inFromServer.close();
inFromUser.close();
socket.close();
}
}
You are sending byte array from client to server and reading string on server side.
Insert somthing in your byte array and then Convert your byte array into String
String str = new String(dataToTransfer,int offset, 1000000);
then write:
outToServer.println(str);

Categories