Async TCP/IP server
Posted: 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):
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:
this part means that those "\r\n" symbols has been recived separatly.
Code
I tryed to increase delay up to 50
w/o success..
Help =)
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
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
Code: Select all
I (44181) nonblocking-socket-server: [sock=56]:
Received
I (44181) nonblocking-socket-server: [sock=56]:
Written
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;
}
Code: Select all
vTaskDelay(pdMS_TO_TICKS(50));
Help =)