В данный момент я работаю над проектом C / server / client и столкнулся со странной проблемой, решение которой заняло у меня некоторое время, но я не совсем доволен решением или, более точно, зачем мне это нужно.По сути, я обнаружил, что отправка сообщений сокета tcp более 10 Кбайт на локальный хост требует задержки в 1 мс.
В качестве фона у меня есть сервер на компьютере, к которому подключаются многие клиенты и передают информацию туда и обратно, и всеКажется, работает нормально.У меня также есть клиенты, которые являются локальными по отношению к серверу, который также подключается. Проблема, с которой я столкнулся, заключалась в том, что, когда размеры сообщений превышали ~ 10 КБ, сообщения не проходили.Я только что заметил это, потому что большинство отправленных сообщений были размером около 1-2 КБ, но клиент, подключенный к тому же компьютеру, что и сервер (localhost), является в большей степени клиентом для управления и поэтому отправляет / получает больше данных.
Настоящая проблема заключалась в том, что сервер (отправитель) возвращал истину / успех из команд отправки C # о том, что данные отправляются, однако получатель указал, что пройдет только первый чанк (если я буферизовал) или ничего не произошло.Поэтому я закончил тем, что включил wireshark и увидел, что, хотя отправка вызовов завершена успешно, никакие данные на самом деле не будут отправляться по проводной связи (помня об этом на локальном интерфейсе обратной связи).отправляю данные и пробую все разные вызовы (NetworkStream.Write / NetworkStream.WriteAsync / Socket.Send / Socket.SendAsync / Socket.BeginSend
) вместе с буферизацией данных или отправляю их все одним нажатием.Казалось, ничто не имеет значения, пока я не установлю задержку между вызовами отправки в цикле, тогда все будет работать идеально (я протестировал до 1,5 ГБ потока данных без проблем).
Я также нашел задержкучто-то меньше 1 мс / 10000 тиков снова вызовет проблемы, я получу так много звонков на работу, что они просто остановятся снова.Установка TcpClient.NoDelay
в true также, похоже, не оказала большого влияния.
Ниже приведен фрагмент моего кода отправки в качестве примера с различными командами отправки, которые я пробовал, что все они имеют одинаковое поведение.
// _client is an abstracted/based off a TcpClient object (the target)
byte[] dataBytes = Serializer.SerializeMessage(message);
int bytesSent = 0;
while (bytesSent < dataBytes.Length) {
int bytesToSend = ((dataBytes.Length - bytesSent) < 8192) ? (dataBytes.Length - bytesSent) : 8192;
//_client.Socket.Send(dataBytes, bytesSent, bytesToSend, SocketFlags.Partial);
//_client.NetworkStream.Write(dataBytes, bytesSent, bytesToSend);
//_client.Socket.BeginSend(dataBytes, bytesSent,bytesToSend,SocketFlags.None, ar => {int bytes = ((Socket)ar.AsyncState).EndSend(ar);}, _client.Socket);
_ = _client.NetworkStream.WriteAsync(dataBytes, bytesSent, bytesToSend);
bytesSent += bytesToSend;
Thread.Sleep(TimeSpan.FromTicks(10000));
}
Так что, хотя сейчас это работает нормально, мой вопрос - зачем это вообще нужно, из предыдущего опыта я всегда нахожу, что если вам нужно «отложить», есть что-то еще, что не так.Кроме того, без задержки ничего не выводится, во всех отчетах о вызовах они успешно отправили байты, но wireshark не показывает передаваемых данных.Я думал только о том, что в библиотеке что-то обнаружит, что это локальная цель, и использует какой-то внутренний по имени абстрагированный от меня канал и где-то заполнится буфер?
Я пытался искать любую проблему, подобную этой, более неделии не мог найти ничего очевидного, поэтому любая оценка будет принята с благодарностью.