10 years, 7 months ago.

Can't get more than 3 active TCP connections

Hello,

I'm working on a project using a mbed LPC1768 as a TCP server connecting to multiple TCP clients. I wrote a simple code for handling multiple TCP clients (some of it is based on examples in Socket handbook), but there is an issue with the code. The issue is I can't get the server to connect more than three active connections. The 4th or more clients could not connect for unknown reasons. I looked around the forums and tried increasing the number limit for MEMP_NUM_TCP_PCB in opt.h (EthernetInterface\lwip\include\lwip\opt.h) and it didn't help either.

I'm using a C# console application for running a TCP client on WIndows. Based on what I saw, the 4th client did seem connected, but an exception was thrown during the "read" function (blocking): "System.Exception {System.IO.IOException} - Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."

And looked like the mbed didn't "detect" the pending connection from the 4th client and the code continues as nothing happened as well.

My code:

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

#define SERVER_PORT             54322
#define MAX_NUM_OF_CONNECTIONS  10

DigitalOut led1(LED1);
DigitalIn alert_button (p23);
Ticker timer;

bool flag = false;
int num_connections = 0;

//Toggle the flag for checking new connections
void check()
{
    if (num_connections < MAX_NUM_OF_CONNECTIONS)
        flag = true;
}

int main (void)
{
    printf("Initializing the Ethernet interface...\n");
    EthernetInterface eth;
    if (eth.init() < 0)
        printf("---Could not initialize the Ethernet interface\n");


    printf("Connecting...\n");
    if(eth.connect() < 0)
        printf("---Could not connect\n");

    printf("\nIP Address is %s\n", eth.getIPAddress());


    printf("\nInitializing and binding the TCP socket...\n");
    TCPSocketServer server;
    if (server.bind(SERVER_PORT) < 0)
        printf("---Could not initialize or bind\n");


    printf("Starting the TCP socket for listening...\n");
    server.set_blocking(false);
    if (server.listen() < 0)
        printf("---Could not start listening\n");

    TCPSocketConnection clients[MAX_NUM_OF_CONNECTIONS];
    bool clients_status[MAX_NUM_OF_CONNECTIONS];

    timer.attach(&check, 5.0);

    printf("\nReady\n");

    char buffer[] = "ALERT!!!";

    while (true) {
        if (flag == true) {
            led1 = 1;

            int index_to_connect = 0;
            bool done_finding = false;

            // Find an empty element for assigning a new connection to it
            while(!done_finding) {
                if (clients_status[index_to_connect] == false)
                    done_finding = true;
                else
                    index_to_connect++;
            }

            // Accept the new connection if there is one pending
            if (server.accept(clients[index_to_connect]) == 0) {
                clients[index_to_connect].set_blocking(false);
                printf("Connected to %s\n", clients[index_to_connect].get_address());

                clients_status[index_to_connect] = true;
                num_connections++;
            }

            led1 = 0;
            flag = false;
        }

        // Send an alert to connected clients when the button is pressed
        if (alert_button == 1 && num_connections > 0) {
            int index_to_send = 0;
            int num_disconnections = 0;
            bool done_sending = false;

            while (!done_sending) {
                if (clients_status[index_to_send] == true) {
                    int result = clients[index_to_send].send(buffer, sizeof(buffer));

                    if (result < 0) {
                        printf("%s has disconnected\n", clients[index_to_send].get_address());
                        clients[index_to_send].close();
                        clients_status[index_to_send] = false;
                    } else
                        printf("Sent to %s\n", clients[index_to_send].get_address());
                }

                if (index_to_send > MAX_NUM_OF_CONNECTIONS)
                    done_sending = true;
                else
                    index_to_send++;
            }

            if (num_disconnections > 0)
                num_connections -= num_disconnections;

            while (alert_button == 1) {} // Stay looping until the button is relased
        }
    }
}

What should I do? Let me know if I need to put more information or anything else on here.

Question relating to:

3 Answers

10 years, 4 months ago.

I wanted 3 listening sockets, and at least 2 active ones. I found that changing the definition of MEMP_NUM_NETCONN in EthernetInterface\lwip\include\lwip\opt.h solved this for me. I increased it from 4 to 6.

Hmm... I am having the same issue as the OP - I increased MEMP_NUM_NETCONN from 4 to 5 and then tried to open 5 connections, and the 5th request resulted in the first socket connection getting closed.

posted by Dave M 18 Sep 2014

Dave, is your code a server listening for connections? If so, I'm pretty sure that listening socket takes up an extra connection "slot", so you'll need to increase the value to be at least the sum of all active connections plus all listening sockets.

posted by Kean Maizels 23 Sep 2014
10 years, 4 months ago.

I have a similar issue with 3 UDP sockets, I believe its the same reason: in (api_lib.c) in netconn_new_with_proto_and_callback() is a call to TCPIP_APIMSG(&msg) and this fails on the 4th attempt.

Since the LWIP_TCPIP_CORE_LOCKING=0, this macro resolves to tcpip_apimsg(m), and this leads me to a global variable "static sys_mbox_t mbox", defined in the file tcpip.c

I'm considerung to transfer this issue into the forum, the "questions" seem not to get the required attention

10 years, 7 months ago.

Ethernet is not something I have looked into, but have a look at https://mbed.org/users/daniele/code/PicoTCP/, IIRC it doesn't have connection limit (besides resources).

See also: http://mbed.org/forum/mbed/topic/4396/