Поток TCP Возврат 255 байтов Только [дубликат]

Вы также можете использовать

DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);

, чтобы убедиться, что у вас есть конечные 0.

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

10 ответов

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

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

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

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

13
ответ дан Eugene Yokota 22 August 2018 в 20:41
поделиться
  • 1
    Или вы можете сделать так, как это делает SMTP, и включить строку терминатора (на собственной строке) – badbod99 26 October 2009 в 10:28

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

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

3
ответ дан Alex Martelli 22 August 2018 в 20:41
поделиться

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

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

-1
ответ дан Andrew Hare 22 August 2018 в 20:41
поделиться
  • 1
    по "размеру пакета" вы имеете в виду, например, предел IPv4 до 65,507 байт? – user 26 October 2009 в 06:22
  • 2
    Извините, я имел в виду MTU - я отредактировал свой ответ, чтобы отразить это. – Andrew Hare 26 October 2009 в 06:23
  • 3
    TCP гарантирует успешную доставку данных, но не пакетов - см. Мой ответ о повторной передаче. – Zepplock 26 October 2009 в 06:24

Это зависит от установленного MTU (Maximum transfer unit). Если ваше установившееся соединение (однажды рукопожатие) относится к MTU размером 512 байт, вам понадобятся два или более TCP-пакетов для отправки 1000 байт.

-1
ответ дан backslash17 22 August 2018 в 20:41
поделиться

Единственное, что гарантирует уровень TCP, заключается в том, что получатель получит:

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

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

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

0
ответ дан Greg Hewgill 22 August 2018 в 20:41
поделиться

В своем сообщении вы определяете, сколько байтов должно содержать ваше сообщение. Например, в вашем случае это 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
ответ дан KMån 22 August 2018 в 20:41
поделиться

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

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

0
ответ дан Matthew Scharley 22 August 2018 в 20:41
поделиться
  • 1
    @Matthew Scharley, с точки зрения TCP-клиента, TCP гарантирует, что он поставляет дейтаграмму в порядок. В основе IP не так, чтобы он мог переупорядочить их, но это внутренние детали TCP. – Eugene Yokota 26 October 2009 в 06:35
  • 2
    Так что это пакеты. Но ОП беспокоит их. Вы правы, и я был в восторге от этого, сказав, что принятое приложение всегда будет получать их в порядке. Но они не обязательно доставляются на компьютер в порядке. – Matthew Scharley 26 October 2009 в 07:14

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

2
ответ дан Randai 22 August 2018 в 20:41
поделиться

Да, есть возможность для получения пакетов по частям. Надеюсь, что эта статья 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
ответ дан Vadakkumpadath 22 August 2018 в 20:41
поделиться

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

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

-1
ответ дан Zepplock 22 August 2018 в 20:41
поделиться
Другие вопросы по тегам:

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