I have one web application from which I can start respective testing process which is in another Java app. I am using Socket Programming for communication between Web app and Java app.
When I request for specific process from web app then SocketServer from Java app hears request and start one thread for Testing process.
Testing process will initialize FirefoxDriver and start browser and do further test process.
My problem is, when I request for another process with different process name then It again creates second thread and start firefox browser but this time it is not considering my second process, it started to do same process which is first thread have.
I do not understand what to do...For every process I created a new thread but further it will doing same process.
My inputs are correctly received at Java app.
Please help me How can I do the concurrent thread safe processing?
I am using GWT,Java, Seleniun FirefoxDriver.
here is the Server code which is running in background and listen client request:
static final int PORT = 6789;
public static void main(String args[]) {
ServerSocket serverSocket = null;
Socket socket = null;
try {
InitializeApplication application = new InitializeApplication();
application.initialize();
serverSocket = new ServerSocket(PORT);
} catch (Exception e) {
log("Exception in SocketServerExecutor !!!",e);
}
while (true) {
try {
socket = serverSocket.accept();
} catch (Exception e) {
log("Exception in SocketServerExecutor !!!",e);
}
Thread thread = new Thread(new SocketServerThread(socket));
thread.start();
}
}
and this is the Thread which start process:
private Socket client;
public SocketServerThread(Socket serverSocket) {
this.client = serverSocket;
}
/**
* Starts appropriate process depending on process name from input.
* Input string contains:
* process name
*/
public void run() {
DataOutputStream outputStream = null;
String param = null;
try{
log("Just connected to "+ client.getRemoteSocketAddress());
try {
while ((param = in.readUTF()) != null){
log("got parameteres from client (i.e. from web app): "+param);
break;
}
} catch (Exception e) { }
if(param!=null && !param.isEmpty()){
String process = params[0];
ProcessManager manager = new ProcessManager();
if(process.equals("testUser"))
manager.startUserProcess(process);
else if(process.equals("testCustomer"))
manager.startCustomerProcess(process);
}
}catch(Exception exc){
if(exc instanceof SocketTimeoutException)
log("Socket timed out! [SocketServerThread]",exc);
else if(exc instanceof BindException)
log("BindException in SocketServerThread !!!",exc);
log(Level.SEVERE, "Exception in SocketServerThread !!!",exc);
}
}
and this is ProcessManager:
public void starUserProcess(String siteName) {
ExecutorService executerService = null;
try{
Callable<Object> callable = new ProcessThread(siteName);
executerService = Executors.newCachedThreadPool();
Future<Object> future = executerService.submit(callable);
future.get();
log("[ProcessManager] Process completed for "+process);
System.exit(0);
}catch (Exception e) {
log("[ProcessManager]::Exception");
log(ex);
}
}
ProcessThread will initialize all required things and Firefox browser and start process.
Client is new every time which contains input.
One of two things that I can thing of off the top of my head could be happening.
You are passing a paramater into your run() function that links back to the initial thread or...
You are using a shared variable that is accessible to all threads and the variable is either not being updated properly, or not being updated at all.
If you could include an SSCCE, that would help us determine where the problem truly lies.
Got the solution: I created the ExecutorService using newSingleThreadExecutor() instead of newCachedThreadPool() and also setDeamon(True) for every newly created ServerThread.
Here is the Executor documentation
Related
I have to implement (in the server side) the quit command which disconnects any clients still connected and closes the server.
Here the server code.
public class Server {
public static void main (String args []) {
if (args.length < 1) {
System.err.println("Usage: java Server <port>");
return;
}
int port = Integer.parseInt(args[0]);
try {
ServerSocket listener = new ServerSocket(port);
Files input = new Files();
while (true) {
System.out.println("Listening...");
Socket s = listener.accept();
System.out.println("Connected");
Thread clientHandlerThread = new Thread(new ClientHandler(s,input));
clientHandlerThread.start();
}
} catch (IOException e) {
System.err.println("Error during I/O operation:");
e.printStackTrace();
}
}
}
how can the server accept command line instructions while it is running?
First of all, you have to keep track of all the clients that you create by putting their instances in a list so that when you're going to shutdown everything, you could access them and tell them to finish their job.
And about how to tell the thread instances to do that, you should call their interrup() method to inform them that they should finish/stop whatever it's doing. Calling the interrupt() method on a thread leads an InterruptedException in the thread that you should handle and gracefully finish whatever you're doing.
For example if you have something like this in the run method of your ClientHandler:
while (true) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
Thread.currentThread().interrupt();
System.out.println(
"We've been asked to finish up the communication. Bye! ;)");
}
// do your business
}
This was of course a very simplified scenario to demonstrate the overall approach. You should be able to find tons of tutorials online about how to use the interrupt.
In following code i am trying to start and stop the server on button using java applet.Start works good using thread but i want to stop the server on button. I have used volatile variable.Still i am not getting the server stop..
here is code:
public class TCPServer extends Thread {
public static final int SERVERPORT = 8002;
private boolean running = false;
public volatile boolean stop = false;
public Socket client = null;
public static void main(String[] args) {
ServerBoard frame = new ServerBoard();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public void run() {
super.run();
running = true;
try {
System.out.println("Server Has Started........ \n Waiting for client........");
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
try {
while (!stop && running) {
client = serverSocket.accept();
System.out.println("Connection Accepted......");
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String usercmnd = in.readLine();
if (usercmnd != null) {
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec(usercmnd);
}
}
if (stop) {
serverSocket.close();
client.close();
System.out.println("Server Has Stopped");
System.exit(0);
}
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
}
public void requestStop() {
stop = true;
}
}
But whenever i click the stop button which will stop the server.Its not showing any output on console as i expected by the code.Its also not showing any error
here is code of stop button
stopServer = new JButton("Stop");
stopServer.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
stopServer.setEnabled(false);
startServer.setEnabled(true);
mServer = new TCPServer();
mServer.requestStop();
}
});
It doesn't stop because you create a new instance before stopping it and you don't even start it first while you are supposed to call requestStop() on your current instance of TCPServer.
// Here you create a new instance instead of using the existing one
mServer = new TCPServer();
mServer.requestStop();
in your ActionListener implementation for the stop button, you are accessing a different instance of TCPServer (as you are creating a new one). So you set the value "Stop" to a second object. It has no impact on the first instance that was created with the start button.
Try to instanciate the TCServer outside of your implementation of the action listener for both buttons and use that single instance for both.
Due to https://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#accept()
ServerSocket::accept is a blocking method, so stop variable can only be checked between successful connections.
You can either set a ServerSocket timeout using ServerSocket::setSoTimeout (and catch SocketTimeoutException), or interrupt Server thread and catch InterruptedException.
Both exceptions will be throwed from ServerSocket::accept.
Note, that thread interruption is highly preferred over timeouts and repeatly exception catching.
Try this:
public void requestStop() {
stop = true;
interrupt();
}
However, in this case, we can not guarantee, that already processing logic will successfully shutdown.
Also, you try invoke requestStop for new instance of TCPServer, instead already existing.
your code client = serverSocket.accept(); is blocking. So once you clicked "stopServer" button, you requested the stop, but it will be acted upon only once a client sends a next request to the server. What you need to do is to run your logic in your method run() in a separate thread and catch there InterruptedException and ClosedByInterruptException and clean up and return there. On your stopButton click you will invoke interrupt() method on your Thread. Read about it in here
am currently working on a project where I have to build a multi thread server. I only started to work with threads so please understand me.
So far I have a class that implements the Runnable object, bellow you can see the code I have for the run method provided by the Runnable object.
public void run() {
while(true) {
try {
clientSocket = serversocket.accept();
for (int i = 0; i < 100; i++) {
DataOutputStream respond = new DataOutputStream(clientSocket.getOutputStream());
respond.writeUTF("Hello World! " + i);
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
//
}
}
} catch(IOException e) {
System.out.println(e.getMessage());
}
}
}
Bellow is the main method that creates a new object of the server class and creates a threat. initializing the Thread.
public static void main(String args[]) {
new Thread(new Server(1234, "", false)).start();
}
I know this creates a new thread but it does not serve multiple clients at once. The first client need to close the connection for the second to be served. How can I make a multi threated server that will serve different client sockets at once? Do I create the thread on the clientSocket = serverSocket.accept();
yes.
from the docs:
Supporting Multiple Clients
To keep the KnockKnockServer example simple, we designed it to listen for and handle a single connection request. However, multiple client requests can come into the same port and, consequently, into the same ServerSocket. Client connection requests are queued at the port, so the server must accept the connections sequentially. However, the server can service them simultaneously through the use of threads—one thread per each client connection.
The basic flow of logic in such a server is this:
while (true) {
accept a connection;
create a thread to deal with the client;
}
The thread reads from and writes to the client connection as necessary.
https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html
I have developed a java swing client-server application. The server has many services like database service, cache service and client service talks to the clients.
The client service opens a socket on a port and listens to incoming connections. It spawns a new thread for every client connection, creates a session and reads the incoming serialized object. It maintains this session (keeps the thread alive) till the client issues a 'CLOSE_SESSION' command.
What i would like to know is if its correct to spawn a new thread for every new client-socket session. Thanks.
My client service code is as below.
Code to create server socket:
try {
ServerSocket socket = new ServerSocket(serverPort);
Socket listener = socket.accept();
Thread client = new Thread(new ClientHandler(listener));
client.start();
} catch (IOException ex) {
log.error(new Throwable(ex));
}
Code to spawn new thread for every client
class ClientHandler implements Runnable {
private static Logger log = Logger.getLogger(ClientHandler.class);
private Socket listener;
public ClientHandler(Socket listener) {
this.listener = listener;
}
public void run() {
try {
ObjectInputStream inStream = new ObjectInputStream(
listener.getInputStream());
try {
ServiceRequestResponse request = (ServiceRequestResponse) inStream
.readObject();
if (request != null && request.getServiceCommand() != null) {
ServiceCommand command = request.getServiceCommand();
log.debug("command : " + command.getCommand());
log.debug("is session alive? " + request.isAlive());
log.debug("ServiceCommand.CREATE_SESSION : "
+ ServiceCommand.CREATE_SESSION.getCommand());
if (!request.isAlive()
&& command.getCommand().equals(
ServiceCommand.CREATE_SESSION.getCommand())) {
// No session yet, and service command issued is login.
// Call login service, check credentials and create
// session.
request.setSessionId(UUID.randomUUID());
log.debug("Created user session with id : "
+ request.getSessionId());
} else {
if (command.getCommand().equals(
ServiceCommand.CLOSE_SESSION)) {
// Close session and do clean up here
}
// Here session is alive.
while (!ServiceCommand.CLOSE_SESSION.equals(command
.getCommand())) {
// Read the service command from the request
// response and
// Hand it over to the appropriate handler.
}
}
}
} catch (ClassNotFoundException ex) {
log.error(new Throwable(ex));
}
} catch (IOException ex) {
}
}
}
If your client session request can last long then thread-per-connection is a good solution.
Alternatives are:
Using NIO;
Using thread pool if client requests are short.
I'm trying to make a multithreaded server/client app with java ! this code is for listen() method in a class of a package that named Bsocket (iserver.core.socket) :
try {
serverSocket = new ServerSocket(port);
}catch(IOException e ){
ui.log(e.toString());//*
}
while (true){
try{
clienSocket = serverSocket.accept();
ui.log("Incomming Connection.");//*
new connectionHandler(clienSocket, ui);
}catch(IOException e ){
ui.log(e.toString());
}
}
ui.log("Incomming Connection."); is a method in below of main class of Bgui (iserver.core.ui).Bgui is a jframe that contain a textarea and something else ! the problem is when the accept methods executed , the ui.log did not works ! whats wrong here ?
You will need to launch your server on a seperate thread since .accept is a blocking call. You might want to do something like so:
(new Runnable() {
#Override
public void run()
{
try {
serverSocket = new ServerSocket(port);
}catch(IOException e ){
ui.log(e.toString());//*
}
while (true){
try{
clienSocket = serverSocket.accept();
ui.log("Incomming Connection.");//*
new connectionHandler(clienSocket, ui);
}catch(IOException e ){
ui.log(e.toString());
}
}
}
}).start();
NOTE: This code is not tested, but it should give you an idea of what you need to do.
Socket.accept() blocks until there's an incoming connection to receive (see the documentation). You shouldn't be making any blocking calls from your UI thread - otherwise it will... you know... block!
You need to separate UI threads from your own network service threads. accept() is blocking (obviously) and it freezes your application until you get a new client, and freezes again waiting for more clients.