Page 1 of 1

File descriptor on read becoming invalid.

Posted: Thu Feb 01, 2024 1:27 pm
by rob18767
I am using code very similar to the following code.

Code: Select all

/**
    @file       main.cpp
    @brief      NetBurner Simple TCP/IP Server Example
    This program will create a TCP server task, which listens on port 23 by
    default. To test the application you can use Telnet. For example, from a
    windows commpan prompt, type `telent <ip address of netburner>`.
    This example uses a simple read() function to receive data from a TCP
    client.
**/

#include "predef.h"
#include <stdio.h>
#include <startnet.h>
#include <tcp.h>
#include <init.h>

const char *AppName = "Simple TCP Server Example";

#define TCP_LISTEN_PORT	23   // Telent port number
#define RX_BUFSIZE (4096)

//----- Global Vars -----
char RXBuffer[RX_BUFSIZE];

/*-------------------------------------------------------------------
 Convert IP address to a string
 -------------------------------------------------------------------*/
void IPtoString(IPADDR  ia, char *s)
{
    PBYTE ipb= (PBYTE)&ia;
    siprintf(s, "%d.%d.%d.%d",(int)ipb[0],(int)ipb[1],(int)ipb[2],(int)ipb[3]);
}

// Allocate task stack for UDP listen task
DWORD   TcpServerTaskStack[USER_TASK_STK_SIZE];

/*-------------------------------------------------------------------
 TCP Server Task
 -------------------------------------------------------------------*/
void TcpServerTask(void * pd)
{
    int ListenPort = (int) pd;

    // Set up the listening TCP socket
    int fdListen = listen(INADDR_ANY, ListenPort, 5);

    if (fdListen > 0)
    {
        IPADDR	client_addr;
        WORD	port;

        while(1)
        {
            // The accept() function will block until a TCP client requests
            // a connection. Once a client connection is accepting, the
            // file descriptor fdnet is used to read/write to it.
            iprintf( "Wainting for connection on port %d...\n", ListenPort );
            int fdnet = accept(fdListen, &client_addr, &port, 0);

            iprintf("Connected to: ");
            ShowIP(client_addr);
            iprintf(":%d\n", port);

            writestring(fdnet, "Welcome to the NetBurner TCP Server\r\n");
            char s[20];
            IPtoString(EthernetIP, s);
            siprintf(RXBuffer, "You are connected to IP Address %s, port %d\r\n",
                     s, TCP_LISTEN_PORT);
            writestring(fdnet, RXBuffer);

            while (fdnet > 0)
            {
                /* Loop while connection is valid. The read() function will return
                   0 or a negative number if the client closes the connection, so we
                   test the return value in the loop. Note: you can also use
                   ReadWithTimout() in place of read to enable the connection to
                   terminate after a period of inactivity.
                */
                int n = 0;
                do
                {
                    n = read( fdnet, RXBuffer, RX_BUFSIZE );
                    RXBuffer[n] = '\0';
                    iprintf( "Read %d bytes: %s\n", n, RXBuffer );
                }
                while ( n > 0 );

                // Don't foreget to close !
                iprintf("Closing client connection: ");
                ShowIP(client_addr);
                iprintf(":%d\n", port);
                close(fdnet);
                fdnet = 0;
            }
        } // while(1)
    } // while listen
}


/*-------------------------------------------------------------------
 User Main
 ------------------------------------------------------------------*/
extern "C" void UserMain(void * pd)
{
    init();

    // Create TCP Server task
    OSTaskCreate( TcpServerTask,
                  (void  *)TCP_LISTEN_PORT,
                  &TcpServerTaskStack[USER_TASK_STK_SIZE] ,
                  TcpServerTaskStack,
                  MAIN_PRIO - 1);	// higher priority than UserMain

    while (1)
    {
        OSTimeDly( TICKS_PER_SECOND * 5 );
    }
}

The code works for a while and then I lose the TCP connection

I checked the following line:

Code: Select all

 n = read( fdnet, RXBuffer, RX_BUFSIZE );
And n is negative (-2) when I lose the TCP connection (close function is called).

fdnet was 33 initially if I try to accept again using:

Code: Select all

 int fdnet = accept(fdListen, &client_addr, &port, 0);
then fdnet is set to 32.

In what ways can my file descriptor become invalid?

Something on the company network? This has only recently started occurring.

Thank you.

Re: File descriptor on read becoming invalid.

Posted: Fri Feb 02, 2024 10:12 am
by TomNB
Hello,

Tools revision and platform?

Re: File descriptor on read becoming invalid.

Posted: Fri Feb 02, 2024 11:08 am
by rob18767
TomNB wrote: Fri Feb 02, 2024 10:12 am Hello,

Tools revision and platform?
NNDK 2.7.7 and MOD5270B.

Re: File descriptor on read becoming invalid.

Posted: Fri Feb 02, 2024 11:15 am
by pbreed
First a general nit pick... when you close the connection, set fdnet =-1 not 0.
0 is stdout....


Now when you do a read given teh code you are showing I don't see a valid path to get a -2 return on that read.
You should only get a -2 if the TCP socket has already been closed or has not completed negotiation.

Exactly what platform and NNDK revision are you seeing this on?
I'd like to try an recreate?

Paul

Re: File descriptor on read becoming invalid.

Posted: Sun Feb 04, 2024 9:49 am
by TomNB
Hello Rob,

We see that you already posted your tools rev and platform. We will use that.

Re: File descriptor on read becoming invalid.

Posted: Mon Feb 05, 2024 9:58 am
by rob18767
Hi my bad

We found that we can run most commands and we tested a command that save values to non volatile memory. This seems to be the problem.

Apologies for any time wasted.

Thank you.

Re: File descriptor on read becoming invalid.

Posted: Mon Feb 05, 2024 10:10 am
by TomNB
Hi Rob,

Glad its working, and thank you for the update!