| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Сети > Передача файла через сокеты |
| Автор: VanHelsing 10.8.2008, 07:47 |
| Передача файла я нашел в ДРКБ, тот который с помощью TFileStream. Ну немного переделал чтобы от клиента к серверу и клиенту мог выбирать файла, который хочет отправить. Вопрос следующий мне надо осуществить передачу файла от клиента другому клиенту через сервер? Приходит в голову пока только одно - сначала принимать файла на сервере, сохранять, а потом создавать новый поток и отправлять клиенту-получателю, но мне кажется это очень долго особенно если файл большого размера. Я можно ли это осуществить другим способом? |
| Автор: SneG0K 10.8.2008, 11:12 |
Пусть клиент делает запрос серверу, сервер дает IP другого клиента и клиент начинает на прямую передавать другому клиенту. |
| Автор: VanHelsing 10.8.2008, 18:42 | ||
Не совсем понимаю как это сделать. Мы же копируем в буфер сокета, а как определять кому принимать? |
| Автор: Burka 10.8.2008, 20:26 |
| Скорей всего для этого клиент должен запускать на своей машине сервер на время передачи файла и ждать соедениния от другого клиента. Но например в интернете с этим могут быть проблемы, так как у сервера должен быть выделенный айпи(многие провайдеры объеденяют несколько пользователей под одним айпи). |
| Автор: VanHelsing 11.8.2008, 18:28 |
| А больше ни у кого никаких предложений нет? Никто с этим не сталкивался? |
| Автор: VanHelsing 12.8.2008, 18:03 | ||
Хотелось бы увидеть какой-нибудь пример! |
| Автор: SneG0K 13.8.2008, 12:07 |
| VanHelsing, пример на словах. Клиент: Слыш сервер, я тут типа хочу передать файлик другому юзеру, ты мне дай его IP и скажи ему чтобы подготовился. Сервер:Вот держи его IP 127.0.0.1 . Сча я его предупрежу. Клиент:УГу.. спс _______ Сервер: Дарова чувак. Клиент-2: Ку Сервер: Тут лузер с ip 127.0.0.1 хочет тебе порнухи напихать. готовся Клиент-2: Ок. Жду |
| Автор: Exai1e 13.8.2008, 12:36 |
| SneG0K, мда... а сервер / клиент2 обладают телепатией ?) откуда они узнают про размер принимаемых данных ? а что мешает сделать к примеру так: клиент1: Привет сервер, хочу передать одно клиенту с айпи (123.123.13.123) (именем компа, ником что угодно) фаил, размера 3 мб сервер: Хорошо передавай =), Клиент2 тебе Клиент1 хочет фаил передать на 3 мб, лови! клиент2: Принять или не принять... вот в чем вопрос. Принимаю. ... Спросите, откуда один клиент знает айпи (ник, имя компа) другого ? Все очень просто. При подключении клиент отсылает свои данные серверу (айпи и ник к примеру) сервер у себя хранит это гденить и когда клиент1 обращается к серверу с просьбой передать фаил "васе_пупкину", то сервер берет данные васи из своей структуры (списка) и отправляет ему. например для сокетов можно взять LocalHost (имя компа) но тогда могут возникнуть проблемы если компьютеров с одним именем подключено к серверу несколько. |
| Автор: SneG0K 13.8.2008, 15:54 |
| Exai1e, я надеюсь на то, что автор темы на форточке не катался. |
| Автор: BaD_SeCt0R 13.8.2008, 16:09 |
| Exai1e, SneG0K, шутники... Если не ошибаюсь, то в ДРКБ пример на основе Client/ServerSocket. Тогда действия такие. Для первого примера: Отсылаешь текстовый запрос на передачу файла (указывая ip клиента #2) серверу. Открываешь новый порт на клиенте №1 . С сервера посылаешь ip клиента №1 клиенту №2. Клиентом соединяешься через новый порт с ip клиента №1. В эвентах серверсокета клиента №1 в OnClientConnect при соединении ip клиента №2 шлешь ему файл стандартным способом, описанным в ДРКБ. Не забудь про хедер с именем и размером файла. Для второго примера: На клиенте №1 готовишь и отправляешь хедер (инфо о файле, размер, имя, ip кому и т.п.), следом шлешь весь файл (буфер строка, через SendText). На сервере принимаешь хедер, затем файл кусками в стрим, готовишь хедер шлешь его и полностью полученные куски клиенту №2. Склеиваешь куски в TFileStream. Сохраняешь в файл. Все. |
| Автор: VanHelsing 13.8.2008, 18:09 |
| Да... много информации. Ну вот что я понял. Клиент выполняет запрос:отправляет серверу свой ip, ip того кому он хочет послать файл, и размер файла, ну можно и имя файла послать(хотя я думаю что имя файла можно послать по завершению приема). Сервер спрашивает клиент, которому предназначается файл, свободен ли он и не принимает ли в данный момент какие-либо файлы. Если клиент отвечает положительно, то клиенту, кот принимает он отправляет ip отправителя и размер файла. А клиенту отправителя говорит что клиент согласен и что тот может начинать пересылать данные. И клиент начинает пересылать данные. Только не нашел как написать в виде кода отправку с клиента на клиент? Если я правильно все понял? |
| Автор: Burka 14.8.2008, 06:11 | ||||
Тут скорей будет не айпи а id клиента, ну мне кажется клиенты не должны знать айпи других клиентов. но это мне так кажется =)
Так как я написал в своем первом сообщении. Один из клиентов должен запускать на своем компе сервер и должен передать через главный сервер необходимые данные для коннекта (свой айпи и порт). |
| Автор: MetalFan 14.8.2008, 08:05 |
| тут я так смотрю есть два варианта: 1. Пересылка файла(данных) между клиентами ЧЕРЕЗ сервер. (что позволит передавать данные между клиентами из локальных сетей без выделенного ИП в интернете. Главное, чтобы сервер имел свой ИП) 2. Пересылка файла(данных) между клиентами напрямую, но для инициации передачи используется сервер (aka P2P). судя по сабжевому сообщению, автору нужно первое. |
| Автор: Exai1e 14.8.2008, 08:08 | ||
чем твой вариант отличается от предложенного мною ?... |
| Автор: BaD_SeCt0R 14.8.2008, 13:35 |
| Exai1e, у тебя сервер принимает файл целиком и только потом отправляет. 3 МБ немного, а если 3 ГБ? |
| Автор: VanHelsing 14.8.2008, 15:56 | ||||
Я просто хочу разобраться с двумя вариантами. С первым я все понял и как сделать представлю. Хотелось бы разобраться со вторым. Обратился клиент к серверу тот передал запрос клиенту получателю, тот ответил серверу, а сервер в свою очередь клиенту-отправителю. Как это сделать я знаю! Я не знаю как написать пересылку от клиента-отправителя к клиенту получателя. Например чтобы с сервера отправить что-либо определенному клиенту нужно написать:
А как это сделать с клиента клиенту? |
| Автор: BaD_SeCt0R 14.8.2008, 16:43 |
Точно так же. Клиент тоже должен содержать на форме TServerSocket для открытия ДРУГОГО порта |
| Автор: VanHelsing 14.8.2008, 18:43 |
| Извините може задаю слишком много тупых вопросов, но все же... Получается мне придется на клиенте включать сервер? Если так, то возникает несколько вопросов. То есть мне придется открывать новый сервер по другому порту. Далее клиент-получатель подключается к новому серверу и начинается передача файла? P.S. А может ли клиент быть одновременно подключен в нескольким серверам? |
| Автор: BaD_SeCt0R 14.8.2008, 20:03 | ||||
А как иначе?
Можно для этого предусмотреть и другого клиента.
TClientSocket? Нет. По определению. Дублируй компонент. |