How do I detect if the remote endpoint is closed, or issued a shutdown request without actually reading or writing data to the socket (or using a KEEPALIVE which is only a polled test)? I.E. how do I determine the socket state?
'RTCS_selectset(s, 1, -1) == s' tells me if "Data or shutdown request is initiated by remote endpoint or all sent data are acknowledged", but how do I determine which one (shutdown or data ack)?
Thanks,
PMT
Solved! Go to Solution.
RTCS_selectset() cannot return you this information, as it has just one return value, which is socket handle. Latest RTCS already has BSD-like select() function and it can distinguish between data requests/ close or reset requests/ acknowledge received for send data. It is part of the Freescale MQX for Kinetis SDK, and also will be in next MQX classic.
In "older MQX" you need to use other RTCS functions. recv()/send() functions give you an error when remote endpoint is reset/connection closed, example:
retval = recv(sock,...);
if(retval < 0)
{
uint32_t error_code = RTCS_geterror(sock);
/* this might be for example RTCSERR_TCP_CONN_RLSD or RTCSERR_TCP_CONN_RESET */
....
RTCS_shutdown(sock, 0); /* complete graceful connection close. destroy socket. */
sock = RTCS_SOCKET_ERROR;
}
Personally I would use RTCS_selectset() only on listening sockets to block wait for connection requests. If you like non-portable customization, you can just read the state from the TCB of a valid TCP socket:
struct tcb_struct *tcb = ((struct socket_struct *)sock)->TCB_PTR;
if(NULL == tcb)
{
/* connection is released -> reset, abort */
}
else
{
uint16_t tcp_state = tcb->state;
/* it will be one of states defined in tcp_prv.h:
* TCB states */
#define LISTEN 0
#define SYN_SENT 1
#define SYN_RECEIVED 2
#define ESTABLISHED 3
#define FINWAIT_1 4
#define FINWAIT_2 5
#define CLOSE_WAIT 6
#define CLOSING 7
#define LAST_ACK 8
#define TIME_WAIT 9
#define CLOSED 10
#define BOUND 11
*/
}
Martin
RTCS_selectset() cannot return you this information, as it has just one return value, which is socket handle. Latest RTCS already has BSD-like select() function and it can distinguish between data requests/ close or reset requests/ acknowledge received for send data. It is part of the Freescale MQX for Kinetis SDK, and also will be in next MQX classic.
In "older MQX" you need to use other RTCS functions. recv()/send() functions give you an error when remote endpoint is reset/connection closed, example:
retval = recv(sock,...);
if(retval < 0)
{
uint32_t error_code = RTCS_geterror(sock);
/* this might be for example RTCSERR_TCP_CONN_RLSD or RTCSERR_TCP_CONN_RESET */
....
RTCS_shutdown(sock, 0); /* complete graceful connection close. destroy socket. */
sock = RTCS_SOCKET_ERROR;
}
Personally I would use RTCS_selectset() only on listening sockets to block wait for connection requests. If you like non-portable customization, you can just read the state from the TCB of a valid TCP socket:
struct tcb_struct *tcb = ((struct socket_struct *)sock)->TCB_PTR;
if(NULL == tcb)
{
/* connection is released -> reset, abort */
}
else
{
uint16_t tcp_state = tcb->state;
/* it will be one of states defined in tcp_prv.h:
* TCB states */
#define LISTEN 0
#define SYN_SENT 1
#define SYN_RECEIVED 2
#define ESTABLISHED 3
#define FINWAIT_1 4
#define FINWAIT_2 5
#define CLOSE_WAIT 6
#define CLOSING 7
#define LAST_ACK 8
#define TIME_WAIT 9
#define CLOSED 10
#define BOUND 11
*/
}
Martin
Martin,
Thanks! I'm glad to see the full BSD select functionality coming in the next release. For my reference, this is after MQX 4.1.1, correct?
Correct, after MQX 4.1.1.