Хорошо, вот что я в итоге сделал. Я создал поток чтения, который создает NetworkStream и StreamReader на основе сетевого потока. Затем я использую StreamReader.ReadLine для чтения строк таким образом. Это синхронный вызов, но он находится в своем собственном потоке. Кажется, работает намного лучше. Я должен был реализовать это, так как это наш протокол для приложения (сообщения с разделителями новой строки). Я знаю, что другие люди будут чертовски искать ответ, как я, вот соответствующий код чтения в моем классе клиента:
ду искал примеры того, как бороться с кадрированием сообщений TCP. Я вижу много примеров, когда NetworkStreams передаются в объект StreamReader или StreamWriter и затем используют методы ReadLine или WriteLine для сообщений с разделителями '\ n'. Мой протокол приложения содержит сообщения, оканчивающиеся на '\ n', поэтому NetworkStream, похоже, является подходящим вариантом. Тем не менее, я не могу найти конкретных примеров того, как правильно обрабатывать все это в сочетании с асинхронными сокетами. Когда ReceiveCallback () вызывается ниже, как мне реализовать классы NetworkStream и StreamReader для работы с кадрированием сообщений? Согласно тому, что я прочитал, я могу получить часть одного сообщения за один прием, а остальную часть сообщения (включая \ n) в следующем приеме. Означает ли это, что я могу получить конец одного сообщения и часть следующего сообщения? Конечно, должен быть более простой способ справиться с этим.
У меня есть следующий код:
private void StartRead(Socket socket)
{
try
{
StateObject state = new StateObject();
state.AsyncSocket = socket;
socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (SocketException)
{
m_Socket.Shutdown(SocketShutdown.Both);
Disconnect();
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
int bytes_read = state.AsyncSocket.EndReceive(ar);
char[] chars = new char[bytes_read + 1];
System.Text.Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();
int charLength = decoder.GetChars(state.Buffer, 0, bytes_read, chars, 0);
String data = new String(chars);
ParseMessage(data);
StartRead(state.AsyncSocket);
}
catch (SocketException)
{
m_Socket.Shutdown(SocketShutdown.Both);
Disconnect();
}
}