Разбор примера TCP server - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Не понимаю почему эта конструкция работает: Имеется код:
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*/
...
}
так вот в чём состоит не понимание: не понимаю как переключается switch ведь при первоначальной инициализации создаётся именованный список и его значение приравнивается к SM_HOME, соответственно выполнение switch идёт по ветке case SM_HOME и если всё нормально (MySocket не равен INVALID_SOCKET), то TCPServerState становится равным SM_LISTENING и дальше идёт break, то есть выход из switch и на этом функция заканчивается, никакого перехода на SM_LISTENING не будет (или я чего-то не понимаю??). Но как он может попасть на SM_LISTENING??? хоть убей не понимаю, даже если взять то, что у нас эта функция вызывается постоянно, то она при каждом вызове будет создавать именованный список с значением TCPServerState равным SM_HOME и мы всё равно не попадём в другие ветки switch.. В общем если кто-то сможет объяснить буду очень рад. Если что-то не понятно пишите

Решение задачи: «Разбор примера TCP server»

textual
Листинг программы
    static enum _TCPServerState
    {
        SM_HOME = 0,
        SM_LISTENING,
        SM_CLOSING,
    } TCPServerState = SM_HOME;

Объяснение кода листинга программы

  1. В данном коде определен перечисление (enum) с названием _TCPServerState.
  2. Перечисление содержит три элемента: SM_HOME, SM_LISTENING, SM_CLOSING.
  3. Значение переменной TCPServerState установлено равным SM_HOME.
  4. Переменная TCPServerState является статической и принадлежит классу (не показан в данном фрагменте кода).

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.286 из 5
Похожие ответы