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 );
fdnet was 33 initially if I try to accept again using:
Code: Select all
int fdnet = accept(fdListen, &client_addr, &port, 0);
In what ways can my file descriptor become invalid?
Something on the company network? This has only recently started occurring.
Thank you.