Arm Mbed and Pelion Device Management support forum

TCP server sample code

Hi, Im new to MBED
I tried this sample code and it crashes after first attempt. any idea ?

All help are welcome

Thanks
Dan

#include "mbed.h"
#include "EthernetInterface.h"

static const char*          mbedIP       = "192.168.10.50";  //IP 
static const char*          mbedMask     = "255.255.255.0";  // Mask
static const char*          mbedGateway  = "192.168.10.254";    //Gateway

int main()
{
    printf("TCP server example\n");
    
    EthernetInterface eth;
    eth.set_network(mbedIP,mbedMask,mbedGateway);
    eth.connect();
    
    printf("The Server IP address is '%s'\n", eth.get_ip_address());
    
    //TCPServer srv;  //TCPServer was migrate to TCPSocket
    TCPSocket srv;
    TCPSocket *client_sock;  // srv.accept() will return pointer to socket
    SocketAddress client_addr;
    char *buffer = new char[1000];
    
    /* Open the server on ethernet stack */
    srv.open(&eth);
    
    /* Bind the HTTP port (TCP 80) to the server */
    srv.bind(eth.get_ip_address(), 80);
    
    /* Can handle x simultaneous connections */
    srv.listen(1);
 while (true) {
    client_sock = srv.accept();  //return pointer of a client socket
    client_sock->getpeername(&client_addr);  //this will fill address of client to the SocketAddress object
    printf("Accepted %s:%d\n", client_addr.get_ip_address(), client_addr.get_port());
   strcpy(buffer, "Hello \n\r");
    client_sock->send(buffer, strlen(buffer));
    client_sock->recv(buffer, 1000);
    printf("Received Msg: %s\n", buffer);  //this was missing in original example. 
    delete[] buffer;
    client_sock->close();
    
    }
}

Hi Dan,

For publishing a piece of code use correct formatting.

   ```
     // your code
   ```

The example what you posted is little bit obsolete, but the reason why it crash, is bad manipulation with a memory. When you take out the line delete[] buffer; the code will working again and again.

You can try TCP_EchoServer

BR, Jan

You could try this, it’s the up to date version, well was yesterday with no warnings. However the ESP8266 is crashing on the server part and I’m not sure why, there’s an issue with Mbed’s ESP8266 driver.

But no worries if you use Ethernet.

https://os.mbed.com/users/star297/code/TCP-NTP-Server/

Thanks Johnny,
Yes it was , I didn’t assign enough space to an array.

Thanks paul,
Your code is really useful for me.

By there way, the TCP receive segment is limited to 536bytes. So I have to receive again if receive packet is bigger than 536 bytes.I tried following, didnt work. wheres this magical number 536 coming from.

BR, Dan

"lwip.pbuf-pool-bufsize": 1460

Hi Dan,

I don’t know the answer, might be an idea to ask a separate question.
I’ve been using snips of code from here:

https://os.mbed.com/teams/sandbox/code/mbed-http/

to use for HTTPS function in a Google Firebase project. There may be some more useful info there.
It’s out of date but my library that is a cut down of this and has no warnings is here:

https://os.mbed.com/users/star297/code/Firebase-https/

I do not have experiences with that but this looks more like a TCP MMS (Message segment size) which is set to 536 in default. A macro with that default value is in the mbed_config.h, probably ganerated from mbed_lib.json.

    printf("Pool %d \n",MBED_CONF_LWIP_PBUF_POOL_SIZE);
    printf("MSS %d \n",MBED_CONF_LWIP_TCP_MSS);

It looks like can be override in the mbed_app.json.

{   "target_overrides": {
        "*": {
            "lwip.tcp-mss": 740
        }
    }
}

Similar old question

BR, Jan

Hi Johnny,
Thanks for your help, I’ll try your method.
At the moment I’m kind of away with following steps. It works fine ,but I’m not sure its good way of coding.

(by the way I’m a newbie to coding :wink:. literally started few weeks ago).
Thanks
BR
Dan

recv_cnt1 = client_sock->recv(recv_buf1, 768);    

           if(recv_cnt1==536)

        {
          recv_cnt2 = client_sock->recv(recv_buf2, 768);    
        }  

        /************join recv buffers***********/

        strcat(web_recv_buf, recv_buf1);

        strcat(web_recv_buf, recv_buf2);

Maybe keep reading until recv returns 0? This way, you only need one buffer.

int offset = 0;
while (true) {
    nsapi_size_or_error_t size = client_sock->recv(buf + offset, 768 - offset);
    if (size > 0) {
        offset += size;
    }

    if (size == 0) {
        offset = 0;
        // do whatever you need to do
    } 
}
2 Likes

Hi @dhanukak
I’m not sure what your current status is.
But, as mentioned by @lonesometraveler, you could use same buffer, and just read into the buffer with the offet of what was already read ( don’t forget to check overflow)

As for your original crash, it wasn’t because you haven’t assigned enough memory.
It was because you allocated the buffer array outside the loop, and then deleted this buffer at the end of the loop, which causes an access violation after the first iteration.
You should delete this buffer, outside the while loop, after it finishes, to avoid memory leak.
Regards,
Mbed Support
Ron

1 Like

Hi @lonesometraveler,
Thanks for your code.
when the receive buffer has more than 536 “nsapi_size_or_error_t size” gives the value 536. So I had to modify your code as follows. Any way I’m saving the memory of Buf1 & Buf2 just using 1 receive buffer

char  *recv_buf=new char[1024];
    nsapi_size_or_error_t size = client_sock->recv(recv_buf, 1024);
    if (size==536) {
    nsapi_size_or_error_t size = client_sock->recv(recv_buf + 536, 1024);
              }
//do my stuff from here

Cheers
Dan