Append to JTextArea - java

I am making server side app, but when I am trying to append text to the JTextarea, it's not working. It prints, however, to the console.
It worked fine until I added the line serverSocket.accept().
Here is my code:
try {
serverSocket=new ServerSocket(4545);
LogOutput.append("Seccessfuly connected\n" );
System.out.println("Seccessfuly connected\n" );
StartButon.setEnabled(false);
while(true){
LogOutput.append("waiting for client\n" );
System.out.println("waiting for client\n" );
serverSocket.accept();
LogOutput.append("Client connected to server\n" );
}
}
catch(Exception e){
LogOutput.append("cannot establish connection : "+ e +"\n" );
StartButon.setEnabled(true);
}

You're completely blocking the Swing event thread or EDT. Get most of that code, starting with the while (true) block onto a background thread if you want your Swing GUI to function in conjunction with a long-running process. Please read the Concurrency in Swing tutorial to see why this matters, and how to solve this issue with a SwingWorker object.

From the given code snippet and your question it seems you are looking for
Client connected to server\n
to be added to your textArea.
serverSocket.accept();
LogOutput.append("Client connected to server\n" );
Once you say serverSocket.accept() now it will wait for client connection to arrive, unless there is some client your next line of code is not going to be executed. serverSocket.accept is blocking method, Start your client program and your server will start processing next line of code.
From the docs
public Socket accept() throws IOException
Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.

Related

Handling Multiple TCP Connections In Java (Server-side)

I'm in the process of writing a messaging program, and I'm running into a spot where I'm having trouble understanding how to pass a socket over to a new thread for handling outbound messages via TCP. I'm currently using UDP packets for messages coming from a client, to the server, which, being UDP, doesn't require very much processing, as it's simply listening for incoming packets, before it de-serializes the objects, and processes them as needed in a separate thread. My problem now is, I'm setting up a client initiated TCP socket for reverse traffic, from the server to the assorted clients that connect. I've done a bit of research, and I already understood that each client should have their own thread for handling outgoing messages, along with another thread simply for accepting the incoming connections. I'm unsure of how to actually achieve this, and I've done some research into the topic.
I've found this: http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html
The resource above basically verified my original suspicion that this would have to be handled by threads dedicated to the client. They included psuedo code here, which is representing my listener thread.
while (true) {
accept a connection;
create a thread to deal with the client;
}
I'm a bit of a visual learner, and I have been searching for some type of an example where this is done. I'm unsure of what variable I'd be passing over to the thread that keeps the original connection open, and pushes data back to clients. I'm also having a little bit of trouble grasping whether it even keeps the same socket open, or if a new one needs to be established, which then, makes me believe a firewall could interfere, but I know that won't be the case.
Can somebody explain this for me in detail? If possible, an example would be greatly appreciated!
I'll be likely replying and commenting on responses in about 15-30 minutes from the time this is posted.
What you are doing sounds correct. I typically implement a server like this (simplified version with no tracking of the clients and so on):
#Override
public void run() {
//start listening on the port
try {
serverSocket = new ServerSocket(port);
logger.info("Listening for connections on port " + port);
} catch (IOException e) {
logger.error("Cannot start SocketListener on port " + port + ". Stopping.", e);
return;
}
while (!stopped) {
try {
//wait for connection
Socket newSocket = serverSocket.accept();
ClientThread client = new ClientThread(newSocket);
Thread clientThread = new Thread(client, MEANINGFUL_THREAD_ID);
clientThread.start();
} catch ...
}
}
where serverSocket is a ServerSocket instance variable and stopped is a flag I use to stop the listener thread.
So to answer your questions in the comment, you normally pass the Socket object to each client thread so that that thread can work with the input and output stream and handle closing of the socket and so on. Once you "accept" a socket connection, you do not need to recreate the ServerSocket, you simply call .accept() again to start waiting for a new connection.
In most cases, you will need to keep track of all client threads in your server so that you can stop the server gracefully or do broadcasts for example.

Return value of server.accept() while waiting for connection

