Async TCP/IP server

maddogmaycry
Posts: 11
Joined: Sun Apr 17, 2022 6:58 am

Async TCP/IP server

Postby maddogmaycry » Thu Apr 28, 2022 8:05 am

Me again,

UPD
I think this is a Putty's fault.
When i put line with "\r\n" inside of it at the end, this scenario will be repeated. When i send line by "ENTER" button, it's seems to be ok.

i use async tcp/ip server and sometimes i get this scenario:
Recive buffer is 1024 lenght.
I send this msg to server (816 bytes):

Code: Select all

777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777
Server reads data from socket and then bring recived data back to the client.
At the end of block i have special CHAR symbols "\r\n"
and sometimes i can see, that server recived not whole data at once:

Code: Select all

I (44001) nonblocking-socket-server: [sock=56]:
Received 777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777
I (44071) nonblocking-socket-server: [sock=56]:
Written 777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777
I (44181) nonblocking-socket-server: [sock=56]:
Received 

I (44181) nonblocking-socket-server: [sock=56]:
Written 
this part means that those "\r\n" symbols has been recived separatly.

Code: Select all

I (44181) nonblocking-socket-server: [sock=56]:
Received 

I (44181) nonblocking-socket-server: [sock=56]:
Written
Code

Code: Select all

#include "esp_log.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include <lwip/netdb.h>
#define INVALID_SOCK (-1)
void watchdog();
static void log_socket_error(const char *tag, const int sock, const int err, const char *message){
    ESP_LOGE(tag, "[sock=%d]: %s\n" "error=%d: %s", sock, message, err, strerror(err));
}

static int try_receive(const char *tag, const int sock, char * data, size_t max_len){
    int len = recv(sock, data, max_len, 0);
    if (len < 0) {
        if (errno == EINPROGRESS || errno == EAGAIN || errno == EWOULDBLOCK) {
            return 0;   // Not an error
        }
        if (errno == ENOTCONN) {
            ESP_LOGW(tag, "[sock=%d]: Connection closed", sock);
            return -2;  // Socket has been disconnected
        }
        log_socket_error(tag, sock, errno, "Error occurred during receiving");
        return -1;
    }
    return len;
}

static int socket_send(const char *tag, const int sock, const char * data, const size_t len){
    int to_write = len;
    while (to_write > 0) {
        int written = send(sock, data + (len - to_write), to_write, 0);
        if (written < 0 && errno != EINPROGRESS && errno != EAGAIN && errno != EWOULDBLOCK) {
            log_socket_error(tag, sock, errno, "Error occurred during sending");
            return -1;
        }
        to_write -= written;
    }
    return len;
}

static inline char* get_clients_address(struct sockaddr_storage *source_addr){
    static char address_str[128];
    char *res = NULL;
    if (source_addr->ss_family == PF_INET) {
        res = inet_ntoa_r(((struct sockaddr_in *)source_addr)->sin_addr, address_str, sizeof(address_str) - 1);
    }
    if (!res) {
        address_str[0] = '\0';
    }
    return address_str;
}

bool tcp_server_task(){
    static char rx_buffer[1024];
    static const char *TAG = "nonblocking-socket-server";
    struct addrinfo hints = { .ai_socktype = SOCK_STREAM };
    struct addrinfo *address_info;
    int listen_sock = INVALID_SOCK;
    static int sock = INVALID_SOCK;

    int res = getaddrinfo("0.0.0.0", "23", &hints, &address_info);
    if (res != 0 || address_info == NULL){
        ESP_LOGE(TAG, "couldn't get hostname for `%s` " "getaddrinfo() returns %d, addrinfo=%p", "0.0.0.0", res, address_info);
        return false;
    }

    listen_sock = socket(address_info->ai_family, address_info->ai_socktype, address_info->ai_protocol);

    if (listen_sock < 0) {
        log_socket_error(TAG, listen_sock, errno, "Unable to create socket");
        goto error;
    }
    ESP_LOGI(TAG, "Listener socket created");

    int flags = fcntl(listen_sock, F_GETFL);
    if (fcntl(listen_sock, F_SETFL, flags | O_NONBLOCK) == -1) {
        log_socket_error(TAG, listen_sock, errno, "Unable to set socket non blocking");
        goto error;
    }
    ESP_LOGI(TAG, "Socket marked as non blocking");
    
    int err = bind(listen_sock, address_info->ai_addr, address_info->ai_addrlen);
    if (err != 0) {
        log_socket_error(TAG, listen_sock, errno, "Socket unable to bind");
        goto error;
    }
    ESP_LOGI(TAG, "Socket bound on %s:%s", "0.0.0.0", "23");
    err = listen(listen_sock, 1);
    if (err != 0) {
        log_socket_error(TAG, listen_sock, errno, "Error occurred during listen");
        goto error;
    }
    ESP_LOGI(TAG, "Socket listening");
    while (1) {
        struct sockaddr_storage source_addr;
        socklen_t addr_len = sizeof(source_addr);
        if (sock == INVALID_SOCK){
            sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
            if (sock < 0) {
                if (errno == EWOULDBLOCK) {
                    ESP_LOGV(TAG, "No pending connections...");
                } 
                else {
                    log_socket_error(TAG, listen_sock, errno, "Error when accepting connection");
                    goto error;
                }
            } 
            else {
                ESP_LOGI(TAG, "[sock=%d]: Connection accepted from IP:%s", sock, get_clients_address(&source_addr));
                flags = fcntl(sock, F_GETFL);
                if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {
                    log_socket_error(TAG, sock, errno, "Unable to set socket non blocking");
                    goto error;
                }
                ESP_LOGI(TAG, "[sock=%d]: Socket marked as non blocking", sock);
            }
        }

        if (sock != INVALID_SOCK){
            int len = try_receive(TAG, sock, rx_buffer, sizeof(rx_buffer));
            if (len < 0) {
                ESP_LOGI(TAG, "[sock=%d]: try_receive() returned %d -> closing the socket", sock, len);
                close(sock);
                sock = INVALID_SOCK;
                goto error;
            } 
            else if (len > 0) {
                ESP_LOGI(TAG, "[sock=%d]: Received %.*s", sock, len, rx_buffer);
                len = socket_send(TAG, sock, rx_buffer, len);
                if (len < 0) {
                    ESP_LOGI(TAG, "[sock=%d]: socket_send() returned %d -> closing the socket", sock, len);
                    close(sock);
                    sock = INVALID_SOCK;
                } else {
                    ESP_LOGI(TAG, "[sock=%d]: Written %.*s", sock, len, rx_buffer);
                }
            }
        }
        // watchdog();
        vTaskDelay(pdMS_TO_TICKS(16));
    }

error:
    if (listen_sock != INVALID_SOCK) {
        close(listen_sock);
    }
    if (sock != INVALID_SOCK){
        close(sock);
    }
    free(address_info);
    tcp_server_task();
    return true;
}
I tryed to increase delay up to 50

Code: Select all

vTaskDelay(pdMS_TO_TICKS(50));
w/o success..

Help =)

Who is online

Users browsing this forum: No registered users and 142 guests