Delphi IdTCPClient IdTCPServer 点对点传送文件
https://blog.csdn.net/luojianfeng/article/details/53959175
客户端向另一个客户端传送文件,不通过服务端中转
那一个很重要的点是,这个客户端也要放一个IdTCPServer,也就是说这个客户端既是客户端,当接收文件的时候也是服务端,必须相应其它客户
端对它的连接,这个时候客户端相当与服务端,好了,明白这个道理就好办了
A客户端(放一个IdTCPClient控件,发送文件)
procedure TFormFileSend.FormShow(Sender: TObject);//连接到服务端,同时自己变成服务端
begin
//自己变成服务端
IdTCPServer1.Bindings.Clear;
IdTCPServer1.Bindings.Add.IP:='192.168.252.1';
IdTCPServer1.Bindings.Add.Port:=8831;
IdTCPServer1.Active:=true;
if IdTCPServer1.Active then
begin
Memo1.Lines.Add('服务器已启动');
end
else
begin
Memo1.Lines.Add('服务器已停止');
end;
//连接到服务端
IdTCPClient1.Host:=FormMain.host;//'192.168.252.1';
IdTCPClient1.Port:=StrToInt(FormMain.port);//8829;
if IdTCPClient1.Connected then
IdTCPClient1.Disconnect;
Try
IdTCPClient1.Connect;
IdTCPClient1.WriteLn(FormMain.qm+'|'+FormMain.bh);
except
MessageBox(Handle,'服务器没有开启','提示',MB_OK);
Exit;
end;
loading();//连接到服务端,显示上线的客户端
end;
procedure TFormFileSend.loading();
var
Node: TTreeNode;
begin
RzCheckTree1.Items.Clear;
sleep(500);//这里一定要延时,不然下面的数据明明有,但是读不出来, 2016-12-31
with ADOQuery2 do
begin
SQL.Clear;
SQL.Add('select a.ip,a.bh,a.qm,c.qm as bm from ipdz a left join zy b on a.bh=b.bh left join bm c on b.szbm=c.bh ');
Open;
while not Eof do
begin
Node := RzCheckTree1.Items.AddChild(nil,FieldByName('qm').AsString+'('+FieldByName('bm').AsString+')'+FieldByName('ip').AsString);
Node.Data:=strnew(PChar(FieldByName('ip').AsString));
Next;
end;
end;
end;
procedure TFormFileSend.SpeedButton1Click(Sender: TObject);//发送文件
var
iFileHandle:integer;
iFileLen,cnt:integer;
buf:array[0..4096] of byte;
i: integer;
zt:Boolean;
begin
if Edit1.Text='' then
begin
ShowMessage('请选择要上传的文件');
Exit;
end;
zt:=False;
for i:=0 to RzCheckTree1.Items.Count - 1 do
begin
if RzCheckTree1.ItemState[i] = cschecked then
begin
zt:=True;
end;
end;
if zt=False then
begin
Application.MessageBox('请选择接收人!','提示',64);
exit;
end;
for i:=0 to RzCheckTree1.Items.Count - 1 do
begin
if RzCheckTree1.ItemState[i] = cschecked then
begin
IdTCPClient2.Host:=PChar(RzCheckTree1.Items.Item[i].Data);
IdTCPClient2.Port:=8831;
if IdTCPClient2.Connected then
IdTCPClient2.Disconnect;
Try
IdTCPClient2.Connect;
except
Memo1.Lines.Add(RzCheckTree1.Items.Item[i].Text+'不在线');
continue;
end;
iFileHandle:=FileOpen(Edit1.Text,fmOpenRead);
iFileLen:=FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0);
ProgressBar1.Max:=iFileLen;
ProgressBar1.Position := 0;
IdTCPClient2.WriteLn(ExtractFileName(Edit1.Text)+'|'+IntToStr(iFileLen));
while true do
begin
Application.ProcessMessages;
cnt:=FileRead(iFileHandle,buf,4096);
IdTCPClient2.WriteBuffer(buf,cnt);
ProgressBar1.Position:=ProgressBar1.Position + cnt;
Memo1.Lines.Add('正在传送文件...'+DateTimeToStr(Now));
if cnt<4096 then
break;
end;
FileClose(iFileHandle);
Memo1.Lines.Add('文件传送完成!'+DateTimeToStr(Now));
end;
end;
end;
procedure TFormFileSend.SpeedButton5Click(Sender: TObject);//取消发送
var
i:Integer;
begin
FileClose(iFileHandle);
IdTCPClient2.Disconnect;
for i:=0 to RzCheckTree1.Items.Count - 1 do
begin
if RzCheckTree1.ItemState[i] = cschecked then
begin
IdTCPClient2.Host:=PChar(RzCheckTree1.Items.Item[i].Data);
IdTCPClient2.Port:=8831;
if IdTCPClient2.Connected then
IdTCPClient2.Disconnect;
Try
IdTCPClient2.Connect;
except
Memo1.Lines.Add(RzCheckTree1.Items.Item[i].Text+'不在线');
continue;
end;
IdTCPClient2.WriteLn('取消发送');
IdTCPClient2.Disconnect;
end;
end;
//Sleep(500);
Memo1.Lines.Add('取消文件发送'+DateTimeToStr(Now));
end;
B客户端(要放一个IdTCPServer控件,相当于服务端接收)
procedure TFormFileSend.IdTCPServer1Execute(AThread: TIdPeerThread);
var
rbyte:array[0..4096] of byte;
sFile:TFileStream;
cmd,FileSize:integer;
str,FileName:string;
begin
if not AThread.Terminated and AThread.Connection.Connected then //注意这里
begin
with AThread.Connection do
begin
Try
str:=AThread.Connection.ReadLn;
if POS('|',str)>0 then
begin
cmd:=pos('|',str); //查找分隔符
FileName:=copy(str,1,cmd-1); //提取文件名
FileSize:=StrToInt(copy(str,cmd+1,Length(str)-cmd+1)); //提取文件大小
if MessageBox(0,Pchar('您有文件 "'+FileName+'" 您是接受还是拒绝?'),'文件接受',MB_YesNo or MB_ICONQUESTION)=ID_Yes
then //询问是否接收
begin
ProgressBar1.Max:=FileSize div 100; //初始化进度条
ProgressBar1.Position:=0;
SaveDialog1.FileName:=FileName; //指定保存的默认文件名,一定要在 SaveDialog1.Execute;之前,不然文件名为空
SaveDialog1.Execute;
sFile:=TFileStream.Create(SaveDialog1.FileName,fmCreate); //创建待写入的文件流
While FileSize>4096 do
begin
Application.ProcessMessages;
AThread.Connection.ReadBuffer(rbyte,4096);// 读取文件流
ProgressBar1.Position:=ProgressBar1.Position + (4096 div 100); //更新显示进度
Memo1.Lines.Add('正在接收文件中...'+DateTimeToStr(Now));
sFile.Write(rByte,4096); //写入文件流
inc(FileSize,-4096);
end;
AThread.Connection.ReadBuffer(rbyte,FileSize);// .ReadBuffer(rbyte,iLen);
sFile.Write(rByte,FileSize);
sFile.Free;
Memo1.Lines.Add('文件接收完成!'+DateTimeToStr(Now));
end;
end;
Finally
//Disconnect;//断开连接
end;
end;
end;
end;
Delphi IdTCPClient IdTCPServer 点对点传送文件的更多相关文章
- Delphi如何处理不同类型的文件
参考:http://www.cnblogs.com/railgunman/articles/1800318.html 程序设计当中,我们时常遇到需要处理文件.目录及驱动器的情况,这里将对如何处理不同类 ...
- delphi项目中的modelsupport文件夹
delphi项目中的modelsupport文件夹 今天写着写着突然发现多了一个这个文件夹..苦思不得其解 看着又难受 删了又重建 终于找到了 存此备查;Tools--option--toget ...
- SZ,RZ传送文件
linux 和window之间通过xshell的命令 SZ,RZ传送文件:
- python使用简单http协议来传送文件
python使用简单http协议来传送文件!在ubuntu环境下,局域网内可以使用nc来传送文件,也可以使用基于Http协议的方式来下载文件我们可以使用python -m SimpleHTTPServ ...
- 如何用DELPHI编程修改外部EXE文件的版本信
右击里面有修改 点开直接修改就可以了吧. DELPHI 里程序的版本信息怎么是灰色的,无法更改 耐心读以下说明,应该能解决你的问题,如果不能解决,请Hi我~ 如何给自己的dll文件添加版本信息呢? 首 ...
- Delphi使用NativeXml访问XML文件
Delphi使用NativeXml访问XML文件 1.创建XML文件var Doc: TNativeXml;//声明上下文对象var filepath:string;//文件路径DOC:=TNativ ...
- Delphi 封装Frame到Dll文件
做项目的时候,发现这个Frame很好用,为了省空间.调用和修改方便,就将Frame封装到dll(动态链接库)里面,确实很好使. 效果图如下: 上图是临时测试用的,忘了将Frame的align设置成al ...
- Linux SSH 远程操作与传送文件
操作系统:centos 6.5 x64 一.远程连接:在进行linux 的 ssh远程操作前,一定要确认linux 是否安装了 openssh-clients,为了方便起见,一般用yum安装即可:# ...
- SCP传送文件时提示No ECDSA host key is known forx.x.x.x and you have requested strict checking.问题的解决办法
在使用SCP向其他设备传送文件时,打印如下错误: No ECDSA host key is known for x.x.x.x and you have requested strict checki ...
随机推荐
- Docker多主机网络 OpenvSwitch
一.Open vSwitch Open vSwitch(以下简称为OVS),英文全称:OpenVirtual Switch,顾名思义,Open vSwitch就是开放虚拟交换.我们可以把他理解成 ...
- 使用nginx的ngx_upstream_jdomain模块实现k8s容器的负载均衡
使用背景最近一直在准备k8s上线事宜,目前已经在测试环境中全面部署并通过压力测试环境检验.离正式上线基本只剩下时间问题.我们目前测试环境中的容器负载均衡大量使用到了nginx,就是借助了ngx_ups ...
- Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)
Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存 ...
- Machine Learning Trick of the Day (1): Replica Trick
Machine Learning Trick of the Day (1): Replica Trick 'Tricks' of all sorts are used throughout machi ...
- Redis实战(七)Redis开发与运维
Redis用途 1.缓存 Redis提供了键值过期时间设置, 并且也提供了灵活控制最大内存和内存溢出后的淘汰策略. 可以这么说, 一个合理的缓存设计能够为一个网站的稳定保驾护航. 2.排行榜系统 Re ...
- 20155330 2016-2017-2 《Java程序设计》第五周学习总结
20155330 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 学习目标 理解异常架构 掌握try...catch...finally处理异常的方法 会用t ...
- zedboard 初使用 -- 工具篇
<一> 安装ISE和Vivada: <二> 安装USB转UART驱动 <三> 安装USB转JTAG驱动插件 http://blog.sina.com.cn/s/bl ...
- Ubuntu 问题汇总
1..bashrc环境变量失效,ls.cp等命令不能使用了: export PATH=/usr/bin:/bin 2.添加环境变量 echo '********' >> ~/.bashrc ...
- Ubuntu 12.04 更新源的方法及地址
本文章转自:http://www.maybe520.net/blog/424/ 安装好ubuntu 12.04之后,可以联网之后,马上要做的最重要的事情之一就是配置更新源列表,这样以后安装更新或者软件 ...
- 突破XSS字符限制执行任意JS代码
突破XSS字符限制执行任意JS代码 一.综述 有些XSS漏洞由于字符数量有限制而没法有效的利用,只能弹出一个对话框来YY,本文主要讨论如何突破字符数量的限制进行有效的利用,这里对有效利用的定义是可以不 ...