![]() |
|
Модераторы: gambit |
![]()
|
|
| Экскалупатор |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1746 Регистрация: 1.4.2009 Где: г. Минск Репутация: нет Всего: 24 |
всем привет. есть такой вопрос, который я никак не могу для себя разобрать. есть задача: программа должна сливать файлы на сервер в сети(через свою серверную часть, которая определяет куда конкретно на диске надо его сохранить). как организовать одновременную закачку файлов? что бы к примеру можно было заливать одновременно от 10 до 20 файлов по, к примеру, 100 метров каждый. или вариант одновременную закачку нескольких файлов и одновременную скачку нескольких с сервера. т.е. грубо говоря есть, к примеру, 20 пользователей в сети, и они решили "одновременно" закачать или скопировать большие файлы в/с сервера. т.е. нужно организовать что бы у всех шел процесс, пусть медленно, но шел.
интересует теория по этому вопросу, как решаются подобные проблемы, что можно почитать по этому поводу? или расскажите мне как это решить. но что бы можно было однозначно понять как решать такие вопросы. части программы между собой взаимодействуют через WCF. |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 15 Всего: 118 |
ну на каждого клиента WCF создаст по потоку в котором и будет работать отсылка\прием файлов. В чем собственно вопрос?
Конечно, это самый плохой подход, но из коробки WCF работает вроде бы только так (асинхронные сокеты там вроде бы не умеет оно) -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| Экскалупатор |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1746 Регистрация: 1.4.2009 Где: г. Минск Репутация: нет Всего: 24 |
т.е. если я правильно понял, то если первый клиент передает какой то файл(юзает соединение и порт), то сам порт при этом не закрывается и доступен для подключения других клиентов? |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 15 Всего: 118 |
а вы про TCP читали вообще стесняюсь спросить...
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| Экскалупатор |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1746 Регистрация: 1.4.2009 Где: г. Минск Репутация: нет Всего: 24 |
не надо стесняться)))) все свои.... я никогда не утверждал что знаю все, просто хочу разобраться в интересующем меня вопросе. я даже допускаю, что если написать приложение не задумываясь, положась на стандартную реализацию, то оно скорее всего будет работать, но я хочу понять как это будет происходить.
про протокол я конечно читал. но я не совсем понял как именно обрабатывается описанная мной ситуация(может не там читал...) когда сервер и клиент установили соединение(ESTABLISHED) и идет передача данных, то, как я понимаю, порт как бы занят делом и не может быть в состоянии LISTEN, т.е. ожидать другого соединения? или все же не так? или(пока что склоняюсь больше к этой точке зрения) система просто выполняет переключения между потоками данных, и таким образом создается иллюзия "одновременности" передачи данных? но фактически в один момент времени соединение только одно? |
|||
|
||||
| -Mikle- |
|
|||
![]() Невидимка Vingrad'а ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1672 Регистрация: 22.6.2003 Где: Казахстан, Астана Репутация: 1 Всего: 59 |
Не понял как вы перешли к TCP от WCF, но кое что про TCP могу пояснить.
На сервере, допустим, ты прослушиваешь на порту 45454. Когда приходит соединение на порт 45454 от клиента, сервер создает отдельный сокет на другом порту (не 45454) для этого клиента, а порт 45454 снова переходит в состояние прослушивания. Каждый сокет на сервере работает с одним клиентом. Во скольких потоках ты будешь обрабатывать коллекцию сокетов на сервере - это уже твоя проблема. Но настоятельно рекомендую не делать по одному потоку на каждый сокет, иначе все умрет нафиг при подключении хотя бы сотни клиентов. -------------------- Если тебе плюют в спину, значит ты впереди... |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 15 Всего: 118 |
-Mikle-, ну просто автор упомянул "порты" я и подумал что это явно не пайпы привязка в WCF, а, скорее всего net.tcp или что-то поверх tcp.
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| -Mikle- |
|
|||
![]() Невидимка Vingrad'а ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1672 Регистрация: 22.6.2003 Где: Казахстан, Астана Репутация: 1 Всего: 59 |
Я не про WCF говорил. Я думал вы к голым сокетам пошли договариваться. А WCF, я уверен, сам умеет распределять клиентов по потокам как надо. Может и можно как-то рулить этими вещами в WCF, но я не сталкивался, необходимости не было. Добавлено через 7 минут и 39 секунд В наших проектах мы сделали для себя один общий механизм для передачи файлов через WCF с индикацией процесса передачи файла. Успешно работает в силверлайте и легко внедряется в любой проект. Правда приходится платить ценой трафика, так как байты оборачиваются в base64+SOAP, но мы решились на это выставив размер буфера передачи побольше. Если интересно, могу на выходных описать использованную идею. -------------------- Если тебе плюют в спину, значит ты впереди... |
|||
|
||||
| Экскалупатор |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1746 Регистрация: 1.4.2009 Где: г. Минск Репутация: нет Всего: 24 |
про TCP тему завел jonie, меня интересовала именно WCF, как она обрабатывает это, теперь все стало немного понятнее. про порты я упоминал в том контексте, что WCF в оконечной точке указывается адрес и порт который надо слушать или в который стучать.
-Mikle-, про то что система создает отдельный сокет для каждого соединения не знал, это намного упрощает задачу. но как это должно выглядеть в коде? очень интересно. потому что не приходилось еще решать подобных задач. |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 15 Всего: 118 |
адрес и порт в контексте передачи данных обычно означают "TCP адрес и порт". WCF в этом случае лежит поверх TCP и вообще-то является сферическим конем в вакуме. а я вот не уверен, сильно не уверен что адаптер умеет такие вещи делать в WCF из коробки, по крайней мере в настройках такого не припомню.. -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| -Mikle- |
|
|||
![]() Невидимка Vingrad'а ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1672 Регистрация: 22.6.2003 Где: Казахстан, Астана Репутация: 1 Всего: 59 |
Ну может я и ошибаюсь, надо поискать, почитать. Просто думается мне, что WCF не будет тупо создавать по потоку на каждого клиента. По любому какой-то более менее разумный пул должен быть у него. Хотя код пишут все те же программисты, может и закосячили где-то. Надо почитать, я не интересовался этим, только предположения.
Выходные пролетели очень быстро, я забыл, что обещал тебе. Постараюсь седня вечером, после работы. В принципе там и писать особо нечего, очень простая идея, но я все равно опишу, потому что в свое время я не нашел похожего в инете. -------------------- Если тебе плюют в спину, значит ты впереди... |
|||
|
||||
| Plamenk |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 258 Регистрация: 18.2.2003 Репутация: 1 Всего: 3 |
Пул в WCF точно есть, но при условии что Вы не будете держать соединение открытым и ещё есть ряд ограничений подробнее можно посмотреть - http://rsdn.ru/article/dotnet/WCF_MultithreadClient.xml
|
|||
|
||||
| -Mikle- |
|
|||
![]() Невидимка Vingrad'а ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1672 Регистрация: 22.6.2003 Где: Казахстан, Астана Репутация: 1 Всего: 59 |
Значит так. Имеем такой контракт:
Сумари в принципе достаточно для того, чтоб понять что и как тут происходит. Идея тут в том, что сервис хранит у себя Dictionary<string, Stream>. У нас используется синглтон-менеджер для этих целей (StreamServiceManager). CreateStream контракта - добавляет новый стрим и возвращает некий идентификатор (мы используем Guid.NewGuid().ToString("N")). Все оставшиеся методы контракта работают уже соответствующим образом со стримом лежащему по соответствующему ключу. Это и есть основная идея. Далее идут уже навороты, упрощающие моим разработчикам жизнь. Так, например, у нас есть несколько контрактов-наследников от IStreamService. Один из них IBlobContainerService, содержащий еще два метода BlobContainer ReadBlob(long blobID) и long WriteBlob(BlobContainer blobInfo), которые работают с блобами в базе данных (у нас все блобы хранятся в одной простой таблице). Метод ReadBlob достает стрим из базы и ложит его в StreamServiceManager, последний в свою очередь возвращает ключ. Этот ключ и MIME-тип возвращаются клиенту в BlobContainer, а клиент дальше уже читает по кусочкам порции из соответствующего стрима. Запись блоба работает в обратном порядке, клиент вызывает CreateStream, затем по кусочкам передает на сервер и в конце вызывает WriteBlob с передачей ключа и миме-типа. Все это сохраняется в базу и клиенту отдается ID записи в базе. Со стороны клиента есть помощник - StreamServiceClient. Он собирает в себе всю логику по работе с сервисом IStreamService (не выше). Основные члены у него это события ProgressChanged, Completed, Error, методы string WriteFrom(Stream source, int bufferSize), void ReadTo(Stream destination, string streamKey, int bufferSize), несколько их перегрузок для удобных вызовов и их асинхронные аналоги (для силверлайта). Именно тут происходит деление на кусочки (по размеру буфера) и файринг событий. Вызывающей стороне достаточно вызвать только метод с передачей стрима и ловить события, если надо. Также есть еще две модели представления для аплоада и даунлоада, которые работают с StreamServiceClient. Во время загрузки\выгрузки идет оповещение о процессе выполнения (у нас в софте несколько способов информационного оповещения пользователя). Естественно, одновременно может передаваться\загружаться несколько файлов, ничего не мешает этому. Вот, в принципе, все. Полные исходные коды всего этого приложить не могу ибо права компании. Но думаю самим сделать нечто подобное, не составит никакого труда. -------------------- Если тебе плюют в спину, значит ты впереди... |
|||
|
||||
| Экскалупатор |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1746 Регистрация: 1.4.2009 Где: г. Минск Репутация: нет Всего: 24 |
-Mikle-, весьма, полезно, попробую разобраться.
|
|||
|
||||
| -Mikle- |
|
|||
![]() Невидимка Vingrad'а ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1672 Регистрация: 22.6.2003 Где: Казахстан, Астана Репутация: 1 Всего: 59 |
Пиши, если вдруг будут впросы.
-------------------- Если тебе плюют в спину, значит ты впереди... |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, cully, mr.DUDA, Exception. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Распределённые приложения и сеть | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |