Разбор примера TCP server - C (СИ)
Формулировка задачи:
Не понимаю почему эта конструкция работает:
Имеется код:
это функция вызывается постоянно из другого кода где крутится в бесконечном цикле:
так вот в чём состоит не понимание: не понимаю как переключается switch ведь при первоначальной инициализации создаётся именованный список и его значение приравнивается к SM_HOME, соответственно выполнение switch идёт по ветке case SM_HOME и если всё нормально (MySocket не равен INVALID_SOCKET), то TCPServerState становится равным SM_LISTENING и дальше идёт break, то есть выход из switch и на этом функция заканчивается, никакого перехода на SM_LISTENING не будет (или я чего-то не понимаю??). Но как он может попасть на SM_LISTENING??? хоть убей не понимаю, даже если взять то, что у нас эта функция вызывается постоянно, то она при каждом вызове будет создавать именованный список с значением TCPServerState равным SM_HOME и мы всё равно не попадём в другие ветки switch..
В общем если кто-то сможет объяснить буду очень рад. Если что-то не понятно пишите
void GenericTCPServer(void)
{
BYTE i;
WORD w, w2;
BYTE AppBuffer[32];
WORD wMaxGet, wMaxPut, wCurrentChunk;
static TCP_SOCKET MySocket;
static enum _TCPServerState
{
SM_HOME = 0,
SM_LISTENING,
SM_CLOSING,
} TCPServerState = SM_HOME;
switch(TCPServerState)
{
case SM_HOME:
// Allocate a socket for this server to listen and accept connections on
MySocket = TCPOpen(0, TCP_OPEN_SERVER, SERVER_PORT, TCP_PURPOSE_GENERIC_TCP_SERVER);
if(MySocket == INVALID_SOCKET)
return;
TCPServerState = SM_LISTENING;
break;
case SM_LISTENING:
// See if anyone is connected to us
if(!TCPIsConnected(MySocket))
return;
// Figure out how many bytes have been received and how many we can transmit.
wMaxGet = TCPIsGetReady(MySocket); // Get TCP RX FIFO byte count
wMaxPut = TCPIsPutReady(MySocket); // Get TCP TX FIFO free space
// Make sure we don't take more bytes out of the RX FIFO than we can put into the TX FIFO
if(wMaxPut < wMaxGet)
wMaxGet = wMaxPut;
// Process all bytes that we can
// This is implemented as a loop, processing up to sizeof(AppBuffer) bytes at a time.
// This limits memory usage while maximizing performance. Single byte Gets and Puts are a lot slower than multibyte GetArrays and PutArrays.
wCurrentChunk = sizeof(AppBuffer);
for(w = 0; w < wMaxGet; w += sizeof(AppBuffer))
{
// Make sure the last chunk, which will likely be smaller than sizeof(AppBuffer), is treated correctly.
if(w + sizeof(AppBuffer) > wMaxGet)
wCurrentChunk = wMaxGet - w;
// Transfer the data out of the TCP RX FIFO and into our local processing buffer.
TCPGetArray(MySocket, AppBuffer, wCurrentChunk);
// Perform the "ToUpper" operation on each data byte
for(w2 = 0; w2 < wCurrentChunk; w2++)
{
i = AppBuffer[w2];
if(i >= 'a' && i <= 'z')
{
i -= ('a' - 'A');
AppBuffer[w2] = i;
}
else if(i == 0x1B) //escape
{
TCPServerState = SM_CLOSING;
}
}
// Transfer the data out of our local processing buffer and into the TCP TX FIFO.
TCPPutArray(MySocket, AppBuffer, wCurrentChunk);
}
// No need to perform any flush. TCP data in TX FIFO will automatically transmit itself after it accumulates for a while. If you want to decrease latency (at the expense of wasting network bandwidth on TCP overhead), perform and explicit flush via the TCPFlush() API.
break;
case SM_CLOSING:
// Close the socket connection.
TCPClose(MySocket);
TCPServerState = SM_HOME;
break;
}
}while(1)
{
....
/*do something*/
...
#if defined(STACK_USE_GENERIC_TCP_SERVER_EXAMPLE) //у меня он дефайн, то есть определён
GenericTCPServer(); //и вызывается эта функция
#endif
...
/*do something*/
...
}Решение задачи: «Разбор примера TCP server»
textual
Листинг программы
static enum _TCPServerState
{
SM_HOME = 0,
SM_LISTENING,
SM_CLOSING,
} TCPServerState = SM_HOME;
Объяснение кода листинга программы
- В данном коде определен перечисление (enum) с названием
_TCPServerState. - Перечисление содержит три элемента: SM_HOME, SM_LISTENING, SM_CLOSING.
- Значение переменной
TCPServerStateустановлено равным SM_HOME. - Переменная
TCPServerStateявляется статической и принадлежит классу (не показан в данном фрагменте кода).