Delphi — это мощный инструмент. Написание программного обеспечения с помощью Delphi может значительно сократить цикл разработки программного обеспечения. Основная идея передачи файлов «точка-точка» заключается в том, что серверное и клиентское программное обеспечение используют один и тот же порт. После подключения клиент отправляет на сервер запрос, включая имя файла, размер и т. д. файл для передачи. Если сервер примет и начнет передачу файлов. Конечно, есть два режима передачи файлов: код ASCII и Bin, но в целом Bin достаточно. Основываясь на приведенном выше обсуждении, изначально можно было использовать элементы управления NMStrm и NMStrmServ в Delphi4. Однако я протестировал это и обнаружил, что элемент управления NMStrm можно использовать для файлов меньшего размера и это очень удобно. Однако, если файл большой (1 Мб). ), произойдет ошибка. Итак, затем мы используем TServerSocket и TClientSocket в Delphi для написания этой программы. Из-за ограничения размера пакета Ethernet и механизма обработки DelphiSocket (в Delphi, когда вы используете Socket для отправки большего потока, получатель запускает OnRead несколько раз). . событие, Delphi гарантирует целостность каждых данных только в нескольких событиях OnRead, а не собирает сами данные и не возвращает их пользователю, поэтому не думайте, что вы можете отправить файл для передачи один раз в один Socket и Recv один раз в другом. Вам придется собирать данные самостоятельно или самостоятельно определять протокол), поэтому мы применяем метод специального протокола. Канонический способ определения протокола — использовать Record End. нравиться:
TMyFilePROtocol=Запись
sSendType=(ST_QUERY,ST_REFUSE,ST_DATA,ST_ABORT,...);
iДлина: целое число;
bufSend: Буфер;
Конец;
Я пробовал этот метод, но он не удался, и я всегда думал, что мой метод правильный, но программа всегда не компилировалась, я думаю, что-то не так с Delphi :) Поэтому в следующем примере программы я использовал другой метод. В классе Socket есть два свойства, ReceiveText и ReceiveBuf. В событии OnRead эти два свойства можно использовать только один раз, поэтому мы можем использовать глобальную переменную, чтобы сохранить, следует ли читать Text или Buf, то есть читать. Отправьте текст один раз и прочитайте его еще раз. Но это имитирует TMyFileProtocol.
Запустите программу:
Напишите самый простой вариант, в основном используемый для объяснения метода.
Определить протокол:
Конст
MP_QUERY = '1';
MP_REFUSE = '2';
MP_ACCEPT = '3';
MP_NEXTWILLBEDATA = '4';
MP_DATA = '5';
MP_ABORT = '6';
MP_OVER = '7';
MP_CHAT = '8';
Введение соглашения:
Сначала Клиент отправляет MP_QUERY, а после его получения Сервер отправляет MP_ACCEPT или MP_FEFUSE;
Клиент отправляет MP_FILEPROPERTY после получения MP_ACCEPT, а Сервер отправляет MP_NEXTWILLBEDATA после его получения;
Клиент отправляет MP_NEXTWILLBEDATA после его получения, а Сервер отправляет MP_DATA после его получения;
Клиент получает MP_DATA и отправляет данные, Сервер получает данные и отправляет MP_NEXTWILLBEDATA;
Цикл, пока Клиент не отправит MP_OVER;
MP_CHAT+String можно отправлять друг другу посередине;
Серверная программа:
Поместите следующие элементы управления: SaveDialog1, btnStartServer,
сс,(TServerSocket)
btnStartServer.OnClick(Отправитель:TObject);
начинать
сс.Порт:=2000;
сс.Открыть;
конец;
ss.OnClientRead(Отправитель: TObject;Socket: TCustomWinSocket);
вар
сТемп: строка;
bufRecv: Указатель;
iRecvLength: целое число;
начинать
если bReadText, то
начинать
sTemp:=Socket.ReceiveText;
случай sTemp[1] из
MP_QUERY:начать
//Отклонить здесь
SaveDialog1.FileName:=Copy(sTemp,2,Length(STemp));
если SaveDialog1.Execute, то
начинать
Socket.SendText(MP_ACCEPT);
fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate);
конец
еще Socket.SendText(MP_REFUSE+'die');
конец;
MP_FILEPROPERTY:начать
//Чтобы отправить StrToInt(Copy(sTemp,2,Length(sTemp))) раз
//Отображение прогресса времени. . .
Socket.SendText(MP_NEXTWILLBEDATA);
конец;
MP_NEXTWILLBEDATA: начало
Socket.SendText(MP_DATA);
bReadText: = ложь;
конец;
MP_END:начать
fsRecv.Free
bReadText:=истина;
конец;
MP_ABORT:начать
fsRecv.Free;
bReadText:=истина;
конец;
MP_CHAT:начать
//Сообщение в чате
конец;
конец;{случай}
конец
еще начать
пытаться
GetMem(bufRecv,2000);//2000 должен >iBYTESEND
Socket.ReceiveBuf(bufRecv^,iRecvLength);
fsRecv.WriteBuffer(bufRecv^,iRecvLength);
окончательно
FreeMem(bufRecv,2000);
конец; {попробовать}
bReadText:=истина;
Socket.SendText(MP_NEXTWILLBEDATA);
конец;
конец;
Клиентская программа:
Разместите следующие элементы управления: edtipAddress, OpenDialog1, btnConnect, btnSendFile,
cs (TClientSocket).
btnConnect.OnClick(Отправитель:TObject);
начинать
cs.Address:=edtIPAddress.Text;
cs.Порт:=2000;
cs.Соединиться;
конец;
btnSendFile.OnClick(Отправитель:TObject);
начинать
если OpenDialog1.Execute, то
Начинать
cs.Socket.SendText(MP_QUERY+OpenDialog1.FileName);//FileSize???
конец;
конец;
cs.OnRead(Отправитель: TObject;Socket: TCustomWinSocket);
вар
сТемп: строка;
bufSend: указатель;
начинать
sRecv:=Socket.ReceiveText;
Случай sRecv[1] из
MP_REFUSE:ShowMessage('Упадешь в обморок, получи отказ!');
MP_ACCEPT: начало
fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpen);
//iBYTEPERSEND — константа, размер пакета, отправляемого каждый раз.
Socket.SendText(MP_FILEPROPERTY+Trunc(fsSend.Size/iBYTEPERSEND)+1);
конец;
MP_NEXTWILLBEDATA: начало
Socket.SendText(MP_NEXTWILLBEDATA);
конец;
MP_DATA: начало
пытаться
GetMem(bufSend,iBYTEPERSEND+1);
если (fsSend.Position+1+iBYTEPERSEND) < fsSend.Size тогда
начинать
fsSend.Read(bufSend^,iBYTEPERSEND);
Socket.SendBuf(bufSend^,iBYTEPERSEND);
fsSend.Free;
end//Обычная отправка, размер iBYTEPERSEND
еще начать
fsSend.Read(bufSend^,fsSend.Size-fsSend.Position-1);
Socket.SendBuf(bufSend^,fsSend.Size-fsSend.Position-1);
end;//Последний раз отправить, отправить оставшиеся данные
окончательно
FreeMem(bufSend,iBYTEPERSEND+1);
конец; {попробовать}
конец;
MP_ABORT:начать
//Отменено :(
fsSend.Free;
конец;
конец;{случай}
конец;
Организационная процедура:
Добавьте оценку ошибок, оптимизируйте программу, объедините сервер и клиент, добавьте отображение оставшегося времени, сделайте возможным передачу нескольких файлов одновременно и добавьте функцию чата, и это станет хорошей передачей файлов из одной точки в другую. программа.