I'm building an iPhone app called AcaniChat. The server uses Node.js ws module. Can I assume that the Node.js ws close callback function is guaranteed to be called for every connection that ends? What if all of a sudden, I blew up my iPhone with a grenade? Would close get called on the server?
No. If the client closes its socket, the TCP connection would be closed, but the server socket would remain "open", although any further operations on the socket would result in an error (or an indication that the client closed the connection).
If the phone was blown up with a granade, the TCP connection wouldn't be closed gracefully, and any further operations on the server socket would result in an error (one different from the error if the client closed its socket).
So a close on a socket does two things: it closes the connection (if it isn't closed already), and releases any local system resources used for the socket object. So you should call close in all cases.
Related
I was playing with websocket a bit (using Sails.js with its built-in socket thing, which is based on Socket.io).
I noticed Chrome receives two frames every 25 seconds. I thought this was some kind of polling to tell the connection was still on.
But then, I cancelled the server and Chrome was notified immediately.
Also I closed the Node process by force with the kill command, and still Chrome was notified, so that means it wasn't Node sending a signal before shutting down the server.
How does this happen?
Normal TCP socket connections do this, so it'd be surprising if websockets didn't.
The server kernel is responsible for cleaning up when the server process dies/exits/is killed. This includes releasing memory, closing files, and shutting down sockets. Cleanly shutting down a TCP socket requires sending a message to tell the peer.
Interestingly, on some old versions of Windows with userspace winsock, this didn't happen if the server process crashed. On all OS with compliant TCP support, it should be guaranteed unless the kernel itself hangs, the machine loses power, or the network breaks.
From HTTP:The definitive guide :
But without Content-Length, clients cannot distinguish between
successful connection close at the end of a message and connection
close due to a server crash in the middle of a message.
Let's assume that for this purpose the "server crash" means crash of the server's HW or OS without closing the TCP connection or possibly link being broken.
If the web server crashes without closing TCP connection, how does the client detect that the connection "has been closed"?
From what I know, if FIN segment is not sent the client will keep waiting for the data unless there is a timer or it tries to send some data (failing which detects TCP connection shutdown).
How is this done in HTTP?
If the web server crashes without closing TCP connection, how does the client detect that the connection "has been closed"?
Since the closing will be done by the kernel that would mean, that the whole system crashed or that the connection broke somewhere else (router crashed, power blackout at server side or similar).
You can only detect this if you sent data to the server and don't get any useful response back.
From what I know, if FIN segment is not sent the client will keep waiting for the data unless there is a timer or it tries to send some data (failing which detects TCP connection shutdown).
How is this done in HTTP?
HTTP uses TCP as the underlying protocol, so if TCP detects a connection close HTTP will too. Additionally HTTP can detect in most cases if the response is complete, by using information from Content-length header or similar information with chunked transfer encoding. In the few cases where the end of response is only indicated by a connection close HTTP can only rely on TCP do detect problems. So far the theory, but in practice most browsers simply ignore an incomplete response and show as much as they got.
I'm trying to determine if a client has closed a socket connection from netty. Is there a way to do this?
On a usual case where a client closes the socket via close() and the TCP closing handshake has been finished successfully, a channelInactive() (or channelClosed() in 3) event will be triggered.
However, on an unusual case such as where a client machine goes offline due to power outage or unplugged LAN cable, it can take a lot of time until you discover the connection was actually down. To detect this situation, you have to send some message to the client periodically and expect to receive its response within a certain amount of time. It's like a ping - you should define a periodic ping and pong message in your protocol which practically does nothing but checking the health of the connection.
Alternatively, you can enable SO_KEEPALIVE, but the keepalive interval of this option is usually OS-dependent and I would not recommend using it.
To help a user implement this sort of behavior relatively easily, Netty provides ReadTimeoutHandler. Configure your pipeline so that ReadTimeoutHandler raises an exception when there's no inbound traffic for a certain amount of time, and close the connection on the exception in your exceptionCaught() handler method. If you are the party who is supposed to send a periodic ping message, use a timer (or IdleStateHandler) to send it.
If you are writing a server, and netty is your client, then your server can detect a disconnect by calling select() or equivalent to detect when the socket is readable and then call recv(). If recv() returns 0 then the socket was closed gracefully by the client. If recv() returns -1 then check errno or equivalent for the actual error (with few exceptions, most errors should be treated as an ungraceful disconnect). The thing about unexpected disconnects is that they can take a long time for the OS to detect, so you would have to either enable TCP keep-alives, or require the client to send data to the server on a regular basis. If nothing is received from the client for a period of time then just assume the client is gone and close your end of the connection. If the client wants to, it can then reconnect.
If you read from a connection that has been closed by the peer you will get an end-of-stream indication of some kind, depending on the API. If you write to such a connection you will get an IOException: 'connection reset'. TCP doesn't provide any other way of detecting a closed connection.
TCP keep-alive (a) is off by default and (b) only operates every two hours by default when enabled. This probably isn't what you want. If you use it and you read or write after it has detected that the connection is broken, you will get the reset error above,
It depends on your protocol that you use ontop of netty. If you design it to support ping-like messages, you can simply send those messages. Besides that, netty is only a pretty thin wrapper around TCP.
Also see this SO post which describes isOpen() and related. This however does not solve the keep-alive problem.
The Arduino Ethernet (board or shield) supports a maximum of 4 connections. If acting as a server, it is very easy to cause a denial of service: just open 4 connections to the Arduino without sending any data. The server code will never realize that connections were established, as the EthernetServer::available() method only returns an EthernetClient when the connection has data available. The connections will thus remain open for as long as the client maintains them, preventing the Arduino from processing other requests, without an opportunity for the server to close them after some time.
So the question is: is there a way to set a timeout on idle connections, maybe at the Wiznet chip level?
As background information, the GET HTTP model of a dialog is called "stateless" what this means is that the connection can be closed and then re-opened with no loss of information.
However, there is an HTTP keyword where the browser can ask to keep a connection open.
The server is allowed to close a connection, in fact HTTP/1.1 defines a message from the server to browser that does just that.
So, in an Arduino where you control all of the software (TCP/IP stack and server code), then you should be to modify the WizNEt libs or add your own wrappers that time-out a dialog and close it, independent of what the browser is doing.
Thus, no DNS (or at least the keep the line open style of DNS).
Get the HTTP/1.1 spec (it is on the web) for more information and specifics.
If a client cancel its request, the application server is suposed to throw the following error :
java.net.SocketException: Connection reset by peer: socket write error
But what is exactly happening ?
Let's say I'm doing a very expensive operation on the server side, and I'm writing some data to the outputstream everytime my server service get a new result (kind of streaming).
In the middle of this operation, the client cancel the request. What happens ?
The operation stops, because the socket throws this error when the connection closed ? If it's not stopped, what happens to the data flushed in the outputstream after that ?
Thanks
I can't tell what Tomcat is doing but here is what happens:
the client closed the socket gracefully (then the server is notified about the close and closes its side of the connection too, in which case any buffered data ready to be sent is lost);
the client cut the socket brutally (then the server is NOT notified and it will detect the connection loss after a timeout or at the first attempt to send data - this will fail).
So, if your streaming is "constant", the server will always be 'protected' against undetected lost connections (the first send attempt will clean-up the area).
If this streaming is not constant, then you should make room for a timeout, or use TCP Keep-Alives to make sure that the connection state is tested on a regulary basis.
Hope it helps.