I learned an example of usage of sockets. In this example a client sends a request to a server to open a socket and then the server (listening to a specific port) opens a socket and everything is fine, socket is "opened" from both sides (client and server).
But it is still not clear to me how flexible is this stuff. For example, is it possible for the client to close an opened (from both ends) socket and to reopen it again (under condition that the server keeps the socket opened).
Is it possible for the server to "know" that a socket was closed on the client side? Is it possible for the client to know that a socket was closed on the server side?
ADDED:
One more important thing to me. What happens if a application (no mater server or client) crashes, abnormally terminated, killed? Will it close all sockets opened on the side of the application?
ADDED 2:
What if an application on one side of the socket is switched off (killed, closed, terminated) and then it is switched on again (on the same IP address and the same port). Should we create a new socket between the two applications or we can use the old socket (created before the crash).
A socket can be used for a lot of things for which the answers to these questions would change, but I'll assume you're talking about TCP.
For example, is it possible for the client to close an opened (from both ends) socket and to reopen it again (under condition that the server keeps the socket opened).
No, because TCP will perform a goodbye and you can't pick up the connection from there again. You'd have to do the three-way handshake again, and that starts a brand new connection.
Is it possible for the server to "know" that a socket was closed on the client side? Is it possible for the client to know that a socket was closed on the server side?
Yes. TCP can send out a goodbye packet or one side can time out and it's entirely possible to detect these scenarios in both cases.
Is it possible for the server to
"know" that a socket was closed on the
client side?
When server tries to send some data to that client a correspondent exception will be thrown.
One more important thing to me. What
happens if a application (no mater
server or client) crashes, abnormally
terminated, killed? Will it close all
sockets opened on the side of the
application?
Exceptions are created for handling these abnormal cases. If there is a black out and a client (or server) is turned off then other side will get an exception as soon as it try to interact with turned off side.
UPD:
What if an application on one side of
the socket is switched off (killed,
closed, terminated) and then it is
switched on again (on the same IP
address and the same port). Should we
create a new socket between the two
applications or we can use the old
socket (created before the crash).
Create new socket.
Q1->Is it possible for the server to "know" that a socket was closed on the client side? Is it possible for the client to know that a socket was closed on the server side?
A1 -> The sever will know, if client closes socket and vice versa. Actually FIN will be sent from the end, which is initiating to close connection.
Q2-> What if an application on one side of the socket is switched off (killed, closed, terminated) and then it is switched on again (on the same IP address and the same port). Should we create a new socket between the two applications or we can use the old socket (created before the crash).
A2->If socket is created, fd number is bind with ip-addr & port, so socket on server side has server-ip & some port and socket on client side has client-ip & some port. if crash happened at client the all fd are freed and it can not be reused.if we use the same fd, system will treat it as normal file fd.
Related
In a client-server application, I send a string to the server in a separate thread:
dataOutputStream.writeUTF(_dos);
dataOutputStream.flush();
But I get in another thread java.net.SocketException: Connection reset in the line:
mes = dataInputStream.readUTF();
At the same time, the server does not receive anything (I checked this in wireshark) and continues to listen to the socket.
The question is: is it possible, if the client socket is damaged, but the server socket is working, to restore the operation of the client socket and thus restore the client-server connection, without restarting both?
The connection is gone. On the client side, you will need to connect again.
Generally speaking, TCP implementations do not allow you to issue a connect on a socket that has become disconnected. You can try, but it's safest to make a new socket object. Even if it works for you, the result may be non-portable.
The server of course also has a socket on a defunct connection, so it needs to close its end. A new socket will be created on 'accepting' the new connection from the client.
I am currently working on a simple multiplayer game where serveral clients need to connect to a server.
My server consits of a single serverSocket. This serverSocket accepts incoming connections and hands them over to connection object that starts a separate thread.
ServerSocket seso = new ServerSocket(12345);
while(true){
Socket toClient = seso.accept();
new Connection(toClient); //creates a thread that opens streams etc
}
Clients open a new Socket and connect to this server.
Socket toServer = new Socket();
toServer.setReuseAddress(true);
toServer.bind(new InetSocketAddress(65432)); //always using the same port
toServer.connect(new InetSocketAddress(serverIP,12345));
Now if i close the connection to the server using toServer.close(); and try to connect again to the server, i get an "address already in use: connect" exception.
Using TCPView i can see that the state of the client procress changes to TIME_WAIT. But shouldn't i be able to use this port again because of setReuseAddress(true)? Am i using it wrong or is it an server problem?
I do always call .close() on toClient and toServer. Nevertheless i always have to wait until the socket is completely closed (after TIME_WAIT) before this client can connect again to the server.
When i close the entire application, the socket is immediately closed (not in state TIME_WAIT) and this client can connect to my server. (And ofc there is a connection reset exception in my server)
How can I do that without always closing the application ?
Thanks for your help.
To expand on my comment, a client / server protocol requires the server to listen on a port known to or discoverable by the client -- that can be considered the definition of "server" -- but it does not ordinarily require clients to connect from a specific port. If you do not bind the client socket to a particular port, then the underlying system will choose an available (source) port automatically and transparently.
If the server depends for some reason on clients connecting from a particular port, then you should re-evaluate that aspect of your design. If it does not, then you are making your own trouble by having clients connect that way. This should be all you need to do:
Socket toServer = new Socket();
toServer.connect(new InetSocketAddress(serverIP, 12345));
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.
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.
In Java, if I connect to a client to a server via a socket and the client has an exception which causes it to crash, is there any way the server can detect that the socket connection is lost.
I assume one method would be have some sort of heartbeat polling the client, but is there a simpler/easier way?
There are a few ways, depending on what you consider to be a "crash".
If the client process dies, the client OS will close the socket. The server can detect this by performing a read(), which will either return -1 (EOF) or raise a SocketException ("connection reset").
If the client gets into an infinite loop, the connection will remain open; the only way to detect this is by incorporating some kind of "heartbeat" into your protocol.
If the client host is rebooted or the network connection breaks, the server may not notice unless either:
the protocol has a "heartbeat" mechanism as above, with some kind of timeout, or
TCP keepalive is enabled on the socket by calling socket.setKeepAlive(true) - this instructs the OS to periodically* send a packet to check that the remote end of the connection is alive, closing the connection if not
*both Windows and Linux default to 2 hours; you can change this system-wide but not per-socket (under Java, anyway)
TCP sockets do this anyway, and Java exposes it to the developer. See setKeepAlive() / getKeepAlive() in the Socket class. If a TCP message isn't sent from the client to the server for a certain period of time, the socket will close, and the server can remove the session information because it still has its endpoint.