La respuesta es implementation specific. Deberá verificar los archivos de encabezado de implementación tcp en su sistema operativo. Aquí hay un cliente de muestra para Linux que devuelve el estado del socket.
ts = TCPSocket.new('localhost', 5777)
ssl = OpenSSL::SSL::SSLSocket.new(ts, OpenSSL::SSL::SSLContext.new)
ssl.sync = true
ssl.connect
# TCP_INFO is 11
# note that TCP_INFO isn't defined in the ruby source.
# i had to look up the integer value in /usr/include/netinet/tcp.h
optval = ts.getsockopt(Socket::SOL_TCP, 11)
state = optval.unpack "i"
puts "state: #{state}"
Aquí está la estructura tcp_info para mi hasta a la fecha de linux ubuntu
struct tcp_info
{
u_int8_t tcpi_state;
u_int8_t tcpi_ca_state;
u_int8_t tcpi_retransmits;
u_int8_t tcpi_probes;
u_int8_t tcpi_backoff;
u_int8_t tcpi_options;
u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
u_int32_t tcpi_rto;
u_int32_t tcpi_ato;
u_int32_t tcpi_snd_mss;
u_int32_t tcpi_rcv_mss;
u_int32_t tcpi_unacked;
u_int32_t tcpi_sacked;
u_int32_t tcpi_lost;
u_int32_t tcpi_retrans;
u_int32_t tcpi_fackets;
/* Times. */
u_int32_t tcpi_last_data_sent;
u_int32_t tcpi_last_ack_sent; /* Not remembered, sorry. */
u_int32_t tcpi_last_data_recv;
u_int32_t tcpi_last_ack_recv;
/* Metrics. */
u_int32_t tcpi_pmtu;
u_int32_t tcpi_rcv_ssthresh;
u_int32_t tcpi_rtt;
u_int32_t tcpi_rttvar;
u_int32_t tcpi_snd_ssthresh;
u_int32_t tcpi_snd_cwnd;
u_int32_t tcpi_advmss;
u_int32_t tcpi_reordering;
u_int32_t tcpi_rcv_rtt;
u_int32_t tcpi_rcv_space;
u_int32_t tcpi_total_retrans;
};
Es posible observar que mi script sólo devuelve un entero. Aquí está la C enumeración que detalla los estados TCP y sus valores enteros. De nuevo, esto se encontró en /usr/include/netinet/tcp.h
enum
{
TCP_ESTABLISHED = 1,
TCP_SYN_SENT,
TCP_SYN_RECV,
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN,
TCP_CLOSING /* now a valid state */
};
Además, este thread dice que se puede detectar mediante la lectura de CLOSE_WAIT EOF. Pero dado que le preocupa si se han enviado datos, es probable que deba desempaquetar hasta tcpi_last_data_sent.
Finalmente, una advertencia. Asumí el desafío de responder a tu pregunta porque sonaba divertido y lo era, pero mis piernas C todavía están tambaleantes así que YMMV. :)