BeginReceive/SocketAsyncEventArgs список ArraySegments

В чем причина передачи списка ArraySegment<byte> в Socket.BeginReceive / SocketAsyncEventArgs?

MSDN для Socket.BeginReceive конструктор даже не правильно описывает первый аргумент):

public IAsyncResult BeginReceive(
    IList<ArraySegment<byte>> buffers,
    SocketFlags socketFlags,
    AsyncCallback callback,
    object state
)

: параметры при
буферы
Тип: System.Collections.Generic.IList<ArraySegment<Byte>>
Массив типа Byte это место хранения полученных данных.
...

Я подумал, что основной идеей было выделить большой буфер в куче больших объектов, а затем передать сегмент этого буфера Socket.BeginReceive, чтобы не приколоть маленькие предметы вокруг кучи и не испортить работу GC.

Но почему я должен хотеть передать несколько сегментов этим методам? В случае SocketAsyncEventArgs Похоже, это усложнит объединение этих объектов, и я не вижу причины этого.

1 ответ

Решение

Что я узнал в этом вопросе и в MSDN:

  1. Есть перегруженная версия BeginReceive это занимает байтовый массив. Когда он заполнен или пакет получен (логически по порядку), выполняется обратный вызов.

  2. Как указано в ответе, я связал:

Чтения могут быть кратны этому, потому что, если пакеты поступают не по порядку, все они становятся видимыми для приложения в момент поступления логически первого из них. В этом случае вы можете одновременно читать все смежные пакеты в очереди.

Это означает: если есть входящий пакет, который не в порядке (то есть с более высоким порядковым номером, чем ожидаемый), он будет сохранен обратно. Как только пропущенный пакет прибыл, все доступные пакеты записываются в ваш список и запускается только один обратный вызов вместо того, чтобы вызывать обратный вызов снова и снова для всех пакетов, уже доступных, каждый заполняя ваш буфер настолько, насколько это возможно, и так далее.,

Таким образом, это означает, что эта реализация экономит много накладных расходов, предоставляя все доступные пакеты в списке массивов, вызывая обратный вызов только один раз, вместо того, чтобы делать много memcopies из сетевого стека в ваш буфер и многократно вызывать вас обратным вызовом.

Другие вопросы по тегам