![]() |
Модераторы: feodorv |
![]() ![]() ![]() |
|
JohnnyQ |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 60 Регистрация: 22.7.2007 Где: Санкт_Петербург Репутация: нет Всего: нет |
Добрый день!
Я пишу программу по передаче файлов через TCP. Более-менее настроил клиента и сервера: они обмениваются сообщениями, теперь нужно добавить передачу любого файла между ними. Нашел в сети примерную прогу, но там передача файла сделана как-то совсем уж коряво, до и передает только текстовые файлы... Вопрос: С помощью каких функций лучше всего передавать файл? может у кого пример есть с описанием? |
|||
|
||||
jonie |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
точно также как ты обмениваешься сообщениями. файл ничем не отличается от сообщения.
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
ExMike |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 22.9.2007 Репутация: нет Всего: нет |
удаленно
Это сообщение отредактировал(а) ExMike - 2.5.2008, 15:46 |
|||
|
||||
bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 1 Всего: 47 |
Нафига TCP, если есть FTP?
![]() |
|||
|
||||
ExMike |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 22.9.2007 Репутация: нет Всего: нет |
дайте пример обменна сообщениями,прост совсем не давно начал с сетью работать
простой if(buf == "messagge"); не хочет работать,или как правильнее? ![]() |
|||
|
||||
Олег2005 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
JohnnyQ,
Стандартная функция интерфейса сокетов для передачи файлов - это send() Она шлет содержимое своего буфера - и ей по барабану, что вы в буфер положили - она шлет байты. В Winsock 2.0 есть две специальные функции - TransmitFie() и TransmitPacket(). Открывается нужный файл, передается его хендл и все - функция сама все передаст. |
|||
|
||||
ExMike |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 22.9.2007 Репутация: нет Всего: нет |
удаленно
Это сообщение отредактировал(а) ExMike - 2.5.2008, 15:48 |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
не путайте понятия TCP - это транспортный уровень, а FTP - прикладной FTP не получится использовать без протокола транспортного уровня (TCP, UDP, ...) Это сообщение отредактировал(а) MAKCim - 1.5.2008, 15:37 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
sergu |
|
|||
Новичок Профиль Группа: Участник Сообщений: 22 Регистрация: 19.9.2006 Репутация: нет Всего: нет |
Короче, открываешь файл в бинарном режиме. Читаешь его кусочками, например по 1024 байт в буфер, и отправляешь его. Потом получаешь этот кусочек файла, и дозаписываешь его в конец целевого файла.
|
|||
|
||||
nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
TransmitFile()
|
|||
|
||||
JohnnyQ |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 60 Регистрация: 22.7.2007 Где: Санкт_Петербург Репутация: нет Всего: нет |
Попробывал так сделать - работает, но опять только для текстовых файлов... открываю файл вот так Fp=fopen(c,"rb") дальше считываю в цикле с помощью fgets(buffer, 1000, Fp ), ну и потом в том же цикле отправляю кусками файл. Может с fgets что-то ни так в бинарном режиме? |
|||
|
||||
W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 1 Всего: 121 |
А справку по fgets читали? Она для чего? В вашем случае надо использоваться fread.
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
nerdy_weirdie |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Бох ты мой, какой fread... если уж на то пошло - лучше спроецировать файл на память и отправить целиком. Если под win, то так:
Это сообщение отредактировал(а) nerdy_weirdie - 12.5.2008, 04:45 |
||||
|
|||||
W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 1 Всего: 121 |
И чем же лучше?
Добавлено через 2 минуты и 42 секунды И чем лучше? -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
![]() ![]() 1) Вы хоть представляете себе, как работают эти fread, fwrite? 2) Значительно удобнее. Это сообщение отредактировал(а) nerdy_weirdie - 12.5.2008, 22:36 |
|||
|
||||
dumb |
|
|||
![]() sceloglauxalbifacies ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2929 Регистрация: 16.6.2006 Репутация: 1 Всего: 158 |
JohnnyQ только начинает трехколесный велосипед осваивать, а ты ему не без пафосной нотки мотоцикл предлагаешь.
могу задать встречный вопрос: ты представляешь себе, как работают эти CreateFileMapping, MapViewOfFile? попробуй на досуге файл на пару гигов обработать по приведенной тобой схеме. удобнее написать непортабельный, испещренный системными вызовами код? это по сравнению с пятком строк с использованием fread? ![]() |
|||
|
||||
nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Смешно вас слушать, ребзя. Для таких ликбезов есть интренет. Скажу лишь, что windows-приложения лучше писать используя непосредственно апишки ядра windows вместо уродливых мутантов созданных через пень-колоду с целью posix-совместимости на основе этих же апишек. Не бойтесь большого числа параметров
![]() Простой пример: FILE* f=fopen("c:\\myfile","w"); if(f) { char szLine[] = "hi\r\n"; fwrite(szLine,strlen(szLine),1,f); fclose(f); } Как ты думаешь, сколько и каких байт запишется в файл? 4 байта? Не угадал. А теперь представь, что ты сохранял файл с важными данными. Этих трансляций-то можно избежать в бинарном режиме, но это лишний раз показывает кучу лишней бороды. О быстродействии и не заикайся. Так вот подумай, что, как и почему. ![]() Это сообщение отредактировал(а) nerdy_weirdie - 13.5.2008, 01:28 |
|||
|
||||
dumb |
|
||||
![]() sceloglauxalbifacies ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2929 Регистрация: 16.6.2006 Репутация: 1 Всего: 158 |
мне не нужно угадывать - твой простой пример запишет у меня 4 байта. потому что знаю, как работают эти функции. в отличие от.
Добавлено через 2 минуты и 48 секунд хорошо, что хоть исправил. ![]() неисправленный "простой пример" был таким:
|
||||
|
|||||
nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Всё равно всё пишет и читает ядро винды. И ты по прежнему доказываешь, что лучше дергать его не напрямую, а через посредников?
Это сообщение отредактировал(а) nerdy_weirdie - 13.5.2008, 01:41 |
|||
|
||||
dumb |
|
||||
![]() sceloglauxalbifacies ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2929 Регистрация: 16.6.2006 Репутация: 1 Всего: 158 |
если ты наступил на грабли преждевременной оптимизации и тебе понравилось, то это вовсе не означает, что сие есть правильное и полезное занятие.
![]() родился еще один вопрос: ты представляешь себе количество системного кода, выполняющегося при вызове, например, ReadFile? можешь поисследовать, а когда оценишь, вернись к этому "бородатому посреднику" fread и сопоставь. точно не скажу, но полагаю, что посредник будет и по объему и по времени выполнения меньше 1% от общего кода. все те же грабли стучат нам по лбу. |
||||
|
|||||
nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Ты все до одного свои аргументы просто выдумываешь? И так упёрто.. Тебе ведь опытный человек пишет. CRT полностью основана на winapi.
Сомневаюсь, что ты мне хоть спасибо за просвещение скажешь, но объясню: fopen вызывает CreateFile (\microsoft visual studio 8\vc\crt\src\open.c, line 388) fwrite вызывает WriteFile (\Microsoft Visual Studio 8\VC\crt\src\write.c, line 297) И так далее. Обрати внимание, сколько там кода и вызовов. И даже новичку намного проще и приятнее отправить и принять через сокет один единственный буфер, в котором лежит весь файл, чем дробить на куски, считать остаток, потом собирать на другом конце провода это. Скорость поиска дорожки на винчестере измеряется миллисекундами, за которые по обыкновенному адслю уходят десятки килобайт - для файлового сервера очень ощутимо ![]() |
|||
|
||||
ptr |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 661 Регистрация: 31.5.2006 Где: Новосибирск Репутация: 9 Всего: 14 |
Это ты похоже все свои аргументы выдумываешь. И что опытный человек хорошего написал?
Больше скажу, так или иначе, все функции работают с ядром ;-) nerdy_weirdie, ты слышал такие слова как переносимость, кроссплатформенность? 1. И часто профессионалы так делают? 2. Быстрее, проще и приятнее не значит лучше. 2. На том конце всё равно придется собирать по-частям (данные не отправятся большим куском). Интересно что будет для файлового сервера ощутимее, держать в памяти многомегабайтный файл, либо потерять пару миллисекунд на вызов методов? Представь сколько полезной работы может сделать процессор, пока ждет данные от винчестера. Зачастую при программировании fopen, fwritе и пр. ещё много раз заворачивают. Это сообщение отредактировал(а) ptr - 13.5.2008, 08:59 -------------------- Единственный способ определить границы возможного - это выйти за эти границы, в невозможное. Артур Кларк. |
|||
|
||||
Олег2005 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
Hi all
И не надоело вам пересчитывать пальцы на руке - у кого их больше, тот и круче? Хотя принципиально я все таки согласен - на АПИ оверхеда будет меньше-ИМХО Однако при передаче по сети это совсем не критично...... Это сообщение отредактировал(а) Олег2005 - 13.5.2008, 12:11 |
|||
|
||||
ptr |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 661 Регистрация: 31.5.2006 Где: Новосибирск Репутация: 9 Всего: 14 |
Никогда не надоест ![]() Это сообщение отредактировал(а) ptr - 13.5.2008, 17:41 -------------------- Единственный способ определить границы возможного - это выйти за эти границы, в невозможное. Артур Кларк. |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
нет
не обязательно ключевое слово TSO -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
ptr |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 661 Регистрация: 31.5.2006 Где: Новосибирск Репутация: 9 Всего: 14 |
Ну да, погорячился ![]() ![]() Сегментация то всё равно происходит, только на другом уровне. -------------------- Единственный способ определить границы возможного - это выйти за эти границы, в невозможное. Артур Кларк. |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
1. уровень NIC мы не контролируем 2. с точки зрения API данные будут приходить достаточно большими порциям в случае, если файл не сильно большой, вполне возможно достаточно будет одной итерации для его получения -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
v1rtu0z |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 61 Регистрация: 21.4.2008 Где: Воронеж Репутация: нет Всего: нет |
вот у меня есть функции для приема и передачи файлов.. там в них используется пара самописных функций, но все интуитивно понятно:
и прием
|
||||
|
|||||
Deepthroat |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 24.9.2007 Где: Outer Heaven Репутация: нет Всего: 2 |
Я в C++ не профи, но мое ИМХО - всегда лучше использовать кроссплатформенные функции сразу, чем потом переписывать код для другой системы.
|
|||
|
||||
cmlwt |
|
|||
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 22.6.2008 Репутация: нет Всего: нет |
Может пригодиться. У самого была проблема считки бинарника
Это сообщение отредактировал(а) cmlwt - 23.6.2008, 16:25 |
|||
|
||||
w32blaster |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 2.1.2006 Где: Tln/Slmae Репутация: нет Всего: нет |
Здравствуйте всем. Прошу прощения, что воскресаю старый топик, но если я открою новый, то всяко меня отправят юзать поиск.
Проблема собсна у меня по сабжу. Снова лаба в универе, и снова трудно разобраться. Задание - сделать прогу, которая имитирует дейсвие ФТП-клиента и сервера. На практике это два скрипта, один за сервер, другой за клиент, и обмениваются сообщениями через сокет по TCP. Препод выложил нам два "исходника" - две проги, от которых мы можем отходить. Могу привести ссылки на них: postit.c postit.h postit_server.c (сервер в Эстонии, если не будет качаться - скажите, перезалью). Эти два примера просто обмениваются сообщениями. Лично я на основе их реализовал функцию ls, то есть просмотр папок и фалов, quit, ну это легко, и cd смена папок. Вот. Осталось дело за малым - put и get. Вот тут-то я и застрял. Собсна, вот мой и вопрос: как можно реализовать передачу фалов? Я в этом топике прочёл, что это нужно делать так же, как и сообщения. Это понятно. Но а поподробнее? Нужно файл считывать по 100 байт и перекидывать на сервер? А как тогда сервер их должен ловить? Ну то есть.... Вобщем, прошу примера или ссылки на толковый пример или туториал. А то не совсем понятно, как сервер получает сообщения. Если, скажем, отправлять клиент будет таким образом:
то как это же события будет обрабатывать сервер? Вот... До сессии три недели.... прошу помощи, любой.... заранее благодарен. Это сообщение отредактировал(а) Олег2005 - 11.12.2008, 14:58 |
|||
|
||||
vinick |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 285 Регистрация: 9.6.2005 Репутация: 6 Всего: 22 |
сценарий для PUT
|
|||
|
||||
w32blaster |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 2.1.2006 Где: Tln/Slmae Репутация: нет Всего: нет |
Спасибо, добрый человек.
![]() ![]() Это сообщение отредактировал(а) w32blaster - 11.12.2008, 15:44 |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
не катит что будем делать если посередине произошла ошибка чтения файла? разрывать соединение? намного лучше передавать файл блоками с подтверждениями с другой стороны - вдруг там место закончилось или еще что-то случилось |
|||
|
||||
antsh85 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 2.1.2008 Репутация: нет Всего: нет |
Привет,
Я туже лабу делаю. Сценарий: Client С & Server S C->S do LS S: LS response is 1000bytes = 3 packets S->C send to C total size of response (1000 bytes) sent (...) S->C send 3 packets sent (...) x 3 C<-S LS response size (1000 bytes) -> recv(...) C<-S 3 packets (вот тут я получаю оборванные пакеты, потому что к тому времени когда клиент начнёт делать recv(...) сервер уже закончивает делать sent(...) ) Мне казалось что если сервер шлёт что то сокету, то это должно где то буфферится, до тех пор пока на стороне клиента не будет вызванно recv(...) Но я похоже не прав, как всё в дейсвительности? Это сообщение отредактировал(а) antsh85 - 25.12.2008, 19:02 |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
для TCP оно буферится
просто если recv вызван до того, как все данные дошли то recv возвращает тот кусок который уже пришел - вне зависимости как это было отправлено через send данные надо собирать из кусков, либо выставить флаг MSG_WAITALL - тогда блокирующий recv заблокируется пока не будет заполнен буфер, либо закрыт сокет, либо не сорвет сигналом, либо не придет OOB Это сообщение отредактировал(а) J0ker - 26.12.2008, 02:18 |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |