Closing Connections

Top  Previous  Next

Passive TCP connection termination

When your socket is engaged in a TCP connection with another host on the network, this host may choose to terminate the connection. This can be done through a "graceful disconnect" sequence ("FIN-ACK-FIN-ACK") or through a reset ("RST" packet).

In both cases the socket will handle connection closing automatically, without any help from your Tibbo BASIC/C program or the VM. In fact, the socket will accept connection termination even when the VM is stopped (for example, it was paused on your breakpoint). All communications are handled by the master process, so the socket does not need the VM to terminate the connection.

There is one intricate detail in the connection termination process that you will have to understand clearly. When the VM is not running, the socket can accept an incoming connection (active open) and can accept an active close. However, the socket won't be able to accept another (next) incoming connection until the VM has had a chance to run and execute the on_sock_eventevent handler (see Checking Connection Status).

Here is why. In many cases there is a need to perform certain actions (like, maybe, clear some buffers, initialize variables, etc.) after the previous connection ends and before the new one begins. Not letting the socket accept next connection before your program has a chance to respond to connection termination is a way to achieve this!

Actively closing TCP connections

A TCP connection can be closed, reset (aborted), or discarded using three different methods- sock.close, sock.reset, and sock.discard.

The recommended (and polite!) way of closing a TCP connection is through the sock.close method. This will initiate a proper closing sequence ("FIN-ACK-FIN-ACK"), known as a "graceful disconnect".

Connection reset is slightly more "rude"- your socket will simply tell the other end that "it is all over" (by sending the "RST" packet).

Finally, the sock.discard method simply makes your socket forget about the connection- the other side is not notified at all.

Just like with connection establishment, you can monitor the progress of connection termination- see Checking Connection Status.

 

note_tip-wt

Notice, that depending on the socket state at the moment of sock.close method invocation, the socket may need to resort to a simple connection closing option- reset or discard. Similarly, when you use the sock.reset, it may sometimes result in discard. For more information read the sock.close, sock.reset, and sock.discard topics.

 

Actively closing UDP connections

For UDP, no matter what method you use to close the "connection", result will still be as if the sock.discard was invoked. This is because in reality there is no such thing as a proper UDP connection termination so simply "forgetting" about the connection is the only option the socket has.

Do not forget: connection handling is fully asynchronous!

Keep in mind that the sock object handles communications asynchronously. When the VM executes the sock.close (sock.reset, sock.discard) method it does not mean that the connection is done with by the time the VM gets to the next program statement. Executing these methods merely instructs the master process to terminate the connection. Connection termination can take some time and your application doesn't have to wait for that to complete. Checking Connection Status topic explains how to find out actual connection status at any time (see sock.state and sock.statesimple read-only properties).

 

note_warning-wt

Asynchronous nature of the sock object has some interesting implications. More On the Socket's Asynchronous Nature topic contains important information on the subject, so make sure you read it!

Socket re-use after connection closing

When the socket connection terminates, the socket is ready to accept another incoming connection or establish a new outgoing connection (if so configured) — with one little caveat! There is a special built-in mechanism that ensures that your application has a chance to react after the previous connection terminates and before the next one is established.

For example, you might need to clean some buffers before each new incoming TCP connection. Naturally, you want this to happen before the new connection is actually accepted.

Typically, your program achieves this by executing code placed in the on_sock_event event handler (this event is explained in Checking Connection Status topic). The socket will not be able to engage in the new connection until the on_sock_event has a chance to execute. There is an interesting example on this in the More On the Socket's Asynchronous Nature topic.

Connection timeouts

The sock.connectiontout provides a way to automatically terminate a connection across which no data was exchanged for a predefined period of time. For TCP, reset (abort) is used, while UDP "connections" are simply discarded. Connection timeout is a useful way to exit "hanged" connections (this happens a lot with TCP on large networks).

The sock.toutcounter R/O property informs your application of the time passed since the data was last exchanged across the connection. Each time there is some data sent or received the sock.toutcounter is reset to zero. The property increments at 0.5 second intervals while no data is moving through this socket.

If the sock.connectiontout is not at 0, the sock.toutcounter increments until it reaches the value of the sock.connectiontout and the connection is terminated. The sock.toutcounter then stays at the value of sock.connectiontout.

If the sock.connectiontout is at 0, the maximum value that the sock.toutcounter can reach is 1. That is, the sock.toutcounter will be at 0 after the data exchange, and at 1 if at least 0.5 seconds have passed since the last data exchange.

Normally, HTTP connections close automatically

There is one case where your socket will perform an active graceful disconnect without you using the sock.close method. This is the case when the socket is running in the TCP-HTTP mode.

In Accepting Incoming Connections we have already explained that the socket automatically switches into the HTTP mode if a TCP connection is accepted on one of the ports from the sock.httpportlist list. The socket can also be switched into the HTTP mode programmatically, through the sock.httpmode property.

Default HTTP functionality requires that the TCP connection is closed once the HTTP server has finished sending out its "response" (i.e. HTML page or another file that has been requested). In this situation the socket won't need the sock.close from your program- the connection will be terminated automatically. In fact, when the socket is in the HTTP mode, your sock.close, sock.reset, and sock.discard will simply be ignored. There is a sock.httpnoclose property alters the standard socket behavior in the HTTP mode. Set this property to 1- YES and the connection will be kept opened even after the socket has sent all of the HTTP reply out.

Just like in all other cases, a new connection on the socket won't be accepted until your program has had a chance to respond- this was explained above.