Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
| denizk |
6.1.2011, 15:18
Сообщение
#1
|
![]() Пользователь Группа: Активисты Сообщений: 654 Регистрация: 31.10.2007 Пользователь №: 18 005 |
Задача:
Отправить файл с сервера на клиент. Реализация: Реализация почерпнута из интернета. Для отделения команд от файла использована следующая схема "file#file.txt#16",команда + разделитель + имя файла + разделитель + размер файла. Код сервера: Добавляю буфер куда будет писаться файл. Код var Form1: TForm1; MS: TMemoryStream; // Буфер для файла Открываем сокет при старте приложения. Код procedure TForm1.FormCreate(Sender: TObject); begin ServerSocket1.Open; // Открываем сокет end; Закрываем сокет при закрытии приложения. Код procedure TForm1.FormDestroy(Sender: TObject); begin ServerSocket1.Close; // Закрываем сокет end; Посылаем файл при нажатии на кнопку. Код procedure TForm1.Button1Click(Sender: TObject); // Передаём файл var Size: integer; P: ^Byte; begin MS := TMemoryStream.Create; // Создаём буфер для файла MS.LoadFromFile(Edit1.Text); // Загружаем файл в буфер // Посылаем информацию о файл (команда # название # размер) ServerSocket1.Socket.Connections[0].SendText('file#'+Edit1.Text+'#'+IntToStr(MS.Size)+'#'); MS.Position := 0; // Переводим каретку в начало файла P := MS.Memory; // Загружаем в переменную "P" файл Size := ServerSocket1.Socket.Connections[0].SendBuf(P^, MS.Size); // Посылаем файл // Выводим прогресс ProgressBar1.Position := Size*100 div MS.Size; StatusBar1.SimpleText := 'Отправлено '+IntToStr(Size)+' из '+IntToStr(MS.Size)+' байт' end; В событие OnClientRead компонента TServerSocket пишу следующее: Код procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); begin if Socket.ReceiveText = 'end' then // Если клиент принял файл, то... begin StatusBar1.SimpleText := 'Клиент принял файл'; MS.Free; // Убиваем буфер end; end; На сервере использовал следующие компоненты: TServerSocket, TButton, TEdit, TProgressBar и TStatiusBar. В TEdit пишу имя пересылаемого файла,прогресс бар для получения инфы об отправке,статусбар показывает размер пересылаемого файла и сведения о установке конекта,серверсокет собственно для передачи. Порты одинаковые на клиенте и сервере использую 2545 или тому подобные. Код клиента: Записываем переменные в Private и объявляем процедуру Код procedure Writing(Text: string); // Процедура записи в данных в буфер private { Private declarations } Name: string; // Имя файла Size: integer; // Размер файла Receive: boolean; // Режим клиента MS: TMemoryStream; // Буфер для файла При создании сервера открываем сокет и ждём передачи файла. Код procedure TForm1.FormCreate(Sender: TObject); begin ClientSocket1.Open; // Открываем сокет Receive := false; // Режим клиента - приём команд end; При завершении приложения закрываем сокет. Код procedure TForm1.FormDestroy(Sender: TObject); begin ClientSocket1.Close; // Закрываем сокет end; Процедура Writing. Код procedure TForm1.Writing(Text: string); begin if MS.Size < Size then // Если принято байт меньше размера файла, то... MS.Write(Text[1], Length(Text)); // Записываем в буфер // Выводим прогресс закачки файла ProgressBar1.Position := MS.Size*100 div Size; StatusBar1.SimpleText := 'Принято '+IntToStr(MS.Size)+' из '+IntToStr(Size); if MS.Size = Size then // Если файл принят, то... begin Receive := false; // Переводим клиента в нормальный режим MS.Position := 0; // Переводим каретку в начало буфера MS.SaveToFile(Name); // Сохраняем файл ClientSocket1.Socket.SendText('end'); // Посылаем команду "end", то есть файл принят MS.Free; // Убиваем буфер StatusBar1.SimpleText := 'Файл принят'; end; end; В событие OnClientRead компонента TClientSocket вписываю: Код procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var Rtext: string; // Принятый текст begin Rtext := Socket.ReceiveText; if Receive then // Если клиент в режиме приёма файла, то... Writing(RText) // Записываем данные в буфер else // Если клиент не в режиме приёма файла, то... if Copy(Rtext, 0, Pos('#', Rtext) -1) = 'file' then // Если это файл, то... begin MS := TMemoryStream.Create; // Создаём буфер для файла Delete(Rtext, 1, Pos('#', Rtext)); // Определяем имя файла Name := Copy(Rtext, 0, Pos('#', Rtext) -1); // Определяем имя файла Delete(Rtext, 1, Pos('#', Rtext)); // Определяем размер файла Size := StrToInt(Copy(Rtext, 0, Pos('#', Rtext) -1)); // Определяем размер файла Delete(Rtext, 1, Pos('#', Rtext)); // Удаляем последний разделитель Label1.Caption := 'Размер файла: '+IntToStr(Size)+' байт'; // Выводим размер файла Label2.Caption := 'Имя файла: '+Name; // Выводим имя файла Receive := true; // Переводим сервер в режим приёма файла Writing(RText); // Записываем данные в буфер end; end; Соединение есть,файл посылается вроде,но не известно куда,т.к. не приходит! Проблема походу с кодировкой,подправьте кто-нить как правильно! |
| Tanker |
11.1.2011, 19:33
Сообщение
#2
|
|
Пользователь Группа: Активисты Сообщений: 363 Регистрация: 26.11.2009 Пользователь №: 22 377 |
вот еще пример пересылки файла http://delphi-faq.zoxt.net/100.htm
и вот http://delphi-faq.zoxt.net/c16.htm по-моему сначала надо проверить, что команда file# дошла... или вообще что-нибудь выведи там при приеме сообщение какая команда пришла -------------------- Успехов!
|
| denizk |
12.1.2011, 14:24
Сообщение
#3
|
![]() Пользователь Группа: Активисты Сообщений: 654 Регистрация: 31.10.2007 Пользователь №: 18 005 |
вот еще пример пересылки файла http://delphi-faq.zoxt.net/100.htm и вот http://delphi-faq.zoxt.net/c16.htm по-моему сначала надо проверить, что команда file# дошла... или вообще что-нибудь выведи там при приеме сообщение какая команда пришла Ага,спасибо)) гляну:сегодня надо одну прогу дописать и другую написать ещё успеть,до завтра! |
| denizk |
19.1.2011, 21:50
Сообщение
#4
|
![]() Пользователь Группа: Активисты Сообщений: 654 Регистрация: 31.10.2007 Пользователь №: 18 005 |
В общем перекомпил проект в дельфи 7 и всё нормально!
А в 2009-2010 дельфи решается проблема так SendText(S) на SendBuf(Pointer(S)^, Length(S)*Sizeof(Char)*2); надо менять и всё почти,единственный косяк,что файл приходит больше чем был! |
| Tanker |
20.1.2011, 19:13
Сообщение
#5
|
|
Пользователь Группа: Активисты Сообщений: 363 Регистрация: 26.11.2009 Пользователь №: 22 377 |
может, за счет выоавнивания до кратности 64 или 32? или сильно длиннее?
-------------------- Успехов!
|
![]() ![]() |
|
Текстовая версия | Сейчас: 20.5.2012, 23:56 |