What does the server.accept() method return when no new socket is formed, i.e., when no new connection is made? Is it possible to go to next line of code while sever.accept() is waiting for a new connection?
If you want to do something while the server is waiting for a connection you can use multiple threads. In a single-threaded application you cannot call a function and continue with your work without waiting it to return: either you are waiting for the server to accept a connection, or you are doing other computations.
A possible alternative to threads is setting the SO_TIMEOUT socket option on the server socket. This makes the call to accept throw an exception if a connection is not received within the timeout, allowing you to go to the next line.
For example:
ServerSocket ss = new ServerSocket(8989);
ss.setSoTimeout(10000); // 10 seconds
Socket clientSocket;
try {
clientSocket = ss.accept();
// process connection from client
} catch (SocketTimeoutException ste) {
// connection was not received,
// do something else
}
Another alternative is using non-blocking IO and the Selector class. Here's an example of a non-blocking socket server written this way.
No. server.accept() is a blocking method and it will wait.
From the javadoc
Listens for a connection to be made to this socket and accepts it. The
method blocks until a connection is made.

shutdown TCP thread server

I coded a little TCP thread Server, which creates a new thread for every server.accept(). Nearly everything works great, but I have problems to kill all threads per interrupt. (I use a ServiceExecutor to manage the threads. Therefore I use the shutdownNow method to reach the interrupt-methods) The Worker-instances use a BufferedReader and it's readline-method to receive and compute the input. AFAIK the readline blocks and would not react on an interrupt, but how to stop it?
while(!isInterrupted()){
try {
clientSocket = this.serverSocket.accept();
} catch(IOException e){
break;
}
this.threadPool.execute(new ThreadWorker(clientSocket));
}
threadPool.shutdownNow();
try{
serverSocket.close();
}catch(IOException e){
//todo
}
I tried to close the ServerSocket to kill the Input/Output Streams, but it didn't work as expected.
A couple alternatives:
1) If you are closing the whole app, and there is nothing of importance to explicitly close, call System.Exit(0). HEALTH WARNING - doing this causes some developers to have apoplectic fits and post endlessly about 'cleaning up gracefully'.
2) Keep a thread-safe list of all client sockets in the accept() thread. Pass a reference to this list as part of your client context that is passed to the client<>server threads. Add new connections to the list in the accept() thread. When a client thread detects a disconnect, remove its entry from the list. When you want to close all clients, iterate the list and close the client sockets - this will cause the readline method to return early, with an error, in the client threads.

How to interrupt a thread if it is to open socket?

I have tried to close the current thread that is a part of multi-threading server.
The thread is ready to open the socket that may be accessed by clients.
Everything works fine except when the code below is contained in while() loop.
new ServerThread(serversocket.accept(), this.Rstr,
bag.numberofDatatoAcquire).start();
Here is the code for the server:
public void run() {
System.out.println("This has been called ");
try{
System.out.println("This has been tried");
serversocket = new ServerSocket(this.iPort);
Thread thisThread = Thread.currentThread();
while(!thisThread.isInterrupted()){
new ServerThread(serversocket.accept(), this.Rstr, bag.numberofDatatoAcquire).start();
//sending socket accessed, where it will store the data and how much it will collect it.
System.out.println("This has been running");
Thread.sleep(10);
}
}catch(InterruptedException e){
//why bother? it is an usual happening...lol
}catch(IOException ioe)
{
System.err.println("Can't open the socket on port");
}
finally{
System.out.println("Thread is dead and ready for change");
}
}
And this is a part of GUI events: this works well without "new ServerThread..." code.
private OverWatch EW = new OverWatch(bag.iPortOrder, bag.SessionAcquisitionSavingDirectory);
....
private void OverWatcherControl(boolean checker)
{
if(checker)
EW.start();
else
EW.interrupt();
}
Since the variable bag.numberofDataToAcquire (public integer type) is supposed to be changed whenever user wants, I think I have to stop this thread and change the variable then run this thread again. Am I wrong? Or how can I interrupt this thread?
Thanks,
ServerSocket.accept() is a blocking call that is not responsive to thread interruption. Almost all the java.net blocking calls (connect, read, accept, etc) do not respond to Thread.interrupt(). This behavior is "as designed".
A way to wake up a thread blocked in .accept() or .read() is to close the underlying socket.
Alternatively you could set SO_TIMEOUT (setSoTimeout) on the ServerSocket, which will cause .accept() to wake up periodically by throwing a SocketTimeoutException. You could catch that exception and use it as an opportunity to check the interrupt status on the thread.
The java.nio package (Java 1.4+) provides an alternate sockets API that is more responsive to interruption.
Just as an alternative to using a timeout or killing the socket:
Fake a new connection to the socket. This will "wake up" the accept() and then an additional signaling mechanism (e.g. flag or interrupt check) can be used (although the logic would have to be altered slightly from shown to not "lie" in the println).
I have used this approach before and it worked well: no need to wait for a timeout (even a sort one) or handle another exception and the socket remains open/valid (which may or may not be desired). On the other hand, I'm not sure what would happen on a really long/broken TCP handshake, but that's a case I never encountered ;-)
Happy coding.
I initially answered it using the serverSocket.setSoTimeout(millis) and handling the SocketTimeoutException. See below.
A better way to do it would be to use ServerSocketChannel which gets interrupted in the accept() call when you call thread.interrupt() so you don't have to spin at all. So you'd do something like:
ServerSocketChannel socketChannel = ServerSocketChannel.open();
socketChannel.socket().bind(new InetSocketAddress(this.iPort), 10);
...
while (! thisThread.isInterrupted()) {
// channel accepts _are_ interrupted by the call to thread.interrupt()
// it throws ClosedByInterruptException when interrupt() is called
SocketChannel accepted = socketChannel.accept();
new ServerThread(accepted.socket(), this.Rstr,
bag.numberofDatatoAcquire).start();
}
I'll take a whack at explaining the code:
while(!thisThread.isInterrupted()){
new ServerThread(serversocket.accept(), this.Rstr,
bag.numberofDatatoAcquire).start();
Thread.sleep(10);
}
I think your problem here is that serversocket.accept() hangs waiting for a socket to be accepted. From the accept() javadocs:
Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.
You need to set a timeout on your socket before the while loop. You can use setSoTimeout(millis) for that.
serversocket.setSoTimeout(10000);
This will then throw a SocketTimeoutException if it times out. Then you won't need the Thread.sleep(10) (which is for 10ms btw) because the sleeping will be done inside of the accept() method. I would not recommend accept(10) because that would spin pretty aggressively.

