У меня есть очень простое TCP-клиент/серверное приложение, написанное на C.
Полный код этого проекта доступен на github.
Клиентская сторона запускает несколько параллельных потоков, каждый из которых нити сделайте следующее:
откройте сокет
подключите этот сокет к серверу
записать в сокет 16 байт предопределенного шаблона данных кусками случайной длины
Общий размер отправленных данных из сокета было прочитано соответственно менее 16 байт.
image1
Такое поведение повторяется как на локальном хосте, так и на через реальное сетевое соединение.
Изучение TCP-потока поврежденных данных с помощью Wireshark показывает, что:
На клиенте проблем нет сторона.
Поврежденные данные соответствуют данным, которые передаются вместе с повторно переданными сегментами данных.
image2Я не могу поверить, что эта проблема связана с реализацией TCP/IP в Linux.
Может ли кто-нибудь объяснить, что не так с моим кодом?
У меня есть очень простое TCP-клиент/серверное приложение, написанное на C. Полный код этого проекта доступен на github. Клиентская сторона запускает несколько параллельных потоков, каждый из которых нити сделайте следующее: [list] [*]откройте сокет [*]подключите этот сокет к серверу [*]записать в сокет 16 байт предопределенного шаблона данных кусками случайной длины [*]закрыть сокет [*]повторить шаги с 1 по 4 N раз [/list] [code]static size_t send_ex(int fd, const uint8_t *buff, size_t len, bool by_frags) { if ( by_frags ) { size_t chunk_len, pos; size_t res;
for ( i = 0; i < count; i++ ) { fd = socket(AF_INET, SOCK_STREAM, 0); if ( fd < 0 ) { fprintf(stderr, "Can't create socket!\n"); break; }
res = connect(fd, (struct sockaddr *) ctx->serveraddr, sizeof(struct sockaddr_in)); if ( res < 0 ) { fprintf(stderr, "Connect failed!\n"); close(fd); break; }
res = send_ex(fd, (const char *) buff, sizeof(buff), frags); if ( res != sizeof(buff) ) { fprintf(stderr, "Send failed!\n"); close(fd); break; }
ctx->sent_packs++;
res = close(fd); if ( res < 0 ) { fprintf(stderr, "CLI: Close Failed!!\n"); }
msleep(delay); }
return NULL; }
[/code] Запуск потока на стороне сервера при каждом входящем соединении, который выполняет следующие действия: [list] считывает данные из подключенного сокета, пока не будут прочитаны все 16 байт [*]после чтения хотя бы первых 4 байтов проверяется, что эти байты соответствуют заданному шаблону. [/list] [code]typedef struct client_ctx_s { struct sockaddr_in addr; int fd; } client_ctx_t;
out: debug("Connection closed\n"); res = close(client->fd); assert(res == 0); free(client); return NULL; } [/code] Проблемы, возникающие, когда клиент запускает тысячу потоков отправки, и каждый из них повторяет соединение-отправку-отключение сто раз ([code]./client -t 1000 -c 100 -d 0 -f[/code]): [list] [*]Потеря первых байтов отправленного шаблона. [*]Общий размер отправленных данных из сокета было прочитано соответственно менее 16 байт. [/list] image1 Такое поведение повторяется как на локальном хосте, так и на через реальное сетевое соединение. Изучение TCP-потока поврежденных данных с помощью Wireshark показывает, что: [list] [*]На клиенте проблем нет сторона. [*]Поврежденные данные соответствуют данным, которые передаются вместе с повторно переданными сегментами данных. [/list] image2Я не могу поверить, что эта проблема связана с реализацией TCP/IP в Linux. Может ли кто-нибудь объяснить, что не так с моим кодом?
В Linux, если я создаю два потока, один для отправки данных TCP и один для получения данных TCP для одного и того же неблокирующего сокета, это потокобезопасно?
или мне следует использовать синхронизацию использование мьютекса.
Я использую C++ для...
Я написал код Python, который использует Curl, получает time_download и некоторую другую информацию о конкретных веб-сайтах и помещает их в индекс в Elasticsearch. Объем данных, с которыми я имею дело, огромен. Приложение вылетело из строя и...
У меня есть TCP-сокет, по которому я получаю видеопоток. Я хочу получать данные в виде пакета за пакетом из сокета, чтобы можно было удалить заголовок пакета и сохранить только потоковые данные. Как я могу это сделать??
Любая помощь будет оценена по...
У меня есть консольное приложение в виде серверного сокета, которое передает сообщения всем подключенным клиентам, а также консольные приложения, где иногда, когда один клиент отключается, серверный процесс аварийно завершает работу, даже не вызывая...