Вопрос сокета TCP - PullRequest
       6

Вопрос сокета TCP

2 голосов
/ 29 января 2011

Я начинаю изучать протокол TCP из Интернета и провожу некоторые эксперименты. После того, как я прочитал статью от http://www.diffen.com/difference/TCP_vs_UDP

«TCP более надежен, так как он управляет подтверждением сообщений и повторными передачами в случае потери частей. Таким образом, абсолютно нет пропущенных данных.»

Затем я делаю свой эксперимент, я пишу блок кода с сокетом TCP:

while( ! EOF (file))
{
   data = read_from(file, 5KB); //read 5KB from file
   write(data, socket); //write data to socket to send
}

Я думаю, что это хорошо, потому что "TCP надежен" и он "ретранслирует потерянные части" ... Но это совсем не хорошо. Небольшой файл в порядке, но когда дело доходит до 2 МБ, иногда это нормально, но не всегда ...

Теперь я попробую другой:

while( ! EOF (file))
{
   wait_for_ACK();//or sleep 5 seconds
   data = read_from(file, 5KB); //read 5KB from file
   write(data, socket); //write data to socket to send
}

Теперь хорошо ...

Все, что я могу думать, это то, что 1-й сбой из-за: 1. переполнение буфера на отправителе, поскольку скорость отправки ниже, чем скорость записи программы (скорость отправки контролируется TCP) 2. Может быть, скорость отправки больше, чем скорость записи, но некоторые пакеты теряются (после некоторой повторной передачи все равно происходит сбой, а затем TCP сдается ...)

Есть идеи? Спасибо.

Ответы [ 2 ]

5 голосов
/ 29 января 2011

TCP гарантирует, что вы не потеряете данные, но вы должны проверить, сколько байтов фактически было принято для передачи ... типичный цикл -

while (size > 0)
{
    int sz = send(socket, bufptr, size, 0);
    if (sz == -1) ... whoops, error ...
    size -= sz; bufptr += sz;
}

когда вызов send принимает некоторые данные из вашей программы, тогда задача ОС - доставить их к месту назначения (включая повторную передачу), но буфер для отправки может быть меньше, чем размер, который вам нужно отправить, и это почему результирующее sz (количество байтов, принятых для передачи) может быть меньше size.

Также важно учитывать, что отправка выполняется асинхронно, т. Е. После того, как функция send возвращает данные, которых еще нет в месте назначения, они были назначены только для транспортной системы TCP для доставки. Если вы хотите знать, когда он будет получен, вам придется использовать другие системы (например, ответное сообщение от вашего партнера).

2 голосов
/ 29 января 2011

Вы должны проверить write(socket), чтобы убедиться, что он пишет то, что вы спрашиваете.Цикл пока вы не отправили все или не рассчитали время ожидания.Не используйте неопределенные тайм-ауты для чтения / записи сокетов.Вы просите неприятностей, если вы делаете, особенно в Windows.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...