AnsweredAssumed Answered

M52259 RTCS TCP/IP server allowing multiple client socket connections

Question asked by matthewteolis on Nov 11, 2014
Latest reply on Dec 8, 2014 by Garabo

Hi,

I would like to be able to have a Server running on the M52259EVB chip that will accept multiple TCP/IP socket connections, preferably on the same port (if possible). I have posted the code showing what I'm doing and I would like to know what's wrong with my code. Thank you.

 

My environment:

  • MQX 3.4
  • CodeWarrior 7.1
  • M52259EVB
  • Java, for client application connecting with sockets

 

Problems:

  1. I currently can't connect 2 clients on the M52259EVB server.
  2. I can only connect/disconnect 5 times. On the 6th time, WireShark shows TCP Retransmission and I can't connect to my board anymore unless I restart the board.

 

/*
** ****************
** Library includes
** ****************
*/
#include < mqx.h >
#include < bsp.h >
#include < rtcs.h >
#include < ipcfg.h >
#include < string.h >

/*
** ****************
** Project includes
** ****************
*/
#include "ProjectInclude.h"
#include "Initializations.h"

/*
** **************************
** Local functions prototypes
** **************************
*/
void InitRTCS()
{
    IPCFG_IP_ADDRESS_DATA ip_data;
    _enet_address mac_address;
    uint_32 error;

    // For multi socket connection (doesn't work)
    _RTCSPCB_init = 4;
    _RTCSPCB_grow = 2;
    _RTCSPCB_max = 20;
    _RTCS_msgpool_init = 4;
    _RTCS_msgpool_grow = 2;
    _RTCS_msgpool_max = 20;
    _RTCS_socket_part_init = 4;
    _RTCS_socket_part_grow = 2;
    _RTCS_socket_part_max = 20;

    error = RTCS_create();
    if (error != RTCS_OK)
    {
        printf("\n[TCPServer]: Failed to create RTCS");
        _task_block();
    }
    ip_data.ip = IPADDR(200, 200, 200, 200);
    ip_data.mask = IPADDR(255, 255, 255, 0);
    ip_data.gateway = IPADDR(0, 0, 0, 0);


    ENET_get_mac_address(BSP_DEFAULT_ENET_DEVICE, ip_data.ip, mac_address);


    ipcfg_init_device(BSP_DEFAULT_ENET_DEVICE, mac_address);
    error = ipcfg_bind_staticip(BSP_DEFAULT_ENET_DEVICE, & ip_data);
    if (error != RTCS_OK)
    {
        printf("\n[TCPServer]: Failed to bind static ip");
        _task_block();
    }
    else
    {
        _task_create(0, TCPS_MAIN_TASK, 0); // TCPServer()
    }
}

void TCPServer()
{
    uint_32 error;
    uint_32 sock, listensock;
    sockaddr_in addr, client;
    uint_16 client_len = sizeof(client);


    // Create a socket //
    listensock = socket(AF_INET, SOCK_STREAM, 0);
    if (listensock == RTCS_SOCKET_ERROR)
    {
        printf("\n[TCPServer]: Failed to create the stream socket.");
        _task_block();
    }

    addr.sin_family = AF_INET;
    addr.sin_port = 17;
    addr.sin_addr.s_addr = INADDR_ANY;

    // Bind the socket //
    error = bind(listensock, & addr, sizeof(addr));
    if (error == RTCS_ERROR)
    {
        printf("\n[TCPServer]: Failed to bind the stream socket - 0x%lx", error);
        _task_block();
    }

    // Start listening //
    error = listen(listensock, 0);
    if (error == RTCS_ERROR)
    {
        printf("\n[TCPServer]: listen() failed - 0x%lx", error);
        _task_block();
    }

    while (1)
    {
        // Accept the connection //
        sock = accept(listensock, & client, & client_len);
        if (sock != RTCS_SOCKET_ERROR)
        {
            // Create sub thread to service client's request //
            _task_create(0, TCPS_COMM_TASK, sock); // TCPCommunication()
        }
        else
        {
            error = RTCS_geterror(listensock);
            // ? When will accept return RTCS_SOCKET_ERROR & RTCS_OK ?
            if (error == RTCS_OK)
            {
                shutdown(listensock, FLAG_ABORT_CONNECTION);
                printf("\n[TCPServer]: Connection reset by peer.");
                printf("\n[TCPServer]: Closed.");
                break;
            }
            else
            {
                printf("\n[TCPServer]: Failed to accept, CODE = 0x%x", error);
                _task_block();
            }
        }
    }
}

