I'm very new to the TCP/IP stack from Microchip and I have succesfully created my own basic TCP server with the help of some of the examples in the Harmony folder. I would like to expand my TCP server to cater to multiple client connections on the same port but I'm not entirely sure the best way to go about this.
Below is a snippit of my basic Server application.
void TCP_SERVER_Tasks ( void )
{
//Handle for the network interface
static TCPIP_NET_HANDLE networkInterfaceHandle;
//IP Address assigned to DHCP Client
static IPV4_ADDR hostIPAddress;
//Handle for TCP Client
static TCP_SOCKET TCPSocketHandle = INVALID_SOCKET;
//System Timer Tick Values
static uint32_t statusRequestTick;
static uint32_t timeoutTick;
//Temporary Buffer for Storage of received UDP/TCP Data
uint8_t receivedDataBuffer[128];
uint16_t numberDataBytesToProcess;
//Check if the network interface has become disconnected.
//Close any open sockets, and goto NETWORKCOMS_STATE_INIT state
if (tcp_serverData.state > NETWORKCOMS_STATE_WAIT_FOR_LINK &&
TCPIP_STACK_NetIsLinked(networkInterfaceHandle) == false)
{
if (TCPSocketHandle != INVALID_SOCKET)
{
//Close the Open TCP Socket
TCPIP_TCP_Close(TCPSocketHandle);
TCPSocketHandle = INVALID_SOCKET;
}
tcp_serverData.state = NETWORKCOMS_STATE_WAIT_FOR_LINK;
}
/* Check the application's current state. */
switch ( tcp_serverData.state )
{
/* Application's initial state. */
case TCP_SERVER_STATE_INIT:
{
//Wait for the TCPIP Stack and System Timer Service to become initialized
if (TCPIP_STACK_Status(sysObj.tcpip) == SYS_STATUS_READY &&
SYS_TMR_Status(sysObj.sysTmr) == SYS_STATUS_READY)
{
if (TCPIP_STACK_NumberOfNetworksGet() > 0)
{
//Get a handle to the network interface
//For this application only one interface is used
networkInterfaceHandle = TCPIP_STACK_IndexToNet(0);
}
timeoutTick = SYS_TMR_TickCountGet();
tcp_serverData.state = NETWORKCOMS_STATE_WAIT_FOR_LINK;
}
break;
}
case NETWORKCOMS_STATE_WAIT_FOR_LINK:
{
//Determine if the network interface is connected
if (TCPIP_STACK_NetIsLinked(networkInterfaceHandle))
{
//Check if a DHCP Server can be found on the network
if (TCPIP_DHCP_IsBound(networkInterfaceHandle))
{
hostIPAddress.Val = TCPIP_STACK_NetAddress(networkInterfaceHandle);
tcp_serverData.state = NETWORKCOMS_SETUP_TCP_SERVER;
}
}
break;
}
case NETWORKCOMS_SETUP_TCP_SERVER:
{
//Setup the TCP Server on the port defined by the TCP_SERVER_PORT constant.
//Store the returned socket handle in the TCPSocketHandle variable.
TCPSocketHandle = TCPIP_TCP_ServerOpen(IP_ADDRESS_TYPE_IPV4, TCP_SERVER_PORT, 0);
// Verify that the socket opened correctly
if (TCPSocketHandle != INVALID_SOCKET )
{
tcp_serverData.state = NETWORK_WAIT_FOR_CONNECTION;
}
break;
}
case NETWORK_WAIT_FOR_CONNECTION:
{
// Periodically check to see if a Client has connected
if( TCPIP_TCP_IsConnected(TCPSocketHandle) )
{
tcp_serverData.state = NETWORK_SERVICE_CONNECTION;
}
break;
}
case NETWORK_SERVICE_CONNECTION:
{
// Make sure that the connection is still available
if ( !TCPIP_TCP_IsConnected(TCPSocketHandle) )
{
tcp_serverData.state = NETWORK_WAIT_FOR_CONNECTION;
}
else
{
if ( TCPIP_TCP_PutIsReady(TCPSocketHandle) > 10 )
{
TCPIP_TCP_StringPut(TCPSocketHandle, "HELLO!!\r\n\0");
}
tcp_serverData.state = NETWORK_CLOSE_CONNECTION;
}
break;
}
case NETWORK_CLOSE_CONNECTION:
{
TCPIP_TCP_Close(TCPSocketHandle);
tcp_serverData.state = NETWORKCOMS_SETUP_TCP_SERVER;
break;
}
/* The default state should never be executed. */
default:
{
/* TODO: Handle error in application's state machine. */
break;
}
}
}
`
Right now if a connection comes in on the port the code responds with HELLO! and then closes the connection.
Before I begin changing the code to service multiple client I need some clarifiaction. Do I need to bind the server socket to my local address before I can begin accepting multiple clients and why?
Can I use the Berkley_Server example located in the Harmony folder as a general template on how to build a general TCP server with multiple client access?
Any clarification or insight will be very appreciated.