Сериализация сокета C # - PullRequest
0 голосов
/ 25 октября 2010

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

  1. Сериализация / десериализация сокета путем чтения и записи через указатель на объект в памяти. Я не могу восстановить сокет после сериализации.

  2. Используйте метод Socket.DuplicateAndClose (), чтобы получить SocketInformation, затем сериализовать его и при необходимости восстановить сокет для того же процесса, используя SocketInformation. Кажется, я не могу использовать сокет после его восстановления, и я не уверен, что это приведет к значительной экономии памяти, так как кажется, что неуправляемые ресурсы остаются в памяти.

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

Любая помощь очень ценится!

Ответы [ 3 ]

8 голосов
/ 25 октября 2010

Это звучит как хорошее продолжение «Приключений Алисы в стране чудес» - чудесное бессмысленное.Вы не можете сериализовать сокет, потому что это просто не имеет смысла.Класс «сокет» (я имею в виду не класс .NET Socket, а тип объектов, которые называются сокетами) не поддерживает операцию «сериализации», потому что сокеты (если мы думаем в объектах реального мира) не контейнеры данных, а воротаканал связи.Вы можете сделать копию книги, но будет очень трудно сделать бумажную копию двери.

Теперь о памяти.У вас может быть около 64 КБ сокетов в вашей системе Windows (я могу ошибаться с точным числом, но это примерно так).Даже при 100 байтах на сокет вы будете занимать всего 6 Мб памяти.В современных серверных ОС (Windows, Linux, как вы это называете) 6 Мб памяти пользовательского режима - это меньше, чем ничего.Вы получите гораздо больше, если пересмотрите общую архитектуру приложения.

1 голос
/ 25 октября 2010

Если я правильно понял вопрос, вы пытаетесь сериализовать объект Socket, сохраняя его информацию (содержимое объекта), а затем пытаетесь восстановить этот объект с сохраненной информацией.

Это не сработает, потому что вы не можете просто сохранить содержимое объекта Socket и восстановить его позже. В глубине сокета используется фактический обработчик сокета (дескриптор открытого файла) из операционной системы. Сохранение и восстановление этих данных не приведет к повторному подключению фактического дескриптора устройства в операционной системе.

Сокет требует физического подключения (открытия) на уровне операционной системы. Это похоже на объект Stream. Вы не можете просто сохранить содержимое объекта и восстановить его позже; для этого требуется вложение в дескриптор файла в операционной системе.

0 голосов
/ 25 октября 2010

Ваши розетки не проблема. Они используют очень мало памяти. Скорее, проблема заключается в том, как вы относитесь к входящим и исходящим данным

Вы выделяете новые (байтовые) буферы для каждой операции?

Вместо этого создайте пул буферов. Позвольте пулу создать новый буфер, если он пуст. Не забудьте вернуть буфер, когда закончите.

Что вы делаете, когда получаете данные в буфер?

Вы строите строку? Если у вас много входящих данных или больших строк, вы можете переключиться на StringBuilder. string.Format ("{0} kdkd {1} jdjd {2}", var1, var2, var3) выделяет меньше памяти, чем var1 + "kdkd" + var2 + "jdjd" + var3 .

Как вы оборачиваете сокет?

У вас есть толстый класс с большим количеством вещей в нем? Тогда проблема в вашем жирном классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...