Изпращане на файлове към мрежата
Сайт на Delphi: ежедневни Delphi-новини, документация, статии, преглед, интервю, компютърен хумор.
Изпращането на текст С ПОМОЩТА на компонентите ServerSocket И ClientSocket е много лесно, както видяхте при писането на троянския кон. Но по някаква причина много хора имат проблеми с изпращането на файлове, въпреки че това не е много по-трудно.
Сега ще напишем две програми: клиент и сървър. Сървърът ще стартира, ще отвори порт и ще изчака връзка. След като клиент се свърже и поиска файл от сървъра, сървърът ще избере файла и ще го изпрати.
Нека започнем нашия пример, като напишем сървър, като по-прост. Създайте нов проект и плъзнете следните компоненти върху формуляра.
• Полето за въвеждане Редактиране, в което се въвежда името на файла.
□ Бутон, който ще ви позволи да намерите файла, който изпращате. По този начин няма да се налага да въвеждате ръчно пълния път на файла.
Компонентът ServerSocket, с негова помощ ще изпращаме данни. Компонентът, с който ще отворим файла.
Ориз. 4.37. Основна форма на сървъра
За компонента ServerSocket трябва да зададете свойството Port на някаква реална стойност на порта, който ще бъде отворен, за да изчака връзка. Избрах за пример числото 2024. След това зададох свойството Active на true, така че сървърът да се активира автоматично при стартиране.
Тук просто показваме прозорец за избор на файл на екрана и ако потребителят е избрал нещо, тогава го поставяме в реда за въвеждане.
Подготовката приключи. Сега трябва да напишем кода за работа с мрежата. Нашият сървър трябва да изчака да пристигне определена команда и ако пристигне, да изпрати файла. За да направим това, трябва да създадем манипулатор на събития, който се извиква всеки път, когато данните идват от мрежата (списък 4.6).
Името на файла Editl.Text и режимът, в който ще бъде включен файлът, се предават като параметри на конструктора. За нас е достатъчно да използваме режим на четене, така че е посочен флагът fmOpenRead. След отваряне текущата позиция във файла трябва да бъде зададена в самото начало. Но, както се казва, "доверявай, но проверявай" - така че принуждавам позицията да започне:
В началото на изпратените данни стои думата size:, по която клиента разбира, че сме му изпратили размера на файла. След това идва самият размер, преобразуван в низ. В самия край на реда се добавя нулев знак #0, с който клиентът може да отдели тази информация от данните на самия файл.
Сега можете да изпратите избрания файл. Това се прави най-добре с помощта на метода SendStearn на компонента Socket. Този метод изпраща поток от произволен формат (файлов поток, поток в паметта и т.н.).
Това е всичко. Сървърът изпрати файла и можете да започнете да пишете клиента, който ще направим отделна програма. Създайте нов проект и поставете следните компоненти във формуляра:
компонент, с който ще се свържем със сървъра и ще поискаме / получим файл.
Ориз. 4.38. Основна клиентска форма
За компонента TClientSocket трябва да зададете свойството Port на същата стойност като сървъра - 2024.
В частната секция на обекта ще декларираме няколко променливи:
В манипулатора на събитие onclick на бутона Shock напишете следния код:
В манипулатора на събитие onclick на бутона Defrost имаме следния код:
Тук просто затваряме връзката.
Веднага щом се свържем със сървъра, веднага му изпращаме командата s, така че сървърът да изпрати файла. Е, сега трябва да създадете манипулатор на събитие OnRead за компонента ClientSocket, който ще бъде извиканвсеки път, когато клиентът получи данни. В него пишем следния код (листинг 4.7).
Процедурата е доста сложна и ще трябва да се работи на части. В самото начало полученият текст се съхранява в променливата s. Следната част от кода ще бъде изпълнена, ако променливата Reciving е вярна. Ще оставим тази част сама засега и ще разгледаме тази, която е точно по-долу:
Следващият ред преобразува текстовото представяне на размера в число и го съхранява в променливата DataSize. Сега изтриваме всички символи от входящия текст до първата нула #o, т.е. изтриваме информацията за размера на прехвърления файл.
След това задаваме променливата Reciving на true. Тази променлива ще покаже, че прехвърлянето на файла е започнало. Тъй като файлът не може да пристигне наведнъж и ние ще го получим на части от приблизително 8 KB всяка, при последващи извиквания към този манипулатор на събития, трябва да знаем, че това, което е дошло, са данни от файла.
Посочете output.dat като име. Не знам точното име на файла, затова използвам това. Пътят не е посочен, което означава, че файлът ще бъде записан в същата директория, където се намира програмата. Използвам fmCreate като флаг при отваряне на файл, което води до създаване на нов файл. Ако такъв файл вече съществува, той ще бъде презаписан.
Сега на клиента, след като сте извлекли размера на файла и сте премахнали този текст от променливата s, можете да извлечете името на файла по същия начин и да го премахнете от получените данни, за да запазите само неговите данни във файла.
След отваряне на файла запазваме получените данни, като извикваме метода за запис.
Сега сте готови да се справите с частта от кода, която пропуснахме:
Както вероятно вече сте разбрали, тук има проверка: ако променливатаReciving е true, което означава, че данните се получават и сме получили следващата част от файла. Поддържам го по същия начин. След това се извършва сравнение, ако размерът на потока е равен на размера на получения файл, тогава файлът е напълно приет и можете да го затворите, да изключите променливата Reciving и да изведете съобщение за успешно приемане.
Можете да използвате подобен метод за получаване на изображения. Ето как да изпратите снимка: va g
ras: TMemory поток; //Потокът от памет започва ms : =TNemoryStream.Create; //Създаване на нишка
Това е минимален пример за изпращане на изображение от компонента imagel. Как да приемете данните, опитайте се да помислите сами.
На компактдиска в директория \Examples\Chapter 4\Send File можете да видите пример за програмите, създадени в този раздел.