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.
Related
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'm trying to get a threaded chatserver working. But my socket is closing and I have no clue why it is.
In the server class I create a new ClientHandler
addHandler(new ClientHandler(this, incoming));
addHandler starts the thread and adds the new ClientHandler to an ArrayList in server.
incoming is the client socket.
public ClientHandler(Server serverArg, Socket sockArg) {
server = serverArg;
client = sockArg;
System.out.println(client.isClosed());
}
There is nothing called between
public void run() {
try {
System.out.println(client.isClosed());
in = new Scanner(client.getInputStream());
out = new PrintWriter(client.getOutputStream(), true);
announce();
System.out.println("Waiting for input");
boolean done = false;
while(!done && in.hasNextLine()) {
System.out.println("There is input!");
server.broadcast(clientName + ": " + in.nextLine());
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
When I run this code. This is the output:
false
true
java.net.SocketException: Socket is closed
Why is it closing immediately after creating this class / before starting it?
The connection is being closed by your code between when you add the handler and when the run() method is called. I suggest you add a breakpoint to the close method in the JDK and see where it is called. Or have a look at the code after you add the handler.
You can use a networking sniffer like wireshark or tcpdump.
To find out that if the connection broke due to the server side.
I guess that maybe the client side close the connection.
I'm trying to create a chat program in java but I had a problem when I run the server form, that the components I used to draw won't appear.
this is the code I used in the run of the form :
public void run() {
Server s = new Server();
s.setVisible(true);
// Etablir la connexion
try
{
ServerSocket ecoute;
ecoute = new ServerSocket(1111);
Socket service = null;
System.out.println("Serveur en attente d'un client !");
while(true)
{
service = ecoute.accept();
System.out.println("Client connécté !");
DataInputStream is = new DataInputStream(service.getInputStream());
s.jTextArea1.setText("Client dit : " + is.readUTF().toUpperCase());
service.close();
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
You said nothing happens when this code is ran. The presence of a public void run() method tells me that this is a thread, or at least a Runnable.
Because of the while(true), if this thread is not started in the proper manner, it will not run independently; that is it will hold up the entire program.
Instead of calling thread.run();, call thread.start();. This will call the run method for you, after starting a new thread that will run in parallel to the main thread.
If this code is not in a thread, and you just used public void run() by chance, then it will still provide the same problem for you.
For more information, refer to the Documentation on Threads
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
Im working on a socket program in Java.
Im running a GUI with a socket server in the background.
The socket server is running a thread that checks for socket messages every 10ms.
Both of them runs fine together but as soon as I try to open my File dialog in the gui, the gui crashes, but the server keeps on running.
Im thinking that I run the server (or the server thread) in a wrong way.
The file dialog works fine if I skip the socket.
What could be the problem, could it be that Im running the thread in a wrong way?
(this in one class)
public ServerController(){
ServSocket st = new ServSocket();
Thread thread1=new Thread(st);
thread1.start();
}
(this is my thread)
public void run(){
while (true) {
try {
Thread.sleep(10);
}
catch (InterruptedException e) {}
switch (Status) {
case CONNECTED:
try {
socket = new Socket(hostIP, port);
System.out.println("Connected on: " + hostIP + port);
out = new PrintWriter(socket.getOutputStream(), true);
changeStatus(STARTSENDING, true);
}
catch (IOException e) {
System.out.println("disconnected");
}
break;
(and this is my main)
static ServerController scon;
static Controller cn;
public static void main(String[] args) {
scon = new ServerController();
cn = new Controller();
cn.gui();
}
Just guessing here, but I think it's relating to the EDT.
Are you trying to launch the dialog from outside the EDT? http://en.wikipedia.org/wiki/Event_dispatching_thread
If you think you might be, try using SwingUtilities static methods (specifically isEventDispatchThread and invokeLater) to hone in and rectify the issue:
http://java.sun.com/javase/6/docs/api/javax/swing/SwingUtilities.html#isEventDispatchThread()
http://java.sun.com/javase/6/docs/api/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable)
hth
The problem is now solved.
Seems that the problem was that i had a scanner that was waiting for input(string = sc.next();) every 10ms in the thread, and after a few input my GUI showed.
I removed the Scanner and i now have a working application.