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

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_

Related

Jetty 11 with Jersey is not accepting requests

I am learning java web application and started with jetty and jersey for creating the rest api. I am following this article https://mkyong.com/webservices/jax-rs/jersey-and-jetty-http-server-examples/#start-jersey-jetty-application
By this, I am able to compile and run the server however it does not accept any requests. I tried telnet, curl and other things - I always get connection refused.
My MainApp.java looks like this
public class MainApp {
public static final String BASE_URI = "http://localhost:8080/";
public static Server startServer() {
// scan packages
// final ResourceConfig config = new ResourceConfig().packages("com.mkyong");
final ResourceConfig config = new ResourceConfig(Receiver.class); -- This is my resouce.
final Server server =
JettyHttpContainerFactory.createServer(URI.create(BASE_URI), config);
return server;
}
public static void main(String[] args) {
try {
final Server server = startServer();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
System.out.println("Shutting down the application...");
server.stop();
System.out.println("Done, exit.");
} catch (Exception e) {
Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, e);
}
}));
System.out.println(
String.format("Application started.%nStop the application using CTRL+C"));
// block and wait shut down signal, like CTRL+C
Thread.currentThread().join();
// alternative
// Thread.sleep(Long.MAX_VALUE); // sleep forever...
// Thread.sleep(Integer.MAX_VALUE); // sleep around 60+ years
} catch (InterruptedException ex) {
Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Am I missing any other configuration? Any help would be appreciated.

Java - Iterate through IP Address List and call thread with IP Address as argument

I'm relatively new to Java and I'm writing an application to interrogate an Apache HTTP server's access_log file; with this, I want to submit the IP Addresses individually (probably via the Apache HTTPClient library) to another Java instance on another server (as the Web server does not have FTP enabled) to pull some log files. At the moment I've managed to bumble my way through modifying a 'tail -f' equivalent class to suit the programs needs and then manipulate that data to get the IP Addresses that I need to do something with - I even managed to make the 'tail' class threaded so it could address multiple periods of time!
With that said, I want to use a for loop to iterate through each entry in my computerRebootList String Array and with each address create a thread to perform some more work but all I can think of is this;
for (String tmpIpAddress : computerRebootList ) {
ComputerIpHandler handler = new ComputerIpHandler();
}
and then create another class named ComputerIpHandler like so;
public class KioskIpHandler implements Runnable {
static final Logger logger = LogManager.getLogger( ComputerIpHandler.class );
#Override public void run() {
//do some code
}
public static void main(String computerIp) {
Thread mainThread = new Thread(new ComputerIpHandler());
mainThread.start();
try {
logger.info("log some stuff");
mainThread.join();
logger.info("yay it's done");
}
catch (InterruptedException errInterrupted) {
logger.error(errInterrupted.getMessage());
logger.error(errInterrupted.getStackTrace());
}
}
}
I read somewhere about ensuring that I need to manage resource limitations so I would have to create a maximum number of threads - arguably I could send something like 10 IPs to this class and then have the rest of the addresses 'queue' until the one has returned... I'm just not confident or fluent enough to be able to conceptualise these ideas.
EDIT: I omitted that I am restricted to Java 1.6 as this is the maximum compatible version of the JRE that we can use on this server - not sure if that hinders this effort somewhat...
Can anyone point me in the right direction?
Check ScheduledThreadPoolExecutor and ScheduledExecutorService classes in package java.util.concurrent in java API. Those and some other classes in that package would manage all resources for you. They are available in java since version 1.5
I recommend using Java's built in FTP connection platform to make a thread for continually receiving data on a specified port, until it receives a termination key.
Basically, one class will create a ServerSocket (open socket on server) and upon connection with another socket (the client socket) it would create a new thread for receiving information.
public class Server {
public ServerSocket ss;
public Socket clientSocket;
public Thread receiveingThread;
public BufferedReader inFromClient = null;
public boolean running = false;
public Server(int port) {
try {
ss = new ServerSocket(port);
startReceiving();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void startReceiving() {
receiveingThread = new Thread("Recieve") {
public void run() {
String dataFromClient = new String("");
while (running) {
try {
inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
dataFromClient = inFromClient.readLine();
} catch (Exception e) {
e.printStackTrace();
}
if (dataFromClient.equals("TERMINATOR_KEY") {
stopRecieving();
}
else if(!dataFromClient.equals("")) {
//add item to array
}
}
}
};
receiveingThread.start();
}
public synchronized void stopReceiving() {
try {
running = false;
receivingThread.join();
ss.close();
clientSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
public static void main(String[] args) {
new Server(yourPortHere);
}
}
then the client class would look something like:
public class Client {
public Socket socket;
public Thread send;
public Client(string serverPublicIP, int port) {
try {
socket = new Socket(serverPublicIP, port);
send("some IP address");
} catch (Exception e) {
e.printStackTrace();
}
}
public void send(String toSend) {
send = new Thread("Send") {
public void run() {
PrintWriter outToServer;
try {
outToServer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
outToServer.print(toSend);
outToServer.flush();
} catch (Exception e) {
e.printStackTrace();
}
finally {
outToServer.close();
}
}
};
send.start();
}
public static void main(String[] args) {
new Client("127.0.0.1", yourPortHere);
}
}
This is the link for the start of socket tutorials on the oracle site.
This is the Oracle Documentation for java.net.ServerSocket
This is the Oracle Documentation for java.net.Socket

Multithreaded WebServer

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.

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.

Handle incoming sockets in another thread

I'm trying to do something potentially stupid, but I reckon it's a good idea, so bear with me. I tried to implement it, but I hit an awkward issue with sockets closing between threads - so I want some fresh eyes on the case.
Scenario
I want to write an object from a Client to a Server via sockets. There may be more than one Client communicating with the Server concurrently.
The object, a Message, is handled by the Server through its handling mechanisms. It is proposed that instead of the Server's main thread looking out for new incoming connections, a Listener thread is set up. Once it spots an incoming connection, it alerts the Server, storing the socket in a queue without receiving the data, so it can go back to listening quickly.
In its own time, the Server picks up the waiting socket, spawns a new thread, reads the Message, and closes the socket.
The code
Here's my first thoughts on how this should be implemented. There is a fundamental flaw in it which I will explain below.
Ignore the use of public fields - I'm just trying to make the code short for you guys
public class Server {
public boolean messageWaiting = false;
public static void main(String[] args) {
new Server().run();
}
public void run() {
Listener l = new Listener();
l.listen(this);
try {
while (true) {
System.out.println("I'm happily doing my business!");
Thread.sleep(1000);
if (messageWaiting) {
acceptMessages(l);
}
}
} catch (InterruptedException die) {}
}
private void acceptMessages(Listener l) {
while (!l.waiting.isEmpty()) {
try (
Socket client = l.waiting.poll();
ObjectInputStream ois = new ObjectInputStream(client.getInputStream())
) {
// Handle messages in new threads! (or a thread pool)
new Thread() {
public void run() {
try {
System.out.println(ois.readObject());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}.start();
} catch (Exception ex) {
// Oh no! The socket has already been closed!
ex.printStackTrace();
}
}
}
}
public class Listener {
public ConcurrentLinkedQueue<Socket> waiting = new ConcurrentLinkedQueue<>();
public void listen(final Server callback) {
new Thread() {
public void run() {
try (ServerSocket rxSock = new ServerSocket(7500)) {
while (!isInterrupted()) {
try (Socket client = rxSock.accept()) {
// Once a new socket arrives, add it to the waiting queue
waiting.add(client);
// Alert the server
callback.messageWaiting = true;
} catch (IOException ex) {
ex.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}.start();
}
}
public class Client {
public static void main(String[] args) {
try (
Socket txSock = new Socket(InetAddress.getLoopbackAddress(), 7500);
ObjectOutputStream oos = new ObjectOutputStream(txSock.getOutputStream())
) {
oos.writeObject("This is a Message, trust me.");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
What's wrong with this?
This:
I'm happily doing my business!
I'm happily doing my business!
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Unknown Source)
at Server.acceptMessages(Server.java:30)
at Server.run(Server.java:20)
at Server.main(Server.java:9)
This is because the Java 7 try blocks I'm using close the sockets once they're finished. So why don't I do this manually? Try yourself - you end up with a warning saying you're only ever going to call close() on a null object!
So, how do I avoid the whole issue of my incoming socket being closed before the Server thread picks up on it? Or is this a bad idea anyway and I should do something else?
Your statement in Listener
try (Socket client = rxSock.accept()) { ...
Is a try-with-resources for the client socket. As soon as you add it to the queue and exit the try block, the socket gets auto-closed.

Categories

Resources