|
以下代碼相比網(wǎng)上其它某些文件傳輸代碼精練很多,傳輸?shù)奈募笮∪我?個人建議:寫網(wǎng)絡(luò)文件傳輸程序時最好用Indy的控件(因為其默認(rèn)即阻塞模式,Server端已封裝了多線程,沒有數(shù)據(jù)包大小限制),ClientSocket
VS ServerSocket傳輸文件很麻煩,要自定通信協(xié)議,并且有個8KB的瓶頸,實現(xiàn)大文件傳輸比較麻煩,
服務(wù)端發(fā)送: var
iFileHandle:integer; iFileLen,cnt:integer; buf:array[0..4096] of
byte; begin
iFileHandle:=FileOpen('E:\Study\深入Delphi6網(wǎng)絡(luò)編程.rar',fmOpenRead);
iFileLen:=FileSeek(iFileHandle,0,2); FileSeek(iFileHandle,0,0);
AThread.Connection.WriteInteger(iFileLen); while true do
begin cnt:=FileRead(iFileHandle,buf,4096);
AThread.Connection.WriteBuffer(buf,cnt); if cnt<4096
then break; end;
FileClose(iFileHandle); end;
=======================================================
客戶端接收: procedure TForm1.Button1Click(Sender:
TObject); var rbyte:array[0..4096] of byte;
sFile:TFileStream; iFileSize:integer; begin try
IdTcpClient1.Connect(5000); except exit;
end;
iFileSize:=IdTCPClient1.ReadInteger;
sFile:=TFileStream.Create('e:\bb.tmp',fmCreate); While iFileSize>4096
do begin IdTCPClient1.ReadBuffer(rbyte,4096);//
.ReadBuffer(rbyte,iLen); sFile.Write(rByte,4096);
inc(iFileSize,-4096); end;
IdTCPClient1.ReadBuffer(rbyte,iFileSize);// .ReadBuffer(rbyte,iLen);
sFile.Write(rByte,iFileSize); sFile.Free; ShowMessage('file get
ok!'); end;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
具體代碼:
Server(Receive):
procedure TFrmServer.FormCreate(Sender:
TObject); begin IdTCPServer1.DefaultPort:=5616;
IdTCPServer1.Active:=True; end;
procedure
TFrmServer.IdTCPServer1Execute(AThread: TIdPeerThread); var
rbyte:array[0..4096] of byte; sFile:TFileStream;
cnt,cmd,FileSize:integer; str,FileName:string;
begin str:=AThread.Connection.ReadLn;
//接收文件大小及文件名 cmd:=pos('|',str); //查找分隔符
FileName:=copy(str,1,cmd-1); //提取文件名
FileSize:=StrToInt(copy(str,cmd+1,Length(str)-cmd+1)); //提取文件大小 if
MessageBox(0,Pchar('用戶 '+AThread.Connection.Socket.Binding.PeerIP+'要給您傳送文件
"'+FileName+'" 您是接受還是拒絕?'),'文件接受',MB_YesNo or MB_ICONQUESTION)=ID_Yes then
//詢問是否接收 begin ProgressBar1.Max:=FileSize; //初始化進(jìn)度條
ProgressBar1.Position:=0; SaveDialog1.FileName:=FileName;
//指定保存的默認(rèn)文件名,一定要在 SaveDialog1.Execute;之前,不然文件名為空
SaveDialog1.Execute;
sFile:=TFileStream.Create(SaveDialog1.FileName,fmCreate); //創(chuàng)建待寫入的文件流
While FileSize>4096 do begin
AThread.Connection.ReadBuffer(rbyte,4096);// 讀取文件流
sFile.Write(rByte,4096); //寫入文件流
cnt:=AThread.Connection.ReadInteger; //從發(fā)送端接收最新的進(jìn)度位置信息
ProgressBar1.Position:=ProgressBar1.Position+cnt; //更新顯示進(jìn)度
Label1.Caption:='當(dāng)前接收進(jìn)度..';
StatusBar1.Panels[0].Text:='正在接收文件中...'; inc(FileSize,-4096);
end; AThread.Connection.ReadBuffer(rbyte,FileSize);//
.ReadBuffer(rbyte,iLen); sFile.Write(rByte,FileSize);
sFile.Free; StatusBar1.Panels[0].Text:='文件接收完成!';
Label1.Caption:='文件接收完成!'; end; END;
procedure TFrmServer.FormDestroy(Sender:
TObject); begin IdTCPServer1.Active:=False;
Application.Terminate; end;
Client(Send):
procedure TFrmClient.SpeedButton1Click(Sender:
TObject); begin OpenDialog1.Execute;
edtFileName.Text:=OpenDialog1.FileName; end;
procedure TFrmClient.btnSendClick(Sender:
TObject); var iFileHandle:integer; iFileLen,cnt:integer;
buf:array[0..4096] of byte;
begin if (edtAddress.Text<>'')and
(edtFileName.Text<>'') then begin
IdTCPClient1.Host:=edtAddress.Text; IdTCPClient1.Port:=5616;
try IdTCPClient1.Connect(5000); except
StatusBar1.Panels[0].Text:='連接接受方失敗!'; exit; end; if
IdTCPClient1.Connected then begin
iFileHandle:=FileOpen(edtFileName.Text,fmOpenRead);
iFileLen:=FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0); ProgressBar1.Max:=iFileLen;
ProgressBar1.Position := 0;
IdTCPClient1.WriteLn(ExtractFileName(edtFileName.Text)+'|'+IntToStr(iFileLen));
while true do begin Application.ProcessMessages;
cnt:=FileRead(iFileHandle,buf,4096);
IdTCPClient1.WriteBuffer(buf,cnt);
IdTCPClient1.WriteInteger(cnt);
ProgressBar1.Position:=ProgressBar1.Position + cnt;
StatusBar1.Panels[0].Text:='正在傳送文件...'; if cnt<4096
then break; end;
FileClose(iFileHandle); Label2.Caption:='文件傳送完成!';
StatusBar1.Panels[0].Text:='文件傳送完成!'; end; end else
ShowMessage('請選擇要傳送的文件和或接受方地址'); end;
|