Swing TCP Client ends connection to server but can then reconnect afterwards - java

I have a Swing client which has a connect and cancel button so it can attempt connection to the server or end a current connection. I'm trying to make it so the client can connect to the server, end the connection and then connect to the server again multiple times.
My understanding is that typically when a client and server end a connection regardless of who ends it the client closes its streams and socket. Obviously then, they cannot be reused for another connection attempt. Right now I have the Socket and stream vars as private instance variables and a method for connecting to server which creates a new socket and then methods for opening and closing streams.
Just wondering how something like this could be typically handled. I've thought about having one humongous method which creates new socket, streams and handles all communication and closing of streams and socket, but it seems messy. Or maybe having a new thread create everything and then when the communication is over terminate the thread.
Ideas appreciated.

- Create a separate Thread at the Server end, when the Client connects to the Server.
- Do the process of read and writing onto the client socket for that particular client into that particular thread.
- And then terminate the Client thread when its done.
- If you again try to connect it, a new thread will span.
- You can always create a HashMap to keep tab on Client-Socket to Thread relation.

You should put all the "logic" in a new class, different than the GUI.
Then because you have 2 buttons, your Gui class should be able to call at least 2 methods on the logic class : connect() and disconnect(). Then in these methods you can handle all the work that is required to connect to a server, open/close streams etc...
That will make your code more clear, more maintainable, and maybe more evolutive if you plan to add features.

I would prefer create a thread for each socket creation and handle request and response withing that thread.

Related

What kind of strategy is more efficient: create a new socket or use one already created?

I'm working on a Java client-server program. I use a socket to make the connection but I'm not sure about the efficiency. So, this is my question:
every time that I need a connection with a server, is it more efficient to create a new socket or to use the one created for the previous connection?
I think I need a method to verify if the client is already connected.
In terms of performance is more efficient re-using a previously created socket. But this don't need to be the best solution, it depends on each case.
The idiom case is having a ServerSocket in the server side that returns a Socket each time a new client connects to to it. If you require multiple clients to work against the server you could create a Thread to treat each client passing it the returned Socket.
Moreover, you don't need a method to verify you have a client already connected, ServerSocket returns a new Socket each time it happens.
Please, read more about this topic in Oracle tutorials.

Must a listening socket runs in thread?

I have some problems understanding how a socket should be handled. I get that server socket must runs in its own thread, because it must check if there are new connections. Now, i'm not sure if every socket opened by a new connection should runs in a thread.
What i have in mind is checking every x time the socket states. If it has something to be read, then read. If not, check the next socket. I see some examples where this process is done in a thread, but i dont want a socket to do stuff, just want to read if it has some data, and process them.
The answer is no, you don't need to listen in a separate thread. But, just realize that while you are "listening" your entire program will be waiting for that to complete before moving onward.
So unless you are fine with your entire program waiting, I would suggest a separate thread.
You can also have one thread which communicates with all sockets in a round-robin manner. It checks each socket if it has new data, and when it hasn't it checks the next.
Another alternative is to use NIO (New Input/Output).
The idea behind NIO is that you have a thread with one Selector which owns multiple Channels (a channel can be a network socket or any other IO interface). You then call selector.select() in a loop. This method blocks until one or more channels have data, and then returns a set of these channels. You can then process the data the channels delivered.
Here is a tutorial.
The problems with round-robin using available() are many.
It assumes that available() actually works, which isn't guaranteed.
It assumes that all clients need the same amount of service.
N-1 clients wait while one client is serviced.
A non-responsive client can block not only your application but all the other clients.
I'm sure there are more.
Don't do this. Use threads or NIO.

Listener for incoming messages

I am currently trying to create a chat application using the Socket and ServerSocket classes, but i kinda ran into a roadblock. I need some kind of listener to execute a certain block of code when a message is incoming from the server or the client, but i can't seem to find one. An option would of course be to just check for incoming messages every 10 ms or something, but isn't there a smarter solution?
In general, you should assign a Thread to each Socket you are reading, so that Thread can block on the socket and wait for incoming information.
You should take a look at DataFetcher: http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/
This class can work asynchronously, and notify a FetcherListener when new data is available
I recommend Netty or Mina. As for Socket and ServerSocket, the read() calls are blocked, so in a way the code below the read()s are executed whenever there's incoming data.
Beware of the incomplete message though, because Sockets provide a stream of bytes and the applications are usually more comfortable with discrete messages.

