Как увеличить пропускную способность TCP-сервера (обслуживает последовательный порт через TCP)?Linux

Ответить Пред. темаСлед. тема
Anonymous
 Как увеличить пропускную способность TCP-сервера (обслуживает последовательный порт через TCP)?

Сообщение Anonymous »

Описание:
Я разрабатываю эхо-сервер TCP, который получает данные от TCP-клиента и записывает их в последовательный порт. порт, а затем считывает данные обратно из последовательного порта для отправки их TCP-клиенту. Для тестирования я использую разъем обратной связи (/dev/ttyUSB0). Этот сервер предназначен только для практики!
Это также сервер приложений для записи в качестве TCP-клиента, который отправляет данные на наш сервер и рассчитывает пропускную способность.
Текущая пропускная способность составляет примерно 72 КБ/с, и я планирую увеличить ее до 80 КБ/с. Вот краткий обзор функциональности и настройки моего сервера:
  • Сервер прослушивает входящие TCP-соединения и обрабатывает их, используя неблокирующий сокет.
    Данные, полученные от TCP-клиента, записываются в последовательный порт.
  • Данные, считанные из последовательного порта, отправляются обратно TCP-клиенту.
  • Я реализовал верхние/низкие водяные знаки для контроля того, когда приостанавливать или возобновлять запись в последовательный порт. (Поскольку существует разница в пропускной способности между TCP и последовательным портом)
Однако я изо всех сил пытаюсь достичь желаемой пропускной способности .

Вопросы:
  • Какие стратегии или оптимизации я могу применить для увеличения пропускной способности сервера?
  • Есть ли потенциальные узкие места в моей текущей реализации?
  • Есть ли более эффективные способы обработки последовательного порта и TCP-соединения для повышения производительности?

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define BACK_LOG 5
#define BUFFER_SIZE 8192
#define SERIAL_BUFFER_SIZE 2048
#define MAX(x, y) (((x) > (y)) ? (x) : (y))

typedef struct sockaddr_in sockaddr_in;
typedef struct tcp_info
{
int fd;
sockaddr_in socket_address;
} tcp_info;

void tcp_destroy_server(tcp_info *tcp_server)
{
if (tcp_server == NULL)
{
return;
}

close(tcp_server->fd);
free(tcp_server);
}

tcp_info *tcp_create_server(const char *ip_addr, int port)
{
tcp_info *tcp_server;
int yes = 1;

if (ip_addr == NULL)
{
return NULL;
}

if ((tcp_server = calloc(1, sizeof(tcp_info))) == NULL)
{
return NULL;
}

tcp_server->socket_address.sin_port = htons(port);
tcp_server->socket_address.sin_family = AF_INET;
inet_pton(AF_INET, ip_addr, &(tcp_server->socket_address.sin_addr));

if ((tcp_server->fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
printf("[ERROR] Failed to create socket!\n");
return NULL;
}

if (setsockopt(tcp_server->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
{
perror("Set socket option failed");
close(tcp_server->fd);
return NULL;
}

if (bind(tcp_server->fd, (const struct sockaddr *)&tcp_server->socket_address, sizeof(tcp_server->socket_address)) == -1)
{
printf("[ERROR] Failed to bind socket!\n");
close(tcp_server->fd);
return NULL;
}

if (listen(tcp_server->fd, BACK_LOG) == -1)
{
printf("[ERROR] Failed to listen!\n");
close(tcp_server->fd);
return NULL;
}

return tcp_server;
}

int serial_open_port(const char *serial_port)
{
int serial_fd = -1;
struct termios tty = {0};

if (serial_port == NULL)
{
return -1;
}

if ((serial_fd = open(serial_port, O_RDWR | O_NOCTTY | O_SYNC | O_NDELAY)) == -1)
{
return -1;
}

if (tcgetattr(serial_fd, &tty) != 0)
{
perror("Error from tcgetattr");
close(serial_fd);
return -1;
}

cfsetospeed(&tty, B921600);
cfsetispeed(&tty, B921600);

tty.c_cflag = (tty.c_cflag &  ~CSIZE) | CS8;
tty.c_iflag &= ~IGNBRK;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cflag &= ~(PARENB | PARODD);
tty.c_cflag &= ~CSTOPB;
tty.c_cflag |= CRTSCTS;

if (tcsetattr(serial_fd, TCSANOW, &tty) != 0)
{
perror("Error from tcsetattr");
close(serial_fd);
return -1;
}

return serial_fd;
}

// receiving buffer
int get_serial_input_buffer_size(int fd)
{
int bytes_available = -1;

if (ioctl(fd, TIOCINQ, &bytes_available) == -1)
{
perror("ioctl TIOCINQ error");
return -1;
}

return bytes_available;
}

// sending buffer
int get_serial_output_buffer_size(int fd)
{
int bytes_available = -1;

if (ioctl(fd, TIOCOUTQ, &bytes_available) == -1)
{
perror("ioctl TIOCOUTQ error");
return -1;
}

return bytes_available;
}

int main(int argc, char *argv[])
{
if (argc != 4)
{
printf("Usage: %s  
 \n", argv[0]);
return EXIT_FAILURE;
}

/* Server configuration */
const char *server_address = argv[1];
int port = atoi(argv[2]);
const char *serial_port = argv[3];

/* Define variables */
tcp_info *tcp_server;
sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
char socket_buffer[BUFFER_SIZE] = {0};
char serial_buffer[SERIAL_BUFFER_SIZE] = {0};
bool enable_write = true;

int client_fd = -1;
int serial_fd = -1;
int serial_written = 0;
int serial_offset = 0;

if ((tcp_server = tcp_create_server(server_address, port)) == NULL)
{
perror("[ERROR] failed to create TCP server");
return EXIT_FAILURE;
}

if ((serial_fd = serial_open_port(serial_port)) == -1)
{
perror("[ERROR] failed to open serial");
tcp_destroy_server(tcp_server);
return EXIT_FAILURE;
}

printf("[INFO] Server waiting for connections.........\n");
memset(&client_addr, 0, sizeof(client_addr));

if ((client_fd = accept(tcp_server->fd, (struct sockaddr *)&client_addr, &client_addr_len)) == -1)
{
perror("[ERROR] Failed to aceept a new socket connection");
tcp_destroy_server(tcp_server);
return EXIT_FAILURE;
}

printf("[INFO] Accept a connection from tcp \n");

fd_set read_fds;
fcntl(client_fd, F_SETFL, O_NONBLOCK);

while (1)
{
FD_ZERO(&read_fds);
FD_SET(client_fd, &read_fds);
FD_SET(serial_fd, &read_fds);

if (select(MAX(serial_fd, client_fd) + 1, &read_fds, NULL, NULL, NULL) == -1)
{
perror("select() error");
break;
}

/* Read data from socket , then writing to the serial port */
if (enable_write && FD_ISSET(client_fd, &read_fds))
{
int valread = recv(client_fd, socket_buffer, BUFFER_SIZE, 0);

if (valread = 23000)
{
enable_write = false;  // stop writing data to serial
}
else if (val 

Подробнее здесь: [url]https://stackoverflow.com/questions/78803174/how-to-increase-tcp-server-serves-a-serial-port-over-tcp-throughput[/url]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Linux»