Can´t maintain two sockets connected at time

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Can´t maintain two sockets connected at time

Jump to solution
2,702 Views
edgarsevilla
Contributor II

I have implemented a server that handles two sockets

A client can connect to any of these sockets (X or Y) and start sharing information in appropriately way.

But when a client attempts to connect to both sockets of the server, the server fails. No matter the order of the connection request to the sockets, the first connection request always works and the second fails (accept function). Now when I get the error, it is 0 (zero).

I have noticed that if the client connects to a socket, then sends the necessary data and then closes the socket before starting a new connection, then there are no faults. But obviously I do not want to be opening and closing connections to the server.

Anyone know how to solve this problem?

Server:

    Kinetis k60 (Tower Kit):

    MQX 3.7

    Codewarrior 10.1

Client:

    PC (Linux)


Socket_Y = socket(...);

...

stServerAddr.sin_port = Port_X;

...

bind(Socket_X, ...);

listen(Socket_X, ...);

...

stServerAddr.sin_port = Port_Y;

...

bind(Socket_Y, ...);

listen(Socket_Y, ...);

....

while(1)

{

    SocketTemp = RTCS_selectall(10);

    if(SocketTemp )

    {

        if(SocketTemp == Socket_X)

        {

            ClientSocket1 = accept(Socket_X,...)

            if(ClientSocket1 = -1)

            {

                RTCS_geterror(Socket_X)

            }

        }

        else if(SocketTemp == Socket_Y)

        {

            ClientSocket2 = accept(Socket_Y,...)

            if(ClientSocket2 = -1)

            {

                RTCS_geterror(Socket_Y)

            }

        }

        else if(SocketTemp == ClientSocket1)

        {

            error = recv(...)

            if(error = -1)

            {

                shutdown(ClientSocket1,...)

            }

            else

            {

                send(...)

            }

        }

        else if(u32SocketTemp == ClientSocket2)

        {

            error = recv(...)

            if(error = -1)

            {

                shutdown(ClientSocket2,...)

            }

            else

            {

                send(...)

            }

        }

        else

        {

            /* Not recognized */

        }

    }

    else

    {

        /* TimeOut -- Nothing to do */

    }

}

Regards,

Edgar Sevilla


Labels (1)
Tags (4)
0 Kudos
1 Solution
1,724 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi Edgar,

Are you adding enough sockets for your application? The web_hvac demo application is a good example of how to implement this.

Take a look to the file:

C:\Program Files\Freescale\Freescale MQX 3.8\demo\web_hvac\RTCS.c

It adds the next lines:

    _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;

These lines will ensure you to have at least 4 sockets available in the system. Remember that your server will already take one, so you will have 3 remain sockets with this configuration settings. Also remember to close those sockets that already finished the client connection in the server side (your board)

I hope this helps you.

Garabo

View solution in original post

0 Kudos
14 Replies
1,724 Views
tongjianwu
Contributor III

Hello everyone,

     I run into the same problem.

     I have another question,when the K60 serves as server,how many clients can be connected ?

     Thanks all of you !

     Have a nice day.

Best Regards.

0 Kudos
1,724 Views
tongjianwu
Contributor III

Garabo

hi,Garabo!

     Need help!

     My platform info:

  

               MCU:                 MK60DN512VLQ10

               MQX Version:     4.1.1

               Server:                created by MK60DN512VLQ10

               Client:                 PC

    When I use the parameters below,I create one client on my PC then close and open it up to six times,after this I can't connect to the server again.

// runtime RTCS configuration for devices with small RAM, for others the default BSP setting is used
// original parameter
_RTCSPCB_init = 10;
_RTCSPCB_grow = 2;
_RTCSPCB_max = 20;
_RTCS_msgpool_init =10;
_RTCS_msgpool_grow = 2;
_RTCS_msgpool_max  = 20;
_RTCS_socket_part_init = 10;
_RTCS_socket_part_grow = 2;
_RTCS_socket_part_max  = 20;

