I have an application I’ve written that has two network servers running, each in a Thread.
Thread 1 - HTTP Server bound to port 80
Thread 2 - TCP Server bound to port 9100 (custom protocol)
Each thread initializes it’s own TCPSocket to act as a server and listening for connection attempts.
What happens is that after I start up both threads so that both server TCPSockets() have been initialized and accepting() connections is that I can only interact with one server at a time. I can connect to the HTTP Server on Thread 1 get back the correct HTML etc. I can also make a connection to the TCP Server on Thread 2 and do whatever is needed.
However, if I have the TCP Server on Thread 2 handling a connection sending and receiving data and attempt to access the HTTPServer on Thread 1 I encounter a hardfault and the board resets.
The two server threads aren’t sharing any resources with the exception of the EthernetInterface.
If I pass the same EthernetInterface to both threads the threads are initialized correctly.
However, if I instantiate two EthernetInterface objects like this:
EthernetInterface httpnet = EthernetInterface();
EthernetInterface ecnet = EthernetInterface();
and then instantiate my two Server threads like this:
NetServer server( &ecnet, 9100, jobQueue);
HTTPServer webServer( &httpnet, 80 );
server.start();
webServer.start();
processor.start();
watchdog.start();
The HTTPServer thread fails to initialize the TCPSocket.
But if I send the same EthernetInterface
object to the constructors of the server threads then they are both initialized and the servers can accept connections - just not simultaneoulsy.
Both threads do the following to initialize and get the server socket ready to accept connections.
// Initialize network socket, bind and start listening for connections
bool NetServer::Init()
{
bool retCode = false;
SocketAddress server_address;
nsapi_error_t result;
m_interface->attach(&util::net::NetworkStatus_callback);
result = NSAPI_ERROR_OK;
if( NSAPI_STATUS_DISCONNECTED == m_interface->get_connection_status() )
{
result = m_interface->connect();
}
if( NSAPI_ERROR_OK == result )
{
if( NSAPI_ERROR_OK == m_interface->get_ip_address(&server_address))
{
m_ipAddress = std::string(server_address.get_ip_address());
printf("\nServer IP address: %s\n", m_ipAddress.c_str());
server_address.set_port(m_port);
if( NSAPI_ERROR_OK == m_serverSock.open(m_interface))
{
if( NSAPI_ERROR_OK == m_serverSock.bind( server_address ))
{
if( NSAPI_ERROR_OK == m_serverSock.listen(5))
{
retCode = true;
}
}
}
}
}
return (retCode);
}
Note that m_interface
is the EthernetInterface passed in the constructor.
Any idea what I might be doing wrong?
I could share more of the code if needed.
My hardware in the NXP RT1050 EVKB with 100mbit Ethernet.