IdTCPClient, IdTCPServer 网络文件传输时,IdTCPClient客户端报错 在线等待

chenfeng3000 2018-10-16 10:44:36
这是网上的经典网络文件传输代码 具体代码如下

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 端 就可以正常接收到这个信息
请问各位大侠,如何排查上述的错误啊 在线等待
...全文
449 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenfeng3000 2018-10-16
  • 打赏
  • 举报
回复
没人回 ,自己顶一下
BlueStorm 2018-10-16
  • 打赏
  • 举报
回复
看看把 IdTCPClient1.WriteBuffer(buf,cnt); 改为 IdTCPClient1.WriteBuffer(buf,cnt,true); 行不行?
BlueStorm 2018-10-16
  • 打赏
  • 举报
回复
看看把IdTCPClient1.WriteBuffer(buf,cnt);改为IdTCPClient1.WriteBuffer(buf,cnt,true);行不行?

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