the attachment is debug error.

Thanks!

Best Regards!

0 Kudos
1,724 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi Jianwu,

Are you making sure that the sockets opened in the server side are being closed and released after the closure of each client? If you don't do this you are starving from memory in the server. Then you are not able to create more sockets. Remember, the limit is the memory. If you don't have more memory to continue creating sockets then you will hang starving for memory.


Have a great day,
Garabo

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,724 Views
tongjianwu
Contributor III

Hi Garabo,

          Thanks for your reply!

          When the client close the connection, I use the following methods to close the client sockets:

0 Kudos
1,724 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Your replay is cut. I can't see anything.

Regards,

Garabo

0 Kudos
1,724 Views
tongjianwu
Contributor III

Hi, Garabo.


          Sorry for that!


         When the client close the connection, I use the following methods to close the client sockets:


Header 1

if (error == RTCSERR_TCP_CONN_CLOSING)

  {

  shutdown(new_socket_handle, FLAG_ABORT_CONNECTION);

  debug_log("\n[TCPServer]: TCPClient Closed (Socket = 0x%x).", new_socket_handle);

  _task_destroy(MQX_NULL_TASK_ID);

  break;

  // Close TCPServer if TCPClient abort.

  }

  else if (error == RTCSERR_TCP_CONN_RESET)

  {

  shutdown(new_socket_handle, FLAG_ABORT_CONNECTION);

  debug_log("\n[TCPServer]: Connection reset by peer.");

  debug_log("\n[TCPServer]: TCPClient Closed (Socket = 0x%x).", new_socket_handle);

  break;

  // Timeout occur if zero char received.

  }

  else if (error == RTCSERR_TCP_TIMED_OUT)

  {

  debug_log("\n[TCPServer]: recv Timeout.");

  if (send(new_socket_handle, "TCPServer recv Timeout.", strlen("TCPServer recv Timeout.") + 1, 0) == RTCS_ERROR)

  {

  debug_log("\n[TCPServer]: Failed to send, CODE = 0x%x.", RTCS_geterror(new_socket_handle));

  _task_block();

  }

  }

  else

  {

  debug_log("\n[TCPServer]: Failed to recv, CODE = 0x%x.", error);

  _task_block();

  }

     I create one task for each socket connected to the server  and the task stack size is 1000bytes,doubt that whether I can use this approach to process each socket.

     I don't know whether I can use the above method close the client sockets.

     Can you give me some advice for processing these?

     Thanks!

Best Regards.

0 Kudos
1,724 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

You are closing correctly in your side. Take a look to the Task Aware Debugging in the TCPIP->Sockets menu and see how many sockets you still in pending to be closed. It is wired that you are not releasing the resources.


Have a great day,
Garabo

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,724 Views
tongjianwu
Contributor III

hi,Garabo.

Thanks for your reply!

I create one task for each socket connected to the server  and the task stack size is 1000bytes,doubt that whether I can use this approach to process each socket.

When the client socket closes the connection,what should i do for the task?

Best regards.

0 Kudos
1,724 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi Juanwu,

Make sure that each task is killed after the socket is shutdown. If they stay in blocked state then you are not releasing that memory and you will get out of it very soon. use _task_abort() instead of _task_block().


Have a great day,
Garabo

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,724 Views
tongjianwu
Contributor III

Hi,Garabo

          Thanks for your quick reply!

           May I use the _task_destroy() function to terminate the socket task?

       

           For example:

          if (error == RTCSERR_TCP_CONN_CLOSING)

           {

                      shutdown(new_socket_handle, FLAG_ABORT_CONNECTION);

                      debug_log("\n[TCPServer]: TCPClient Closed (Socket = 0x%x).", new_socket_handle);

                      _task_destroy(MQX_NULL_TASK_ID);

                      break;

                      // Close TCPServer if TCPClient abort.

          }

          When creating one socket for client, how many stack will be consumed?

          Finally I find the socket TX and RX buffer are the default value (4380 bytes),then rectify these value to (1024 byets). Using the following RTCS parameter,10 client sockets can connect to my server.

