這是網上的經典網路檔案傳輸代碼 具體代碼如下
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; //初始化進度條
ProgressBar1.Position:=0;
SaveDialog1.FileName:=FileName; //指定保存的默認檔案名,一定要在 SaveDialog1.Execute;之前,不然檔案名為空
SaveDialog1.Execute;
sFile:=TFileStream.Create(SaveDialog1.FileName,fmCreate); //創建待寫入的檔案流
While FileSize>4096 do
begin
AThread.Connection.ReadBuffer(rbyte,4096);// 讀取檔案流
sFile.Write(rByte,4096); //寫入檔案流
cnt:=AThread.Connection.ReadInteger; //從發送端接收最新的進度位置資訊
ProgressBar1.Position:=ProgressBar1.Position+cnt; //更新顯示進度
Label1.Caption:='當前接收進度..';
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;
我的問題就出在 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; 貌似程式不能連續進行 IdTCPClient1.WriteBuffer(buf,cnt); 寫操作,我將IdTCPClient1.WriteBuffer(buf,cnt);
IdTCPClient1.WriteInteger(cnt); 兩句注釋掉后,程式能夠正常運行,也就是說檔案分塊的代碼沒有問題,錯就錯在這兩句上
度娘了很長時間得不到解決 程式報錯 class EIdSocketError with message ' Socket Error #0 ’錯誤 Process stopped
但是上一句 IdTCPClient1.WriteLn(ExtractFileName(edtFileName.Text)+'|'+IntToStr(iFileLen)); Server 端 就可以正常接收到這個資訊
請問各位大俠,如何排查上述的錯誤啊 在線等待
uj5u.com熱心網友回復:
沒人回 ,自己頂一下uj5u.com熱心網友回復:
看看把IdTCPClient1.WriteBuffer(buf,cnt);改為IdTCPClient1.WriteBuffer(buf,cnt,true);行不行?uj5u.com熱心網友回復:
看看把IdTCPClient1.WriteBuffer(buf,cnt);
改為
IdTCPClient1.WriteBuffer(buf,cnt,true);
行不行?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/35950.html
標籤:網絡通信/分布式開發
上一篇:c++ 設計模式使用
