cancel
Showing results for 
Search instead for 
Did you mean: 

setting a backlog, response issue with TCP Raw Socket Server

VSomasekhar
Associate II
  1. How to set the number of simultaneous connections (backlog) in the Raw Socket Listen API? This is the relevant code snippet: /* start tcp listening for echo_pcb */ tcp_echoserver_pcb = tcp_listen( tcp_echoserver_pcb ); In contrast, the BSD/LWIP Sockets Listen API is: int lwip_listen(int s, int backlog)
  2. Do I have to enable this macro in opt.h for the above purpose? #define TCP_LISTEN_BACKLOG
  3. I am running a modified TCP Echo Server on the Board and sending continuous sequence of Modbus requests from the Modscan32 tool to the Modbus server running on the Board with STM32H723Zet6 MCU. But the response is given only to the first Request. The TCP Server is based on the source in the webpage: https://community.st.com/t5/stm32-mcus-embedded-software/how-to-send-data-lwip-tcp-server-to-client/td-p/119556
  4. How to modify the TCP Raw Socket Server mentioned above to send the response for all the request packets? As mentioned, the TCP Raw Socket Server is responding only once, that too after restart.
21 REPLIES 21
STea
ST Employee

Hello @VSomasekhar ,

I think that the server stops responding because you are running out of memory as you allocate a packet each time you try to send a response and then this packet should be free afterwards.
you need also to set the pointer back to NULL after sending the response to make sure you are not holding the received buffer value in your send buffer.

ideally you should implement proper buffer management for this to work properly and ensure that you have sufficient space in the pool for handling data in LWIP.
Regards

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi,

Thanks for the suggestion. I've created a packet buffer in ModbusIxFace(struct pbuf *p), using pbuf_alloc(). I've freed it in tcp_echoserver_recv(..), using pbuf_free(), where:

es->state == ES_CLOSING

But now the server is responding 4-5 times only and then stopping responses. The file is attached. Please check and suggest. I've tried the same at other locations also, where pbuf_free(p) was called and where: es->state = ES_CLOSING_SERVER;

In the program, I've created only one packet buffer, and tried to free it. But it doesn't seem to improve - hardly 4-5 responses. 

VSomasekhar
Associate II

Thanks again for your help. Today I came to know that our customer is going to order 3000-5000 boards very soon. We need to complete this project asap to keep this business. I am ready to provide any more data required, which doesn't violate my employer's IP. I have attached the Modbus request and response traces in that attachment. Please check and suggest any possible way to correct the server. 

As suggested by you, I have included the pbuf_free() function, as given in the tcp raw server file. But if that place is not suitable, please suggest a different place.

If not please suggest any other solution, including an appropriate server program, with LWIP or Raw socket server. 

1. Please confirm if this attempt to use the Echo Server works out or not. Initially I thought it should work. I couldn't find any other suitable server program. If available, please let me know.

2. This server is definitely sending continuous responses in the echo server mode, although I didn't find any "infinite loops" in the server program. Please help me understand how this can happen.

3. If there is any other server program available for this purpose, please help me with it. 

4. My employer's survival is dependent on this business. I request you to please help.

4. Thanks a lot for all the help. 

Hello @VSomasekhar ,

I'll take a look at this and come back to you as soon as possible.
Regards

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I thought it would be useful to attach the main.c file also for more clarity on this issue. Please find the application entry point and the relevant code flow in the attached main file. The tcpRawServer() function called in the main function is defined as: 

int tcpRawServer()

{

int Ret = 0;

//lwip socket based tcp echo server entry point

tcp_echoserver_init(portnum);

return Ret;

}

tcp_echoserver_init(..) is already known to you.

Just for your reference, this echo server is available at:

https://www.st.com/en/embedded-software/stsw-stm32070.html

 

STea
ST Employee

Hello @VSomasekhar ,

can you try to set a new project based on the example found in STM32CubeH7/Projects/NUCLEO-H723ZG/Applications/LwIP/LwIP_TCP_Echo_Server/Src/main.c at master · STMicroelectronics/STM32CubeH7 (github.com) because the main you are using is quite an old example in which we use old drivers.
Maybe try modifying the project From GitHub and tell me what you get afterwords.

you can take the memory management and dynamic allocation and chaining of pbufs on this example changing the echo part with you function construction messages to the es structure.

try calling you function for constructing Modbus packet before any call to tcp_echoserver_send() :

-in tcp_echoserver_recv(Handles incoming data, manages connection state, and sends data back to the client)

-in tcp_echoserver_poll(Periodically checks and handles pending operations, such as sending remaining data or closing the connection)

-in tcp_echoserver_sent(Handles the acknowledgment of sent data, sends any remaining data, and closes the connection if necessary)

Regards

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I have downloaded the required files and will create a new project in the STM32CubeIDE now. I'll include the raw socket server files, do the changes in the tcp_echoserver_recv(..) function, add the requires Modbus functionality and test it. 

I need one clarification please. When the es structure is created, it is put into ES_ACCEPTED state in the

tcp_echoserver_accept(..) function. It is moved to ES_RECEIVE state in the tcp_echoserver_recv(..) function. If the received packet buffer is NULL, it is moved to ES_CLOSING state in the same function. 
 
The server is expected to run indefinitely, in a loop. From the above description, tcp_echoserver_recv(..) is supposed to be in a loop. From the echo server functionality, which runs indefinitely as observed, clearly, there is a loop. But where is the loop in the source code? I couldn't find it, please help. In other words, how does the function tcp_echoserver_recv(..) run in a loop?
 
In the standard BSD sockets or LWIP sockets programs, recv() and send() functions will be in an infinite loop. But in the case of raw sockets, tcp_echoserver_recv(..) has to run forever. What is it that makes it run forever?

Hello @VSomasekhar ,

The loop is periodically called in the main file  

while (1)
  {
    /* Read a received packet from the Ethernet buffers and send it
       to the lwIP for handling */
    ethernetif_input(&gnetif);

    /* Handle timeouts */
    sys_check_timeouts();

#if LWIP_NETIF_LINK_CALLBACK
    Ethernet_Link_Periodic_Handle(&gnetif);
#endif

#if LWIP_DHCP
    DHCP_Periodic_Handle(&gnetif);
#endif
  }

The received messages will be then passed to the LWIP to handle it by trigging thee receive callbacks in Lwip when receiving a packet.
Regards

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I think there was some misunderstanding. Let me make it clearer. I am calling "tcpRawServer()" from the main, above the while loop, which calls tcp_echoserver_init(..) function. All the TCP Raw socket functions mentioned in the earlier message are branched out from tcp_echoserver_init(..) function. There is a state-machine, most of it in the tcp_echoserver_recv(..) function. But how does the function tcp_echoserver_recv(..) runs after tcp_server_connection_close(..), without a loop? 

I have created a new project and included the TCP Raw Socket Server files from the specified path (STM32CubeH7/Projects/NUCLEO-H723ZG/Applications/LwIP/LwIP_TCP_Echo_Server/Src/main.c at master · STMicroelectronics/STM32CubeH7). Since I have created the project using .ioc file from the STM32CubeIDE, I have not replaced the main.c file. But I have replaced the TCP Raw Socket Server files. The behavior is exactly the same as before. It shows 8 or 9 modbus responses and then the ping response is lost. Shall I change the main file also, as given in the specified path?