How to make an accepted socket non-blocking in java

I'm accepting a connection from a client and then passing that connected socket off to another object, however, that socket needs to be non-blocking. I'm trying to use getChannel().configureBlocking(false) but that does not seem to be working. It needs to be non-blocking because this the method below is called every 100ms. Is there some other way that I should be making this non-blocking? Thanks for any help!
public void checkForClients() {
DataOutputStream out;
DataInputStream in;
Socket connection;
InetAddress tempIP;
String IP;
try {
connection = serverSocket.accept();
connection.getChannel().configureBlocking(false);
System.err.println("after connection made");
in = new DataInputStream(connection.getInputStream());
out = new DataOutputStream(connection.getOutputStream());
tempIP = connection.getInetAddress();
IP = tempIP.toString();
System.err.println("after ip string");
// create a new user ex nihilo
connectedUsers.add(new ConnectedUser(IP, null, connection, in, out));
System.err.println("after add user");
} catch (SocketTimeoutException e) {
System.err.println("accept timeout - continuing execution");
} catch (IOException e) {
System.err.println("socket accept failed");
}
}
Two things:
Why aren't you using a ServerSocket if you're listening for connections?
If you want to accept multiple clients you want to use a loop.
The basic structure of a multi-client server is:
while (true) {
// accept connections
// spawn thread to deal with that connection
}
If the issue is blocking on the accept() call, well that's what accept() does: it blocks waiting for a connection. If that's an issue I suggest you have a separate thread to accept connections.
See Writing the Server Side of a Socket.
I would expect your code to block on the accept call, never getting to the configureBlocking call.
I typically spin off a separate thread for each socket connection, and let it block until a connection is actually made/accepted This allows the main thread to continue unblocked while it is waiting for client connections.
If you're looking for non-blocking sokets, my suggestion is to use Selectors and ServerSocketChannels with the NIO package.
http://java.sun.com/j2se/1.4.2/docs/guide/nio/
If the typical blocking socket doesn't give you the availability you need (a connection every 100ms does seem tight). You should look at a non-blocking socket. Here is a tutorial. You can also look at Apache MINA to make this easier.
One approach is to use an I/O loop (event loop) in a single threaded environment. Take a look at Deft web server for inspiration. (Especially the start() method in IOLoop)

Categories