I have written a Client-Server program using java Sockets and it works just fine. Now I'm trying to move on to HTTPS for communicating between client and server.
My code is based on java built-in Sockets (Socket and ServerSocket) and it works just fine. But when I use HTTPS Sockets (SSLSocket and SSLServerSocket) without changing the rest of the code, unfortunately won't work anymore.
The program needs persistent connection between server and client to let them send and receive data for minutes. The problem seems to be that HTTPS connection has been closed in server or client side after first transaction has been completed.
To be more precise, This is what happens:
1. Server creates a SSLServerSocket and calls "accept()" on it.
2. Client creates a SSLSocket and connects to the server. Then writes to server through "DataOutputStream"
3. Server reads the client through "DataInputStream" and sends back its response through "DataOutputStream".
4. Client reads the server through "DataInputStream".
Everything is OK till now! But after that when the client sends another stream, on the server side no data would be "available()" on the server through the same method used before.
Is there a way to keep this connection alive?
Tnx for ur helps in advance!
InputStream.available() isn't a reliable way of detecting socket input. You therefore have no evidence that the connection isn't alive. Just block in a read method. This implies a dedicated thread for reading per client.
Related
The problem:
I am having some strange behaviour from a Jetty server (rest over https) when some client connections are closed (client-side) before the server has had time to reply. Normally this is well managed and expected by a webserver/application server but in a specific instance something breaks the server that stops replying.
I am trying to reproduce programmatically and locally the issue, opening a client connection and closing it before the server has had time to reply, but I do not have much experience with a situation like this, normally the clients I write are expected to not die immediately.
I am not interested in the language/application I have to use to replicate my case, it can be a Java program, a netcat command, telnet, dotnetcore... The only limit I have is that it should run on a Kubernetes pod, if possible.
I am trying to use Java to open a socket then close it immediately, or to create an Http client and stop it immediately after a request sent, but with no luck at the moment.
At the same time I am looking at netcat, but I fear it's too low level for a rest request.
I am working on a java server-client based app and using Netty (4.0.27.Final) for TCP socket connections. I have facing an issue with client side.
In client I use one BootStrap, one NioEventLoopGroup for multiple clients (100+ concurrent clients) and just call the following for each new client connection.
b.handler(new MyConnectionInitializer());
b.connect(IP, PORT).sync().channel().closeFuture().sync();
Now after doing work each client calls ctx.disconnect(). After calling it, all the clients receive ChannelInactive and connection to server for all the clients get disconnect. While I just want that only the client for which ctx.disconnect is called should be disconnect.
Should I call some other function instead of ctx.disconnect()?
Any help appreciated.
You should use close() instead of disconnect(). As far as I understand disconnect() actually closes the connection (and with it all other channels that might still be open) while close() only closes the current channel.
Please someone correct me if I wrote something wrong.
There is an existing service that i would like to write a dummy service (using Netty) for. It will be used for testing purposes.
The existing client code fragment for the service looks like:
Socket socket = new java.net.Socket();
socket.connect(new InetSocketAddress("localhost", 8080), 10000);
socket.setSoTimeout(20000); // set a timeout of 20 seconds
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
// write some string to the server and wait for answer
out.println("SomeCommand");
// server has written some answer, read it
char[] c = new char[2];
ir.read(c, 0, 2);
String cs = new String(c);
if ("OK".equals(cs.toString())) {
// write some more string's to the server
}
// we're done, close the connection
out.println("BYE");
out.close();
socket.close();
Is Netty the right framework to create a server for java.net.Socket connections? (If not, which framework should be used, if any?)
I am trying to find a way to start with Netty using the QuoteOfTheMoment example. The QuoteOfTheMomentServerHandler does basically what i want, upon the incoming message, return some answer so that the above snippet can read the answer using the inputstream but the above socket cannot make a connection to the QuoteOfTheMomentServer. The error is "connection refused".
[EDIT] More clarification:
The problem (i think) is not connecting or the port i use. Let me try to better ask the question:
I just started with netty (no nio experience) and am not familiar with the different types of channels, pipelines and what not.
The server should, like a servlet request/response (like, not http or trying to rebuild a http servlet impl), react on a inputString written to the output-stream as in the code fragment and write back some string/bytes to the input-stream as in the code fragment, so the client only then moves on. So the connection should stay open but also be synchronous, the client waits for answer from the server. If i use the example "Writing the Server Side of a Socket" in the java tutorial i am able to get it working for the client. But i want to utilize the thread handling etc. from netty.
The QuoteOfTheMomentServerHandler seems as server side implementation what i want but can that setup handle the given client code ?
So the question is which kind of pipeline, channel or something like that should be used given the way the client works ?
Again, the client and server are existing. I want to build a dummy server implementation to work with the existing client.
Netty is a TCP/IP framework. So yes if you are developing a TCP/IP server this toolkit is good to use.
I assume you are getting a error when trying to connect the client to the server. Also the server should also be running.
When getting a the connection refused error there are a couple of thine to check. First one is the firewall(if any) on the server allowing connections to port 8080? Secondly from your client machine try open a telnet session to the server something like:
Telnet yourserverip 8080
This opens a socket connection to the server. If you get a error message Google it.
The last one is that you might be running a server like tomcat, glassfish, IIS which uses port 8080 already. Try a non standard port like 10810 for example.
UPDATES:
If you are new to netty please read the users guide found here http://netty.io/docs/stable/guide/html/.
I had a look at the Quote of the moment service and I do believe I found part of the problem. The Quote of the moment service is a broadcast UDP/IP client and server. UDP is a much more lightweight "version" of TCP IP. It does not guarantee delivery to the client or server and it is broadcast. UDP is sort of like a radio broadcast as it is generally not targeted to a specific IP but broadcast over the entire network. Thus you normal TCP IP connection will not be able to work on the UDP server.
See this link on how to write a UDP Client http://systembash.com/content/a-simple-java-udp-server-and-udp-client/.
I would suggest that you convert the Quote of the moment server from UDP to TCP/IP server as this will give you some practise in creating a TCP/IP server without getting into too much detail. Once you are comfortable with that you should be able to start once from scratch.
Just remember that Netty handles the NIO part for you. It is a higher level framework based on NIO thus hiding a lot of the detail from you. You dont need to know NIO that well to use netty but you need to understand the Netty concepts well.
If you have a Java client Socket connected to a Java server's ServerSocket, how do you then obtain the Java server object in the client class?
I have had a look at the Socket class and there seems to be no method for getting hold of a server object through the Socket.connect()ion.
The reason I am asking, is that I would like to send an instruction from my client to the server to deregister the client from subscribing to further updates from the server. My server-client relationship is based on the Observer pattern.
To carry out the instruction, I believe I need to obtain the server object.
I am asking this question because I have not found anything on Google or stackoverflow.com which combines the Observer pattern with server-client socket relationships.
Of course that may indicate my approach is terminally flawed, but if it is, let it be a warning to others :)
Its not 100% clear what you're asking, but here goes.
If you want the remote client to indicate to the server side that it is done, then have it send a message that the server side understands to mean done, then simply close the socket object on the server side and on the client. The server socket may continue listening for more connections if appropriate.
If the socket handling the client connection on the server side is to shut down the server socket so it will no longer listen for incoming connections, then simply pass both sockets to the code that is handling the socket which is handling the client connection.
My TCP server is implemented using Netty. My client using vanilla java.net.Socket to connect to this server. I'm using the same socket to send multiple requests to the server. Once done with all the requests the client calls socket.close().
I'm not closing the channel anywhere in my server code. Also, I've set TCP KEEP_ALIVE on my server. Will closing the socket on the client end automatically close the channel on the server or do I've to do something else explicitly and what is the best practice ?
Usually, if an application closes a socket, its remote peer also notices that the closure. Therefore, you don't need to call close() on both side. However, sometimes, due to network problems, you might not get notified when the remote peer closes the connection. To work around this problem, it's a good idea to send some message periodically, and then you will detect the unexpected closure sooner.
Please note SO_KEEP_ALIVE will not help much here because for most operating systems because the default keep alive time is very long.