void TCPCommunication(uint_32 temp)
{
    uint_32 error;
    uint_8 recv_buffer[54];
    uint_32 sock = temp;
    uint_32 opt_val;
    uint_32 opt_len;


    // set receive push to FALSE, recv will return only if buffer is full, and timeout if set.
    //opt_val = FALSE;
    opt_val = TRUE;
    opt_len = sizeof(uint_32);
    error = setsockopt(sock, SOL_TCP, OPT_RECEIVE_PUSH, & opt_val, opt_len);
    if (error != RTCS_OK)
    {
        printf("\n[TCPServer]: Failed to setsockopt for OPT_RECEIVE_PUSH, CODE = 0x%x.", error);
        _task_block();
    }


    // set receive timeout to 60s, recv will return received n bytes if timeout occur
    opt_val = 60 * 1000;
    error = setsockopt(sock, SOL_TCP, OPT_RECEIVE_TIMEOUT, & opt_val, opt_len);
    if (error != RTCS_OK)
    {
        printf("\n[TCPServer]: Failed to setsockopt for OPT_RECEIVE_TIMEOUT, CODE = 0x%x.", error);
        _task_block();
    }


    opt_val = 54;
    error = setsockopt(sock, SOL_TCP, OPT_RBSIZE, & opt_val, opt_len);
    if (error != RTCS_OK)
    {
        printf("\n[TCPServer]: Failed to setsockopt for OPT_RBSIZE, CODE = 0x%x.", error);
        _task_block();
    }


    // Clean the buffers to '\0' //
    memset(recv_buffer, 0, 54);


    while (TRUE)
    {
        if (recv(sock, recv_buffer, 54, 0) == RTCS_ERROR)
        {
            error = RTCS_geterror(sock);


            // Close TCPServer if TCPClient close first.
            if (error == RTCSERR_TCP_CONN_CLOSING)
            {
                shutdown(sock, FLAG_ABORT_CONNECTION);
                printf("\n[TCPServer]: TCPClient Closed (Socket = 0x%x).", sock);
                break;
            }
            // Close TCPServer if TCPClient abort.
            else if (error == RTCSERR_TCP_CONN_RESET)
            {
                shutdown(sock, FLAG_ABORT_CONNECTION);
                printf("\n[TCPServer]: Connection reset by peer.");
                printf("\n[TCPServer]: TCPClient Closed (Socket = 0x%x).", sock);
                break;
            }
            // Timeout occur if zero char received.
            else if (error == RTCSERR_TCP_TIMED_OUT)
            {
                printf("\n[TCPServer]: recv Timeout.");
                if (send(sock, "TCPServer recv Timeout.", strlen("TCPServer recv Timeout.") + 1, 0) == RTCS_ERROR)
                {
                    printf("\n[TCPServer]: Failed to send, CODE = 0x%x.", RTCS_geterror(sock));
                    _task_block();
                }
            }
            else
            {
                printf("\n[TCPServer]: Failed to recv, CODE = 0x%x.", error);
                _task_block();
            }
        }
        else
        {
            if (send(sock, recv_buffer, sizeof(recv_buffer), 0) == RTCS_ERROR)
            {
                printf("\n[TCPServer]: Failed to send, CODE = 0x%x.", RTCS_geterror(sock));
                _task_block();
            }

            // clean buffer to ensure '\0' filled for next recv.
            memset(recv_buffer, 0, 54);
        }
    }
}





Outcomes