197 lines
5.0 KiB
C++
197 lines
5.0 KiB
C++
#ifndef TCPSERVER_H
|
|
#define TCPSERVER_H
|
|
|
|
#include <ESP8266WiFi.h>
|
|
#include "List.h"
|
|
#include "TCPClient.h"
|
|
|
|
#define MAX_CLIENT -1
|
|
//#define DEBUG_TCPS
|
|
|
|
|
|
template <typename T>
|
|
class TCPServer
|
|
{
|
|
public:
|
|
TCPServer(unsigned int port = 80, uint8_t maxClient = MAX_CLIENT, uint16_t clientDataBufferSize = 255) : _wifiServer(port), _port(port), _serverStarted(true), _maxClient(maxClient), _clientDataBufferSize(clientDataBufferSize), _currentClient(NULL)
|
|
{
|
|
_wifiServer.begin();
|
|
}
|
|
|
|
virtual ~TCPServer()
|
|
{
|
|
_clientList.dispose();
|
|
}
|
|
|
|
uint8_t getMaxClient()
|
|
{
|
|
return _maxClient;
|
|
}
|
|
|
|
unsigned int getPort() const
|
|
{
|
|
return _port;
|
|
}
|
|
|
|
uint8_t getConnectedClientsCount()
|
|
{
|
|
return _clientList.count();
|
|
}
|
|
|
|
virtual void run()
|
|
{
|
|
handleNewClients();
|
|
getClientData();
|
|
}
|
|
|
|
virtual void start()
|
|
{
|
|
if(!_serverStarted)
|
|
{
|
|
_wifiServer.begin();
|
|
_serverStarted = true;
|
|
}
|
|
}
|
|
|
|
virtual void stop()
|
|
{
|
|
if(_serverStarted)
|
|
{
|
|
_wifiServer.stop();
|
|
_clientList.dispose();
|
|
_serverStarted = false;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
virtual T* createNewClient(WiFiClient wc)
|
|
{
|
|
return new T(wc, freeClientId(), _clientDataBufferSize);
|
|
}
|
|
|
|
virtual void handleNewClients()
|
|
{
|
|
WiFiClient wc;
|
|
|
|
if(_maxClient == -1 || _maxClient > _clientList.count())
|
|
{
|
|
wc = _wifiServer.available();
|
|
}
|
|
|
|
if(wc && wc.connected())
|
|
{
|
|
T *clientPointer = createNewClient(wc);
|
|
_clientList.addFirst(clientPointer);
|
|
#ifdef DEBUG_TCPS
|
|
Serial.printf("TCPServer : New client accepted. Id : %u , Number of clients : %u, local port : %u, remote port : %u\n",clientPointer->_id, _clientList.count(),clientPointer->_client.localPort(),clientPointer->_client.remotePort());
|
|
#endif
|
|
greetClient(clientPointer);
|
|
}
|
|
|
|
_currentClient = _clientList.removeLastRef();//We pick a client in the list to process it's request
|
|
|
|
if(_currentClient != NULL)
|
|
{
|
|
if(_currentClient->_error != TCPClient::OK)
|
|
{
|
|
_currentClient->closeConnection();
|
|
delete _currentClient; _currentClient = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual void greetClient(T *client)
|
|
{
|
|
client->_client.println(F("Successfully connected !"));
|
|
client->_client.print(F("Your are client with id : "));
|
|
client->_client.println(client->_id);
|
|
}
|
|
|
|
virtual void getClientData()
|
|
{
|
|
if(_currentClient == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
uint32_t bytesAvailable((_currentClient->_client).available());
|
|
|
|
if(bytesAvailable)
|
|
{
|
|
uint16_t freeSpace = (_currentClient->_dataBufferSize-1/*for \0*/ - _currentClient->_dataSize);
|
|
|
|
if(freeSpace != 0)
|
|
{
|
|
int amountToBeRead = bytesAvailable < freeSpace ? bytesAvailable : freeSpace;
|
|
|
|
(_currentClient->_client).read(_currentClient->_data + _currentClient->_dataSize, amountToBeRead);
|
|
_currentClient->_dataSize += amountToBeRead;
|
|
_currentClient->_data[_currentClient->_dataSize] = '\0';
|
|
_currentClient->_newDataAvailable = true;
|
|
}
|
|
}
|
|
else if(!(_currentClient->_client).connected())
|
|
{
|
|
#ifdef DEBUG_TCPS
|
|
Serial.print("TCPServer : Client disconnected and can be discarded : ");Serial.println(_currentClient->_id);
|
|
#endif
|
|
_currentClient->_clientState = TCPClient::DISCARDED;
|
|
}
|
|
|
|
processClientData(_currentClient);//We process the actual data
|
|
_currentClient->_newDataAvailable = false;
|
|
|
|
if(_currentClient->_clientState == TCPClient::ClientState::DISCARDED)
|
|
{
|
|
_currentClient->closeConnection();
|
|
#ifdef DEBUG_TCPS
|
|
Serial.print("TCPServer : Client was discarded : ");Serial.println(_currentClient->_id);
|
|
#endif
|
|
delete _currentClient;
|
|
_currentClient = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
_clientList.addFirst(_currentClient);
|
|
|
|
}
|
|
|
|
virtual void processClientData(T *client)
|
|
{
|
|
if(client->_dataSize > 0 && ((char) client->_data[0] != '\r' && (char) client->_data[0] != '\n'))
|
|
{
|
|
Serial.print("Client --> ");Serial.print(client->_id);Serial.print(" : ");Serial.print((char *)client->_data);Serial.println("#");
|
|
}
|
|
|
|
client->freeDataBuffer(client->_dataSize);
|
|
}
|
|
|
|
uint8_t freeClientId()
|
|
{
|
|
int listCounter(_clientList.count());
|
|
int freeId(0);
|
|
|
|
for(int i(0); i < listCounter; i++)
|
|
{
|
|
if(_clientList.getRef(i)->_id == freeId)
|
|
{
|
|
freeId++;
|
|
i = -1;
|
|
}
|
|
}
|
|
return freeId;
|
|
}
|
|
|
|
boolean _serverStarted;
|
|
uint8_t _maxClient;
|
|
unsigned int _port;
|
|
uint16_t _clientDataBufferSize;
|
|
WiFiServer _wifiServer;
|
|
T *_currentClient; //current client to be processed
|
|
List<T> _clientList;
|
|
private:
|
|
};
|
|
|
|
#endif //TCPSERVER_H
|