Socket.EndReceive рабочий процесс - PullRequest
0 голосов
/ 13 января 2019

На сайте Microsoft вы можете найти этот код для ReadCallback(IAsyncResult)

static void ReadCallback(IAsyncResult ar)
{
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    int read = handler.EndReceive(ar);

    if(read > 0)
    {
        state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, read));
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
    }
    else
    {
        if(state.sb.Length > 1)
        {
            string content = state.sb.ToString();

            Console.WriteLine($"Read {content.Length} bytes from socket. \nData: {content}");
        }
        handler.Close();
    }
}

Что мне неясно, так это if/else утверждение. Почему мы снова BeginReceive, если уже что-то читаем?

Почему бы нам просто не сделать

static void ReadCallback(IAsyncResult ar)
{
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    int read = handler.EndReceive(ar);

    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, read));

    if(state.sb.Length > 1)
    {
        string content = state.sb.ToString();

        Console.WriteLine($"Read {content.Length} bytes from socket. \nData: {content}");
    }
    handler.Close();
}

1 Ответ

0 голосов
/ 13 января 2019

В основном, потому что частичные сообщения - это вещь.

Если, например, вы отправляете 1000 байтов, то первый получатель может фактически получить только 30. Затем следующий получает 70, следующий получает 100, затем 50, затем 150 и т. Д., Пока не будут получены все 1000 байтов (очевидно, цифры будут выше с современными сетями). Вот почему большинство TCP-сообщений имеют какой-либо маркер конца или имеют префикс с размером: чтобы вы знали, когда они завершены.

Просто помните: даже если вы запрашиваете 100 байтов, EndReceive даст вам до такого количества байтов. Это не обязательно ждать, пока у них есть все.

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