RobotStudio event

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

 

 

Comments

  • Moved to RobotWare forum.
    Henrik Berlin
    ABB
  • 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
    jeroen2012-01-26 15:22:43
  • 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.

    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!?