Multithreaded WebServer - java

Hi I`m trying to create a Multithreaded Webserver
I have referred
Link 1
Link 2
import java.net.*;
import java.io.*;
public class WebServer {
ServerSocket server;
public WebServer() {
try {
server=new ServerSocket(3000);
} catch (IOException ex) {
System.out.println("exc in const "+ex.getMessage());
}
}
Socket client;
BufferedReader br;
Thread t=new Thread(new Runnable(){
#Override
public void run() {
try{
System.out.println(br.readLine());
}
catch(Exception e){
System.out.println("exc is "+e);
}
}
});
public void RUN(){
while(true){
try {
client=server.accept();
System.out.println(client.getPort());
if(client!=null){
r=new BufferedReader(new InputStreamReader(client.getInputStream()));
t.start();
}
} catch (IOException ex) {
System.out.println("ex is "+ex.getMessage());
}
}
}
public static void main(String[] args) {
WebServer webserver=new WebServer();
try {
webserver.RUN();
} catch (Exception e) {
System.out.println("main "+e);
}
}
}
In the above code I keep getting a thread Illegal Access Exception so why do i keep getting this exception
I want to open Multiple tabs in browser and open localhost:3000 then the Server Must print the http request and port number but this happens only for first Client and not the others it shows illegalThreadAccess Exception and the Program terminates
Will greatly Appreciate if any pages are there that tell how to display some content in a Webbrowser.

As you can read in the documentation of the Thread class method start() throws
IllegalThreadStateException if the thread was already started.
In your code, you create thread only once, and you try to run it multiple times.
How to fix? Before line:
t.start();
you should create new thread
Thread t=new Thread(new Runnable(){
#Override
public void run() {
try{
System.out.println(br.readLine());
}
catch(Exception e){
System.out.println("exc is "+e);
}
}
});
Edit: About questions in comments. When you start thread, it starts to live its own live. You can eg. wait for terminating by invoking join() method on the thread object. The specification of the Thread class says how it's working and it says that you cannot rerun it.

Related

why serverScoket.accept() execute several times about only one request

I am learning the book how tomcat works and find a thing which make me a big surprise. I simplify the code as below:
public class Boot {
public static void main(String[] args) {
ServerDemo server = new ServerDemo();
try {
server.start();
System.in.read();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
public class ServerDemo implements Runnable {
private ServerSocket serverSocket = null;
public void run() {
while (true) {
Socket socket = null;
try {
socket = serverSocket.accept();
System.out.println("--receive request from client----"+
Thread.currentThread().getId());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void start() {
try {
serverSocket = new ServerSocket(8080);
Thread thread = new Thread(this);
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
the Boot class is Main class and used to boot this application and the ServerDemo class is a simplified server which listen 8080 port and will print info when a request from browser reach.
Now the question is that: I think when I make a request from browser it will execute
socket = serverSocket.accept();
and then print info only once and then thread block itself because of accept method waiting the next request.
But the real is that the thread print info several times:(maybe 3,4..) about a request.
and this is a executing:
input:
http://localhost:8080/index
output:
--receive request from client----13
--receive request from client----13
--receive request from client----13
my expected output:
--receive request from client----number
summary: I cant figure out about one request why it prints several times it means accept method execute several times.
Its probably your browser trying a few different things to get you to response cause you just closed the connection on them. Try using curl or wget instead.
– ug_

thread pool server shut down gracefully

I have a simple http server implemented with thread pool. I want to shut down the server gracefully. I referred the post Best Way to Gracefully Shutdown a Java Command Line Program
Here is the basic code:
public static void main(String[] args) {
ThreadPoolServer threadserver = new ThreadPoolServer(9000);
new Thread(threadserver).start();
threadserver.attachShutDownHook();
while (true) {
try {
Thread.sleep(20 * 10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void stopthread(){
this.shutdown = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
public synchronized void attachShutDownHook() {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
stopthread();
}
});
}
But it seems it does not stop the right way, any ideas? Thx.
This is too small piece of code.
But at the first sight I don't see any check for shutdown value in the main while loop. Secondly the variable should be set after and probably join on the listening thread would be worthy. In the run method I assume you properly handle the exception raised by asynchronous close.

Program freeze when calling Server method in Java

I have a basic GUI in Java where there is a JButton,I have given a functionality to start the Server with that button. But when I click the button the program freezes. Is it because of the while loop? If so how can I overcome this?
Server Code
void connect_clients()
{
try {
ServerSocket listener = new ServerSocket(7700);
try {
while (true) {
Socket socket = listener.accept();
try {
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
out.println(new Date().toString());
}
finally {
socket.close();
}
}
}
finally {
listener.close();
}
}
catch (IOException ex) {
Logger.getLogger(Test_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
}
Your program is freezing because you are blocking the UI thread. You need to post this on a separate thread:
public void postListen()
{
new Thread(new Runnable()
{
public void run()
{
connect_clients();
}
}).start();
}
Call that method instead and it should run the connect_clients() method on a separate thread. The new thread will block until a client connects.
Here is method explanation of ServerSocket.accept():
Listens for a connection to be made to this socket and accepts it. The
method blocks until a connection is made.
Until there is data input to socket, your program will freeze. If it's another problem, please check your logs. There may be another problem.

how to check if javafx application is already running programatically?

i'm trying to run a javafx application from a thread outside the scope of the application class. Th problem i'm using a while loop to generate the application and it throws an illegalstatexception whenever it is called twice, so i need a way to distinguish if the application is already running to continue with my other tasks, any ideas?
Based on #nejinx 's answer, you have to do this when calling Application.launch():
try {
Application.launch(args);
} catch (IllegalStateException e) {}
That way, if the error happens, your program will just keep running and not try to start the application again.
public class MyServer implements Runnable{
public static final int PORT = 99 ;
private static ServerSocket serverSocket;
private Window window;
public MyServer(Stage window) throws AlreadyBoundException {
if(serverSocket!=null && !serverSocket.isClosed())
throw new AlreadyBoundException("The server is already running.");
this.window = window;
try( Socket clientSocket = new Socket("localhost", PORT);) {
Platform.exit();
} catch (IOException e) {
final Thread thread = new Thread(this);
thread.setDaemon(true);
int priority = thread.getPriority();
if(priority>Thread.MIN_PRIORITY)
thread.setPriority(--priority);
thread.start();
}
}
public void run() {
try {
serverSocket = new ServerSocket(PORT, 1);
while (true) {
Socket clientSocket = serverSocket.accept();
clientSocket.close();
Platform.runLater(()->window.requestFocus());
}
}catch (IOException e) {
System.out.println("Error in MyServer: " + e);
}
}
}
And in the JavaFX APP:
#Override
public void start(Stage stage) throws Exception {
// Start server
new MyServer(stage);
// ...
}
The only way you can do this is to catch the IllegalStateException
If you dig down into the JavaFX source code you see this:
if (launchCalled.getAndSet(true)) {
throw new IllegalStateException("Application launch must not be called more than once");
}

Breaking out of a loop from different class

So, this is what I have. This is a server program that connects to multiple clients by using threads. As of now, that main loop is pretty much infinite.
Say a client sent a shutdown command to a ServerThread. Would that ServerThread be able to access the main class, break out of the loop, and reach the end of the program?
I tried turning putting isRunning = false in the ServerThread, but that doesn't seem to work.
public class Server
{
public static boolean isRunning = true;
public static void main(String[] args)
{
// init stuff
try {
serverSocket = new ServerSocket(27647);
} catch (IOException e) {
println("Could not listen on port 27647");
}
while(isRunning)
{
Socket clientSocket = null;
try{
clientSocket = serverSocket.accept();
} catch(IOException e) {
println("Could not connect to client");
}
ServerThread serv = new ServerThread(clientSocket);
serv.start();
}
try {
serverSocket.close();
} catch (IOException e1) { }
}
}
You need to make isRunning volatile and you have to close the serverSocket to unblock the accepting thread. I suggest you have a method like
public void close() throws IOException {
isRunning = false;
serverSocket.close();
}
If you call this from any thread, the thread will stop almost immediately.

Categories

Resources