Получение данных в TCP

Предварительная бета-версия поддерживает программы VB6, но это может ничего не значить в терминах розничной версии.

Среда IDE поддерживалась в первоначальном выпуске Vista, но, как указано выше, срок «поддержки» истек.

Все сводится к тому, что вы подразумеваете под «поддержкой» в разных контекстах, но программы работают на бета-версии Win7, и люди утверждают, что IDE также может работать там (хотя я сам не проверял это).

6
задан 26 October 2009 в 05:28
поделиться

10 ответов

См. Протокол управления передачей :

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

«Поток» означает, что нет границы сообщения с точки зрения получателя. Вы можете получить одно 1000-байтовое сообщение или тысячу 1-байтовых сообщений в зависимости от того, что находится под ним и как часто вы вызываете чтение / выбор.

Изменить : Позвольте мне уточнить с точки зрения приложения. Нет, TCP не гарантирует, что при однократном чтении вы получите все пакеты размером 1000 байт (или 1 МБ, или 1 ГБ), которые отправил отправитель. Таким образом, протокол выше TCP обычно содержит заголовок фиксированной длины с общей длиной содержимого в нем.

13
ответ дан 8 December 2019 в 13:00
поделиться

Как указано в других ответах, TCP является протоколом потока - каждый отправленный байт будет получен (один раз и в том же порядке), но нет внутреннего "сообщения" границы »- независимо от того, отправляются ли все байты в одном вызове .send или в нескольких, они все равно могут быть получены в одном или нескольких вызовах .receive .

Итак, если вам нужны «границы сообщений», вы должны наложить их поверх потока TCP, по сути, IOW на уровне приложения. Например, если вы знаете, что отправляемые вами байты никогда не будут содержать \ 0 , строки с завершающим нулем работают нормально; различные методы «экранирования» позволяют отправлять строки байтов, которые не подчиняются таким ограничениям.

3
ответ дан 8 December 2019 в 13:00
поделиться

В основном, что касается TCP, он гарантирует только то, что данные, отправленные с одного конца на другой, будут отправлены в том же порядке. Обычно вам нужно иметь внутренний буфер, который продолжает цикл до тех пор, пока не получит ваш 1000-байтовый «пакет». Поскольку упомянутая команда recv возвращает, сколько фактически было получено. Поэтому обычно вам придется реализовать протокол поверх TCP, чтобы убедиться, что вы отправляете данные с соответствующей скоростью. Потому что, если вы отправите () все данные за один проход, это приведет к перегрузке нижележащего сетевого стека, что вызовет осложнения. Поэтому обычно в протоколе есть крошечный пакет подтверждения, отправляемый обратно, чтобы подтвердить, что пакет размером 1000 байт отправлен.

2
ответ дан 8 December 2019 в 13:00
поделиться

В своем сообщении вы решаете, сколько байтов должно содержать ваше сообщение. Например, в вашем случае это 1000. Ниже приведен код C # для достижения того же. Метод возвращает 1000 байтов. Код прерывания - 0 байт; вы можете настроить это в соответствии с вашими потребностями.

Использование:

strMsg = ReadData(thisTcpClient.Client, 1000, out bDisconnected);

Ниже приведен метод:

    string ReadData(Socket sckClient, int nBytesToRead, out bool bShouldDisconnect)
    {
        bShouldDisconnect = false;

        byte[] byteBuffer = new byte[nBytesToRead];
        Array.Clear(byteBuffer, 0, byteBuffer.Length);

        int nDataRead = 0;
        int nStartIndex = 0;

        while (nDataRead < nBytesToRead)
        {

            int nBytesRead = sckClient.Receive(byteBuffer, nStartIndex, nBytesToRead - nStartIndex, SocketFlags.None);

            if (0 == nBytesRead)
            {
                bShouldDisconnect = true;
                //0 bytes received; assuming disconnect signal
                break;
            }

            nDataRead += nBytesRead;
            nStartIndex += nBytesRead;
        }

        return Encoding.Default.GetString(byteBuffer, 0, nDataRead);
    }

Сообщите нам, что это вам не помогло (0: Удачи.

2
ответ дан 8 December 2019 в 13:00
поделиться

Да, есть вероятность получения пакетов по частям. Надеюсь, эта статья msdn и следующий пример (взяты из статьи в msdn для быстрого ознакомления) будут полезны вам, если вы используете сокеты Windows.

void CChatSocket::OnReceive(int nErrorCode)
{
   CSocket::OnReceive(nErrorCode);

   DWORD dwReceived;

   if (IOCtl(FIONREAD, &dwReceived))
   {
      if (dwReceived >= dwExpected)   // Process only if you have enough data
         m_pDoc->ProcessPendingRead();
   }
   else
   {
      // Error handling here
   }
}
1
ответ дан 8 December 2019 в 13:00
поделиться

TCP гарантирует, что они получат все 1000 байт, но не обязательно по порядку (хотя для принимающего приложения так будет выглядеть) и не обязательно все сразу (если вы не создадите пакет самостоятельно

Тем не менее, для пакета размером всего 1000 байт велика вероятность, что он будет отправлен одним пакетом, если вы сделаете это за один вызов send ], хотя для больших передач это может быть не так.

0
ответ дан 8 December 2019 в 13:00
поделиться

Единственное, что гарантирует уровень TCP, это то, что получатель получит:

  • все байты, переданные отправителем
  • в том же порядке

Нет никаких гарантий на все о том, как байты могут быть разделены на «пакеты». Все, что вы могли прочитать о MTU, фрагментации пакетов, максимальном размере сегмента и т. Д., Находится ниже уровня сокетов TCP и не имеет значения. TCP предоставляет потоковую службу только .

Что касается вашего вопроса, это означает, что получатель может получить первые 500 байтов, а затем следующие 500 байтов. Или получатель может получать данные по одному байту за раз, если это то, что он запрашивает. Это причина того, что функция recv () принимает параметр, который сообщает ей, сколько данных возвращает ,

0
ответ дан 8 December 2019 в 13:00
поделиться

IP-пакеты могут фрагментироваться во время повторной передачи.

Таким образом, конечная машина может получить несколько пакетов, которые будут повторно собраны стеком TCP / IP. В зависимости от сетевого API, который вы используете, данные будут предоставлены , вы либо повторно соберете, либо в пакетах RAW.

-1
ответ дан 8 December 2019 в 13:00
поделиться

Протокол управления передачей гарантирует успешную доставку всех пакетов, требуя подтверждения от получателя успешной доставки каждого пакета отправителю. Согласно этому определению, получатель всегда будет получать полезную нагрузку кусками, если размер полезной нагрузки превышает MTU (максимальная единица передачи) .

Для получения дополнительной информации прочтите Протокол управления передачей .

-1
ответ дан 8 December 2019 в 13:00
поделиться

Зависит от установленного MTU (максимальной единицы передачи). Если ваше стабильное соединение (после установления связи) относится к MTU в 512 байт, вам потребуется два или более TCP-пакетов для отправки 1000 байт.

-1
ответ дан 8 December 2019 в 13:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: