Ваш код очень неправильный.Подобные циклы противоречат цели асинхронного программирования.Асинхронный ввод-вывод используется, чтобы не блокировать поток, а позволить им продолжать выполнять другую работу.Зацикливаясь таким образом, вы блокируете поток.
void StartListening()
{
_listener.BeginAccept(OnAccept, null);
}
void OnAccept(IAsyncResult res)
{
var clientSocket = listener.EndAccept(res);
//begin accepting again
_listener.BeginAccept(OnAccept, null);
clientSocket.BeginReceive(xxxxxx, OnRead, clientSocket);
}
void OnReceive(IAsyncResult res)
{
var socket = (Socket)res.Asyncstate;
var bytesRead = socket.EndReceive(res);
socket.BeginReceive(xxxxx, OnReceive, socket);
//handle buffer here.
}
Обратите внимание, что я удалил всю обработку ошибок, чтобы сделать код чище.Этот код не блокирует какой-либо поток и поэтому намного эффективнее.Я бы разбил код на два класса: серверный код и клиентский код.Это упрощает поддержку и расширение.
Следующее, что нужно понять, это то, что TCP является потоковым протоколом.Не гарантируется, что сообщение поступит за один прием.Поэтому вы должны знать, каков размер сообщения, или когда оно заканчивается.
Первое решение состоит в том, чтобы поставить перед каждым сообщением префикс заголовка, который вы сначала анализируете, а затем продолжить чтение, пока не получите полное тело / сообщение.
Второе решение состоит в том, чтобы поместить некоторый управляющий символ в конец каждого сообщения и продолжить чтение, пока не будет прочитан управляющий символ.Помните, что вы должны закодировать этот символ, если он может существовать в реальном сообщении.