EndReceive в Async Socket без строк - PullRequest
       60

EndReceive в Async Socket без строк

0 голосов
/ 05 ноября 2019

Я следую этому примеру о создании асинхронного tcp-слушателя в C #. MSDN Пример

Я вижу, что все данные кодируются в виде строки для проверки полноты сообщения. Точнее, каждое отправленное сообщение уже является строкой, к которой мы добавляем символ 'EOF' для завершения строки.

Серверная часть, о которой я говорю, находится в следующем фрагменте:

public static void ReadCallback(IAsyncResult ar) {  
    String content = String.Empty;  

    // Retrieve the state object and the handler socket  
    // from the asynchronous state object.  
    StateObject state = (StateObject) ar.AsyncState;  
    Socket handler = state.workSocket;  

    // Read data from the client socket.   
    int bytesRead = handler.EndReceive(ar);  

    if (bytesRead > 0) {  
        // There  might be more data, so store the data received so far.  
        state.sb.Append(Encoding.ASCII.GetString(  
            state.buffer, 0, bytesRead));  

        // Check for end-of-file tag. If it is not there, read   
        // more data.  
        content = state.sb.ToString();  
        if (content.IndexOf("<EOF>") > -1) {  
            // All the data has been read from the   
            // client. Display it on the console.  
            Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",  
                content.Length, content );  
            // Echo the data back to the client.  
            Send(handler, content);  
        } else {  
            // Not all data received. Get more.  
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,  
            new AsyncCallback(ReadCallback), state);  
        }  
    }  
}  

Есть ли способ, как я обычно делаю с классами TcpListener / TcpClient, проверить, доступны ли полученные байты в сокете?

Я имею в виду что-то вроде этого:

    private void HandleClientConnection(TcpClient client)
    {
        NetworkStream clientStream = client.GetStream();

        MemoryStream memoryStream = new MemoryStream();

        while (true)
        {
            int read = clientStream.ReadByte();

            if (read != -1)
            {
                memoryStream.WriteByte((byte)read);
            }
            else
            {
                break;
            }
        }
    }

Мне известно, что я, вероятно, неправильно понял этот пример, или, по крайней мере, часть Begin / End и "устаревший" асинхронный шаблон. Но это моя цель, знаете ли вы какой-нибудь способ заставить его работать без использования строк?

1 Ответ

0 голосов
/ 08 ноября 2019

Вы сказали: «Есть ли способ проверить, доступны ли принятые байты в сокете?»

В общем случае «EndReceive» блокирует поток до тех пор, пока данные не станут доступны. Поэтому вам не нужно ничего делать, потому что «EndReceive» выполняет всю работу за вас.

«bytesRead» - это int, который показывает вам, сколько данных вы получили.

aцитата из docs.microsoft

Метод EndReceive будет блокироваться до тех пор, пока данные не станут доступны. 1

Но если вы используете сокет SYNC (которыйэто не так) тогда это другая тема.

...