Я сейчас тестирую управляемую сетевую библиотеку c #, которую написал, и столкнулся со случайной проблемой.Эта проблема проявляется в очень согласованном (всегда в пределах 30 мс) блоке 5000 мс в networkstream.write () для, возможно, 1% всех операций отправки.Это тестовая среда, все работают локально, каждый раз используя один и тот же размер пакета (2 МБ).На стороне клиента я непрерывно записываю следующее в подключенный сетевой поток:
tcpClientNetworkStream.Write(headerBytes, 0, headerBytes.Length);
tcpClientNetworkStream.Write(dataBytes, 0, dataBytes.Length);
, а на стороне сервера я использую асинхронное чтение в ожидании данных.Как только данные появляются, я использую цикл while над tcpClientNetworkStream.DataAvailable, пока все данные не будут получены.
Мне известно, что networkstream.write () может блокироваться, если буферы заполнены, но если это проблема, я не могу придумать более быстрый способ их очистки на стороне сервера (размеры буфера отправки и получения)по умолчанию на 8192 байта).Тот факт, что блок настолько последовательный, кажется очень странным.Моей первой мыслью была, возможно, какая-то форма Thread.Sleep, но полный поиск по проекту ничего не показал.Если бы кто-то мог помочь пролить свет на эту проблему, это было бы очень полезно.
Marc
отредактировать, чтобы добавить: Хак, который, кажется, устраняет проблему, заключается в следующем (хотя естьсвязанное снижение производительности из-за BlockCopy):
byte[] bytesToSend = new byte[headerBytes.Length + dataBytes.Length];
Buffer.BlockCopy(headerBytes, 0, bytesToSend, 0, headerBytes.Length);
Buffer.BlockCopy(dataBytes, 0, bytesToSend, headerBytes.Length, dataBytes.Length);
tcpClientNetworkStream.Write(bytesToSend, 0, bytesToSend.Length);
edit to add2: я также воспроизвел проблему, используя две асинхронные записи с сигналом потока между ними.На данный момент единственное решение, которое у меня есть, это одиночная операция записи, как в приведенном выше редактировании.
редактирование в add3: Хорошо, следует еще одно возможное исправление.Мне все еще интересно знать, почему последовательная запись иногда «блокирует» так, как она это делает.
BufferedStream sendStream = new BufferedStream(tcpClientNetworkStream);
sendStream.Write(bytesToSend, 0, bytesToSend.Length);
sendStream.Write(packet.PacketData, 0, packet.PacketData.Length);
sendStream.Flush();
edit to add4: После дальнейшего обширного тестирования решение «edit to add3» не делаетпроблема исчезнет, это только уменьшает количество случаев отправки примерно до 0,1%.Гораздо лучше, но далеко не решено.Я заменим асинхронное чтение на блокирующее чтение, чтобы посмотреть, сортирует ли оно это, как это было предложено PaulF.