Keeping persistent connections from a home-made Java server

I've built a simple Java program that works as a server locally.
At the moment it does a few things, such as previews directories, forwards to index.html if directory contains it, sends Last-Modified header and responds properly to a client's If-Modifed-Since request.
What I need to do now is make my program accept persistent connections. It's threaded at the moment so that each connection has it's own thread. I want to put my entire thread code within a loop that continues until either Connection: close, or a specified timeout.
Does anybody have any ideas where to start?
Edit: This is a university project, and has to be done without the use of Frameworks.
I have a main method, which loops indefinitely, each time it loops it creates a Socket object, a HTTPThread object is then created (A class of my own creation) - that processes the single request.
I want to allow multiple requests to work within a single connection making use of the Connection: keep-alive request header. I expect to use a loop in my HTTPThread class, I'm just not sure how to pass multiple requests.
Thanks in advance :)
I assume that you are implementing the HTTP protocol code yourself starting with the Socket APIs. And that you are implementing the persistent connections part of the HTTP spec.
You can put the code in the loop as you propose, and use Socket.setSoTimeout to set the timeout on blocking operations, and hence your HTTP timeouts. You don't need to do anything to reuse the streams for your connection ... apart from not closing them.
I would point out that there are much easier ways to implement a web server. There are many existing Java web server frameworks and application servers, or you could repurpose the Apache HTTP protocol stacks.
If it should act like a web service: Open 2 sockets from the client side, one for requests, one for
responses. Keep the sockets and streams open.
You need to define a separator to notify the other side that a
transfer is over. A special bit string for a binary, a special
character (usually newline) for a text-based protocol (like XML).
If you really try to implement an own http-server, you should rather make use of a library that already implements the HTTP 1.1 connection-keepalive standard.
Some ideas to get you started:
This wikipedia article describes HTTP 1.1 persistent connections:
http://en.wikipedia.org/wiki/HTTP_persistent_connection
You want to not close the socket, but after some inactive time period (apache 2.2 uses 5 seconds) you want to close it.
You have two ways to implement:
in your thread do not close the socket and do not exit the thread, but instead put a read timeout on the socket (whatever you want to support). When you call read it will block and if the timeout expires then you close the socket, else you read next request. The downside of this is that each persistent connection holds both a thread and a socket for whatever your max wait period is. Meaning that your solution doesn't scale because you're holding threads for too long (but may be fine for the purposes of a school project)!
You can get around the limitation of (1) by maintaining a list of tuples {socket,timestamp}, having a background thread monitor and close connections that timeout, and using NIO to detect a new read on an existing open socket. So after you finish reading the initial request you just exit the thread (returning it to the thread pool). Obviously this is much more complicated but it has the benefit of freeing up request threads.

Reconnect to server when socket is closed

I've got a program that opens N sockets to a server, each one in a different thread.
After sending two string for login porpuse, the program listen to the server, until an error occurs and the server sends the disconnect command, and the socket is closed. I want the program to reconnect once the server closes the socket : is it possible?
SocketList.add(new ConnectionHandler(id, actualSocket, out, in));
SocketRead p = new SocketRead(in, out, rowid);
new Thread(p).start();
I'd like that, when the socketread object receive the "DISCONNECT" command, the socket is restarts ( if needed, opening another thread).
I'm not sure what SocketList, ConnectionHandler or SocketRead are, so I'll assume they are classes that you've written for your application.
If you want to be able to reconnect, then you are going to have to change the structure of your code. On the one hand, the SocketRead object doesn't have the information needed to allow it to reconnect. On the other hand, the controlling code (your snippet) isn't able to detect the disconnect command.
It is not clear what will work best, but here are a couple of options:
pass the Socket (or the InetAddress and port number) to SocketRead and make it responsible for opening a new socket.
pass the Thread to the ConnectionHandler and make it responsible for detecting the death of the thread, creation of a new Socket and creating a new Thread.
pass the ConnectionHandler to the SocketRead object, hand have the latter call a callback or event handler method in the former when the socket disconnect occurs.
In the event handler of the DISCONNECT event, put in your reconnection logic.
For more information on how to write EventHandlers refer this link.

Categories