Keil Logo

Technical Support

On-Line Manuals

RL-ARM User's Guide (MDK v4)

RL-RTX RL-FlashFS RL-TCPnet TCP Socket Opening TCP Connection TCP Active Open TCP Passive Open Sending TCP Data Example for Sending Data Multiple TCP Connections UDP Socket Opening UDP Connection Sending UDP Data When DHCP Enabled When ARP Cache Empty Example for Sending Data IP Multicasting Multiple UDP Connections Configuring RL-TCPnet Static Configuration System Definitions Ethernet Network Interface PPP Network Interface SLIP Network Interface UDP Socket TCP Socket BSD Socket HTTP Server Telnet Server TFTP Server TFTP Client FTP Server FTP Client DNS Client SMTP Client SNMP Agent SNTP Client Error Function Runtime Configuration Library Files Using RL-TCPnet Stand Alone With RTX Kernel Event Driven Operation IP Address Assignment Ethernet Interface PPP Interface SLIP Interface Localhost Applications HTTP Server Script Language CGI Functions Ajax Support Using XML XML Example How it works SOAP Support SOAP Interface Large POST Messages Web Pages Default Page Error Pages Web on SD Card Web Update File System Interface Http Caching How it works Internal Web External Web Multi-user Authentication Using RAM File System FCARM File Converter PRINT Directive NOPRINT Directive PAGEWIDTH Directive PAGELENGTH Directive ROOT Directive Telnet Server Command Line Interface Multi-user Authentication Sending Reply Message Short Reply Long Reply Continuous Screen Update TFTP Server File System Interface TFTP Client File System Interface FTP Server File System Interface Multi-user Authentication Supported Commands FTP Client File System Interface SMTP Client SNMP Agent MIB Database MIB Interface MIB Entry MIB Table DNS Resolver Starting DNS Device Drivers Ethernet Driver Interrupt Mode Modem Driver Serial Driver Using Serial Link Cable Connection Modem Connection Windows Dial-up Add Direct Serial Link New Dial-up Connection Configure PPP Dial-up Configure SLIP Dial-up Debugging Enabling Debug Debug Level Redirecting Output Function Overview BSD Routines CGI Routines Ethernet Routines FTP Routines HTTP Routines IGMP Routines Miscellaneous Routines Modem Routines PPP Routines Serial Routines SLIP Routines SMTP Routines SNMP Routines System Functions TCP Routines Telnet Routines TFTP Routines UDP Routines RL-CAN RL-USB Example Programs Library Reference Appendix

Multiple TCP Connections

It is often required for the server applications to be able to accept several TCP connections from clients on the same port. Such applications are for example: Web server, FTP server, Telnet server etc. The multiplex handling must be implemented in the session layer of the user application.

Because TCP socket is a connection-oriented service, it accepts only one concurrent connection. The basic packet multiplexing is done in TCP Transport layer and the user application receives the socket number as a parameter in the callback function.

The framework of the user application shall contain the following basic functions:

  1. The user_init() function to initialize all user application sessions at startup.
    void user_init () {
      USER_INFO *user_s;
      int i;
    
      for (i = 0; i < user_num_sess; i++) {
        user_s = &user_session[i];
        user_s->Count = 0;
        user_s->Flags = 0;
        user_s->BCnt  = 0;
        user_s->Tout  = 0;
        user_s->File  = NULL;
        user_s->Script= NULL;
        /* Allocate a TCP socket for the session. */
        user_s->Socket = tcp_get_socket (TCP_TYPE_SERVER, TCP_TOS_NORMAL,
                         120, user_listener);
        user_s->State = USER_STATE_ERROR;
        if (user_s->Socket != 0) {
          if (tcp_listen (user_s->Socket, USER_SERVER_PORT) == __TRUE) {
            user_s->State = USER_STATE_IDLE;
          }
        }
      }
    }
    
    All user sessions are now initialized and each session has allocated it's own TCP socket. A socket is listening on selected USER_SERVER_PORT port.
  2. The user_listener() callback function for TCP socket. This callback function is common for all TCP sockets allocated in this user application.
    static U16 user_listener (U8 socket, U8 event, U8 *ptr, U16 par) {
      USER_INFO *user_s;
      U8 session;
      int i;
    
      session = user_map_session (socket);
      if (session == 0)) {
        return (__FALSE);
      }
      user_s = &user_session[session-1];
      switch (event) {
        case TCP_EVT_CONREQ:
          if (user_s->State == USER_STATE_IDLE) {
            user_s->State = USER_STATE_RESERVED;
          }
          return (__TRUE);
    
        case TCP_EVT_ABORT:
          user_kill_session (user_s);
          return (__TRUE);
    
        case TCP_EVT_CONNECT:
          user_s->State = USER_STATE_ACTIVE;
          return (__TRUE);
    
        case TCP_EVT_CLOSE:
          user_kill_session (user_s);
          return (__TRUE);
    
        case TCP_EVT_ACK:
          user_s->Count += user_s->BCnt;
          user_s->BCnt = 0;
          return (__TRUE);
    
        case TCP_EVT_DATA:
           ..
          return (__TRUE);
      }
      return (__FALSE);
    }
    
  3. The user_map_session() function to map the socket, which has generated a callback event, to it's owner session.
    static U8 user_map_session (U8 socket) {
      int i;
    
      for (i = 1; i <= user_num_sess; i++) {
        if (user_session[i-1].Socket == socket) {
          return (i);
        }
      }
      return (0);
    }
    
  4. The user_kill_session() function to initialize the session to a default state, close any eventually opened files and release any eventually allocated buffers.
    static void user_kill_session (USER_INFO *user_s) {
    
      user_s->State =  USER_STATE_IDLE;
      if (user_s->Flags & USER_FLAG_FOPENED) {
        user_fclose (user_s->File);
        user_s->File = NULL;
      }
      if (user_s->Script != NULL) {
        free_mem (user_s->Script);
        user_s->Script = NULL;
      }
      user_s->Flags = 0;
      user_s->Count = 0;
      user_s->BCnt  = 0;
      user_s->Tout  = 0;
    }
    
  5. The user_run_server() function to maintain the application jobs, timeouts, etc. This function shall be frequently called from the main loop.
    void user_run_server () {
      USER_INFO *user_s;
      int i;
    
      for (i = 0; i < user_num_sess; i++) {
        user_s = &user_session[i];
    
        switch (user_s->State) {
          case USER_STATE_IDLE:
          case USER_STATE_RESERVED:
            /* Keep TCP sockets listening. */
            if (tcp_get_state (user_s->Socket) < TCP_STATE_LISTEN) {
              tcp_listen (user_s->Socket, USER_SERVER_PORT);
            }
            break;
          case USER_STATE_WAITING:
            if (sec_tick == __TRUE) {
              if (--user_s->Tout == 0) {
                /* A timeout expired. */
                user_kill_session (user_s);
              }
            }
            break;
          case USER_STATE_ACTIVE:
             ..
            break;
        }
      }
    }
    

Note

  • There is one TCP socket used per user session. You need to reserve enough TCP sockets in Net_Config.c configuration file for all user sessions.
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.