TCP/IP disconnect not handled correctly

Hi,

I have a TCP/IP connection between my robot to a control program running on a PC. The code below runs in a separate semi-static task.
If I physically disconnect the robot (plug out cable), after a while this task crashes on the SocketSend function call shown below.
The socket_status keeps reporting SOCKET_CONNECTED however.
How can I fix/work around this?

Regards,

! --------------------------------------------------------------------------------
! Send status to client.
! --------------------------------------------------------------------------------
TRAP TrapStatus
VAR socketStatus sockStat;
sockStat:=SocketGetStatus(client_socket);
IF sockStat=SOCKET_CONNECTED THEN
! Send status to client.
SocketSend client_socketStr:=Status+ByteToStr(13Char)+ByteToStr(10Char);
ELSE
! Connection lost?
! …
ENDIF
! Acknowledge.
SetDO doStatus,0;
RETURN;
ERROR
!TryNext;
! Acknowledge.
SetDO doStatus,0;
RETURN;
ENDTRAP

Moved to RobotWare forum.

I’ve been working through this myself, and I think I can help. SOCKET_CONNECTED will be true unless the client or server explicitly closes the connection. However, if the cable is unplugged, you should be getting a Timeout Error. You can handle error with the following error catcher:

ERROR
IF ERRNO=ERR_SOCK_TIMEOUT THEN

Just be careful not to spend too much time in your TRAP, as I believe code ignores any other interrupts while inside a TRAP.

Hallo jeroen.
In your topic I see you are writing TCP communication. I want to make TCP server on the server side. Do you know if is posible to start new thread with socket (returned by SocketAccept fnc) ? Your code looks working like this.
thanks for help.

What exactly do you mean by a new thread?

I don’t think you can make a server with a thread for each connection; you just have to handle all connections in the same task.

In my application I just need to handle a single connection.

I have a ServerStart procedure:

PROC ServerStart(bool Recover)

IF Recover THEN
Log “ServerStart with recovery need”;

SocketClose server_socket;

SocketClose client_socket;

ELSE

Log “ServerStart without the need for recovery”;

ENDIF

SocketCreate server_socket;

SocketBind server_socket, IPAddress, IPPort;

SocketListen server_socket;

Log “Wait for connection”;

SocketAccept server_socket, client_socketClientAddress:=client_ipTime:=WAIT_MAX;

Log "Connection with " + client_ip;

ERROR

IF ERRNO=ERR_SOCK_TIMEOUT THEN

Log “ERR_SOCK_TIMEOUT”;

Retry;

ELSEIF ERRNO=ERR_SOCK_CLOSED THEN

Log “ERR_SOCK_CLOSED”;

Return;

ELSE

Log “Unknown error”

ENDIF

ENDPROC

And in the main loop I handle the server like:

ServerStart(FALSE);
– Some more initialization

WHILE TRUE DO

SocketReceive client_socket Str:=ReceiveTime:=nHeartbeatTimeout;

Log Receive;

! Process data

ENDWHILE

ERROR

IF ERRNO=ERR_SOCK_TIMEOUT THEN

Log “Timeout”;

! Close connection and restart.

ServerStart(TRUE);

Retry;

ELSEIF ERRNO=ERR_SOCK_CLOSED THEN

Log “Socket closed by peer!”;

ServerStart(TRUE);

Retry;

ELSE

Log “Unknown error”;

ENDIF

ENDPROC

Hi there!

I’m quiet new to RAPID, but I spent some time on developing
a TCP-based communication from client-PC to server-IRC5.

just a thought:
If you have the option “Multitasking” installed, you can use some additional tasks for separate server sockets that listen continously for incoming data.

@jeroen:
You can try to use

ResetRetrycount;

in your error handling rigth after

ServerStart(TRUE);

The standard number of retry counts is 4 (configurable somewhere …), so after four times of handling the same error, the

Retry;

will not be executed and the loop/proc will come to end/be finished.

hope this might help!?