_RTCSPCB_init = 10;
_RTCSPCB_grow = 2;
_RTCSPCB_max = 20;
_RTCS_msgpool_init = 10;
_RTCS_msgpool_grow = 2;
_RTCS_msgpool_max  = 20;
_RTCS_socket_part_init = 10;
_RTCS_socket_part_grow = 2;
_RTCS_socket_part_max  = 20;

          if I change the tx and rx buffer size whether any negtive effects can happen?

          Another question,when receiving the data from the client socket,I use one lwsem to notify the command parse function to process the data.

          Then connect some sockets to the TCP server and after this, connect one another socket,at this time I can't use the lwsem to notify the command parse   function,but when I use lwevent ,this situation doesn't happen. I don't know what happen,can you give me some advice?

Thanks.

Have a nice day!

Best Regards!

Jianwu

0 Kudos
1,724 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi Jianwu,

Yes, you need to destroy the task since it won't be used any more for the closed socket.

The only stack consumed is the used by the task created to handle that connection.

With the TaskAwareDebugging, you can see that every new TCP socket connection needs extra 500+4392x2+148=9432B/59.0KB=16% as follows:

MQX -> Lightweight Memory Block Summary Size (Decimal) Owner    Type

500      0x10001  TCP Control Block;RTCS/TCP

4392   0x10001  TCP Tx Window;RTCS/TCP

4392   0x10001  TCP Rx Window;RTCS/TCP

148     0x10001  TCP Send Clock;RTCS/TCP

(TCP/IP Task id is 0x10001)

The default OPT_TBSIZE and OPT_RBSIZE are 4380 bytes. If you call setsockopt() to reduce these two, for example, to a quarter like 1095 bytes, the memory usage to open a new TCP socket will drop from 16% to 4.7% as follows:

MQX -> Lightweight Memory Block Summary Size (Decimal) Owner    Type

500  ->  500   0x10001  TCP Control Block;RTCS/TCP

4392 -> 1108   0x10001  TCP Tx Window;RTCS/TCP

4392 -> 1108   0x10001  TCP Rx Window;RTCS/TCP

148  ->   84   0x10001  TCP Send Clock;RTCS/TCP

If the problems persists please set a slower number, try next:

uint_32 value;

value = 256;

setsockopt(sock, SOL_TCP,OPT_TBSIZE,&value,sizeof(value));

setsockopt(sock, SOL_TCP,OPT_RBSIZE,&value,sizeof(value));

Try this to see if you can get more resources.

I am sorry but I did not catch your last question.

Regardsm

Garabo.

0 Kudos
1,724 Views
c_dawg
Contributor III

Thanks for the solution!  It is important to note when creating a project using CW 10.2 with MQX 3.8 selecting “Add RTCS support” will create rtcs_init.c.  This file contains RTCS_create() called by rtcs_init() in main.c. So it is important to have:

    _RTCS_socket_part_init = 4;

    _RTCS_socket_part_grow = 2;

    _RTCS_socket_part_max  = 20;

before rtcs_init() in main.c.

0 Kudos
1,725 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi Edgar,

Are you adding enough sockets for your application? The web_hvac demo application is a good example of how to implement this.

Take a look to the file:

C:\Program Files\Freescale\Freescale MQX 3.8\demo\web_hvac\RTCS.c

It adds the next lines:

    _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;

These lines will ensure you to have at least 4 sockets available in the system. Remember that your server will already take one, so you will have 3 remain sockets with this configuration settings. Also remember to close those sockets that already finished the client connection in the server side (your board)

I hope this helps you.

Garabo

0 Kudos
1,724 Views
edgarsevilla
Contributor II

Thanks Garabo,

That solve the problem.

0 Kudos