How to dynamically specify TCPServer port?

I have some server code that works fine if I hardcode the listening port as a global, e.g.

TCPServer server = TCPServer(80);

but I want to be able to change that port inside the program, e.g. save the listening port in EEPROM and read it on restart.

I can't declare "TCPServer server" without the initializer, I get

QuinnsLightCPU.cpp:701:12: error: no matching function for call to 'TCPServer::TCPServer()'
TCPServer server;
^
QuinnsLightCPU.cpp:701:12: note: candidates are:
In file included from ./inc/application.h:53:0,
from Graphics.h:4,
from QuinnsLightCPU.cpp:23:
../wiring/inc/spark_wiring_tcpserver.h:42:2: note: TCPServer::TCPServer(uint16_t, network_interface_t)
TCPServer(uint16_t, network_interface_t nif=0);
^
../wiring/inc/spark_wiring_tcpserver.h:42:2: note: candidate expects 2 arguments, 0 provided
../wiring/inc/spark_wiring_tcpserver.h:34:7: note: constexpr TCPServer::TCPServer(const TCPServer&)
class TCPServer : public Print {
^
../wiring/inc/spark_wiring_tcpserver.h:34:7: note: candidate expects 1 argument, 0 provided

Is there any way to set up the server without a hardcoded port?

You could allocate the instance dynamically:

TCPServer* server = NULL;

void setup()
{
   int port;
   EEPROM.get(0, port);
   server = new TCPServer(port);
}

It’s like this because of compatibility with arduino, although in future, I see no issue with adding an optional port to the “begin” method. Then the code could be simpler:

TCPServer server;

void setup()
{
    int port;
    EEPROM.get(0, port);
    server.begin(port);
}
4 Likes

Thanks for the idea. As written this global declaration

TCPServer server = NULL;

gives this:

QuinnsLightCPU.cpp:56:20: warning: passing NULL to non-pointer argument 1 of 'TCPServer::TCPServer(uint16_t, network_int
erface_t)' [-Wconversion-null]
TCPServer server = NULL;
^

and this in setup()

server = new TCPServer(wsPort);

gives this

QuinnsLightCPU.cpp: In function 'void setup()':
QuinnsLightCPU.cpp:610:9: error: invalid user-defined conversion from 'TCPServer*' to 'const TCPServer&' [-fpermissive]
server = new TCPServer(wsPort);
^
In file included from ./inc/application.h:53:0,
from Graphics.h:4,
from QuinnsLightCPU.cpp:23:
../wiring/inc/spark_wiring_tcpserver.h:42:2: note: candidate is: TCPServer::TCPServer(uint16_t, network_interface_t)
TCPServer(uint16_t, network_interface_t nif=0);
^
../wiring/inc/spark_wiring_tcpserver.h:42:2: note: no known conversion for argument 1 from 'TCPServer*' to 'uint16_t {
aka short unsigned int}'
QuinnsLightCPU.cpp:610:9: error: invalid conversion from 'TCPServer*' to 'uint16_t {aka short unsigned int}' [-fpermissi
ve]
server = new TCPServer(wsPort);
^
In file included from ./inc/application.h:53:0,
from Graphics.h:4,
from QuinnsLightCPU.cpp:23:
../wiring/inc/spark_wiring_tcpserver.h:42:2: error: initializing argument 1 of 'TCPServer::TCPServer(uint16_t, network
_interface_t)' [-fpermissive]
TCPServer(uint16_t, network_interface_t nif=0);
^

But if I remove the "new" from the assignment in setup() the code will compile and it looks like it's working as expected so I'll ignore that warning for now.

Thanks again.

Then the code could be simpler

A single fixed port number is not so hot, to understate.

Rather than New which is off the heap, declaring a static class instance at compile time is probably prudent. Static outside a function, and/or global, rather than off the stack as a local.

There was a typo - I changed TCPServer to TCPServer*.