Я пишу клиент-серверное приложение на C #, и все идет отлично. На данный момент все работает, и все это довольно надежно. Моя проблема в том, что у меня возникают некоторые задержки при отправке пакетов по соединению.
На стороне клиента я делаю это:
NetworkStream ns = tcpClient.GetStream();
// Send packet
byte[] sizePacket = BitConverter.GetBytes(request.Length);
byte[] requestWithHeader = new byte[sizePacket.Length + request.Length];
sizePacket.CopyTo(requestWithHeader, 0);
request.CopyTo(requestWithHeader, sizePacket.Length);
ns.Write(requestWithHeader, 0, requestWithHeader.Length);
// Receive response
ns.Read(sizePacket, 0, sizePacket.Length);
int responseLength = BitConverter.ToInt32(sizePacket, 0);
byte[] response = new byte[responseLength];
int bytesReceived = 0;
while (bytesReceived < responseLength)
{
int bytesRead = ns.Read(response, bytesReceived, responseLength - bytesReceived);
bytesReceived += bytesRead;
}
(Не обращая внимания на перехват исключений и т. Д.) Сервер делает обратное, то есть блокирует NetworkStream.Read () до тех пор, пока не получит полный запрос, затем обрабатывает его и отправляет ответ с помощью Write ().
Необработанная скорость записи () / чтения () не является проблемой (т. Е. Отправка больших пакетов происходит быстро), но отправка нескольких небольших пакетов, один за другим, без закрытия соединения, может быть очень медленной (задержки 50-100 мс). Странно то, что эти задержки обнаруживаются при подключении к локальной сети с типичным временем пинга <1 мс, но они не происходят, если сервер работает на локальном хосте, даже если время пинга будет фактически одинаковым (по крайней мере, разница не должна быть порядка 100 мс). Это имело бы смысл для меня, если бы я повторно открывал соединение для каждого пакета, вызывая много рукопожатий, но я не. Это как если бы сервер, переходящий в состояние ожидания, выбрасывает его из синхронизации с клиентом, а затем немного спотыкается, восстанавливая то, что по сути является потерянным соединением. </p>
Итак, я делаю это неправильно? Есть ли способ синхронизировать соединение между TcpServer и TcpClient, чтобы сервер всегда был готов к приему данных? (И наоборот: иногда обработка запроса от клиента занимает несколько мс, а затем клиент, похоже, не готов получить ответ от сервера, пока у него не будет несколько минут для пробуждения после блокировки на Read () .)