Почему сервер TCP-BSD застрял в read () даже данные получает? - PullRequest
1 голос
/ 01 апреля 2020

Я создал приложение сервера TCP с использованием сокетов BSD и платы разработки NUCLEO-H743ZI2 с STM32CubeMX 5.6.0 и LwIP 2.0.3 в Keil-MDKARM.

Я заметил, что:

  • Если клиент сначала подключается и отправляет 11 или более байтов, сервер получает данные правильно и read() отвечает, отображая данные.
  • Однако, если клиент отправляет первые данные размером менее 11 байтов, read() функциональные блоки, даже если следующие полученные данные превышают 11 байт, пока клиент не отключится. После отключения отображаются все данные, поставленные в очередь.

А именно, если первые данные, отправленные клиентом на мой сервер, имеют размер менее 11 байтов, event_callback для rcvevent не будет запущен до отключения.

Моя цель - сделать сервер доступным для приема одного байта.

Я вставил задачу / поток для сервера ниже. Позвольте мне в кратчайшие сроки получить ваши добрые ответы и не стесняйтесь запрашивать другие связанные файлы / библиотеки (lwip.h, lwipopts.h ..).

С уважением

void StartTask01(void const * argument)
{
    /* USER CODE BEGIN StartTask01 */
    MX_LWIP_Init();

    /*start a listening tcp server*/
    int iServerSocket;
    struct sockaddr_in address;

    if ((iServerSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    {
        printf("Socket could not be created\n");
    }
    else
    {
        address.sin_family = AF_INET;
        address.sin_port = htons(80);
        address.sin_addr.s_addr = INADDR_ANY;

        if (bind(iServerSocket, (struct sockaddr *)&address, sizeof (address)) < 0)
        {
            printf("socket could not be bound\n");
        }
        else
        {
            listen(iServerSocket, MEMP_NUM_NETCONN);    
        }
    }
    /*server started listening*/

    struct sockaddr_in remoteHost;
    int newconn;
    char caReadBuffer[1500];
    memset(caReadBuffer, 0, 1500);

    for(;;)
    {
        /*block until accepting an incoming connection*/
        newconn = accept(iServerSocket, (struct sockaddr *)&remoteHost, (socklen_t *)(sizeof(remoteHost)));

        if (newconn != -1)/*if accepted well*/
        {   
            /*block until data arrives*/
            read(newconn, caReadBuffer, sizeof(caReadBuffer));
            printf("data read: %s\n", caReadBuffer);
            memset(caReadBuffer, 0, 1500);
        }
    }
/* USER CODE END StartTask01 */
}

Ответы [ 2 ]

0 голосов
/ 01 апреля 2020

решено:

Проблема в том, что мой сервер прослушивал порт 80. Я изменил его на порт 7, и, к счастью, ошибка устранена, теперь read () работает, как и ожидалось.

Эта ошибка позвольте мне думать, что у LwIP были проблемы при прослушивании этого порта web (80) вместо других. Должно быть какое-то различие между прослушиванием некоторых впечатляющих портов даже для невыполненных протоколов.

0 голосов
/ 01 апреля 2020

Проблема, которая вызывает эту проблему, заключается в том, что вы звоните read только один раз для каждого соединения. Если вам не удастся получить все данные из этого единственного вызова на read (что совершенно непредсказуемо), вы никогда больше не будете вызывать read для этого соединения.

Когда вы звоните read на блокирующем TCP-соединении оно будет блокироваться только при отсутствии доступных данных. В противном случае он предоставит вам все доступные данные вплоть до максимального количества запрашиваемых вами байтов. Это не будет ждать больше данных, если только некоторые доступны. Вам нужно снова позвонить read, если вы не получили все данные, которые ожидали.

Одна ваша вторая итерация for l oop, вы перезаписываете newconn новым подключение. Вы не закрываете старую связь. Итак, у вас есть утечка в сокете.

...