用TTcpClient和TTcpServer进行文件的传输
发送数据时有Sendln,SendBuf,SendStream。接收数据时有Receiveln,ReceiveBuf,当时我很奇怪为什么没有ReceiveStream。因为很自然的想到是对应关系的。但当时我不知道,发数据时是一小段一小段地发的
看看SendStream代码:
- function TBaseSocket.SendStream(AStream: TStream): Integer;
- var
- BufLen: Integer;
- Buffer: array[0..511] of Byte;
- begin
- Result := 0;
- if Assigned(AStream) then
- begin
- repeat
- BufLen := AStream.Read(Buffer, SizeOf(Buffer));
- until (BufLen = 0) or (SendBuf(Buffer, BufLen) = SOCKET_ERROR);
- end;
- end;
从以上代码可看到,SendStream一次最多发送512字节的内容,所以,我们这接收端循环用ReceiveBuf接收就可以了。不用像以前那样写得又复杂乱。
发送端(Client)代码:
- unit Unit1;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, Sockets;
- type
- TForm1 = class(TForm)
- tcpclnt1: TTcpClient;
- btn1: TButton;
- procedure btn1Click(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- var
- Form1: TForm1;
- implementation
- {$R *.dfm}
- procedure TForm1.btn1Click(Sender: TObject);
- var
- f : TFileStream;//文件流
- i : Integer;
- fn : string;//文件名
- begin
- {用for循环是实现发送多个文件,如果只是发送一个文件,不用循环}
- for i := 1 to 11 do
- begin
- tcpclnt1.Connect; //连接服务端,我把TTcpClient的BlockMode设为bmBlocking
- fn := 'a' + IntToStr(i) + '.rar';
- f := TFileStream.Create('d:/send/' + fn,fmOpenRead); //用文件流以读方式打开要发送的文件
- tcpclnt1.Sendln(fn); //给对方发送文件名
- tcpclnt1.Sendln(IntToStr(f.Size)); //给对方发送文件大小
- tcpclnt1.SendStream(f); //发送文件流
- f.Free;//释放文件流
- tcpclnt1.Disconnect;//关闭连接
- end;
- end;
- end.
接收端(Server)代码:
- unit Unit1;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, Sockets;
- type
- TForm1 = class(TForm)
- tcpsrvr1: TTcpServer;
- procedure FormActivate(Sender: TObject);
- procedure tcpsrvr1Accept(Sender: TObject;
- ClientSocket: TCustomIpClient);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- var
- Form1: TForm1;
- implementation
- {$R *.dfm}
- procedure TForm1.FormActivate(Sender: TObject);
- begin
- tcpsrvr1.Open; //在OnActive事件中启动TCPServer的监听
- end;
- procedure TForm1.tcpsrvr1Accept(Sender: TObject;
- ClientSocket: TCustomIpClient);
- var
- f : TFileStream; //文件流
- iFileSize : Integer; //文件大小
- iTotalRec : Integer; //总接收到的字节数,用来和文件大小比较,如果比文件大小的值要小,就还要继续接收
- iacRec : Integer; //每一次ReceiveBuf实际接收到的字节数
- pbuf : Pointer; //缓存指针
- i : Integer;
- fn : string; //文件名
- begin
- GetMem(pbuf,512); //我们一次最多也读取512字节
- try
- iTotalRec := 0; //先把总接收到的字节数置零
- fn := ClientSocket.Receiveln; //接收文件名
- iFileSize := StrToInt(ClientSocket.Receiveln); //接收文件大小,接收到的字符串,要转成integer
- f := TFileStream.Create('d:/rec/'+ fn,fmCreate);//创建文件
- try
- {如果接收到的总字节数小于文件总字节数且实际接收字节数不为-1就一直循环接收}
- while iTotalRec < iFileSize do
- begin
- iacRec := ClientSocket.ReceiveBuf(pbuf^,512);//一次接收512字节
- if iacRec = -1 then
- Break;//如果实际接收字节数是-1表示出错了,退出循环(应该写个log,或作出错处理什么的)
- f.Write(pbuf^,iacRec);//把接收到的数据写到文件流中
- Inc(iTotalRec,iacRec);//叠加接收到的总字节数
- end;
- finally
- f.Free; //释放流
- end;
- finally
- FreeMem(pbuf);//释放内存
- end;
- end;
- end.

用TTcpClient和TTcpServer进行文件的传输的更多相关文章
- windows与linux之间文件的传输方式总结(转)
当然,windows与linux之间文件的传输的两种方式有很多,这里就仅仅列出工作中遇到的,作为笔记: 方法一:安装SSH Secure Shell Client客户端 安装即可登录直接拖拉到linu ...
- Linux SSH远程文件/目录传输命令scp
转载地址:http://www.vpser.net/manage/scp.html 相信各位VPSer在使用VPS时会经常在不同VPS间互相备份数据或者转移数据,大部分情况下VPS上都已经安装了Ngi ...
- C# TCP实现多个客户端与服务端 数据 与 文件的传输
C#菜鸟做这个东东竟然花了快三天的时间了,真是菜,菜,菜--- 下面是我用C#写的 一个简单的TCP通信,主要的功能有: (1) 多个客户端与服务器间的数据交流 (2)可以实现群发的功能 (3)客户端 ...
- Linux scp 远程文件/目录传输
Linux scp远程文件/目录传输 1.获取远程服务器上的文件 scp -P 22 root@www.test.com:/root/test.tar.gz /home/test.tar.gz 上端口 ...
- DOS命令行使用pscp实现远程文件和文件夹传输(转)
转自 http://snailwarrior.blog.51cto.com/680306/141201 pscp是putty安装包所带的远程文件传输工具,使用和Linux下scp命令相似,具体的使 ...
- 简单实现TCP下的大文件高效传输
简单实现TCP下的大文件高效传输 在TCP下进行大文件传输不象小文件那样直接打包个BUFFER发送出去,因为文件比较大所以不可能把文件读到一个BUFFER发送出去.主要有些文件的大小可能是1G,2G或 ...
- windows与linux之间文件的传输
这边记录一下如何在windows与linux之间进行文件的传输,下面是具体的网址. 原文地址::http://blog.csdn.net/shufac/article/details/51966276 ...
- Windows与Linux之间海量文件的传输与Linux下大小写敏感问题
Windows与Linux之间海量文件的传输与Linux下大小写敏感问题 mount.cifs 支持通过网络文件系统挂载,不过需要安装cifs-utils,也可通过mount -t cifs挂载,详细 ...
- 使用linux的nc来进行文件的传输
NAME nc - arbitrary TCP and UDP connections and listensSYNOPSIS nc [-46DdhklnrStUuvz] [-i interv ...
随机推荐
- js中 慎用for(var o in arrays) 遍历数组,for(var i,i< objects.length;i++)与for(var i,n = objects.length;i<n;i++) 的性能区别
原文:js中 慎用for(var o in arrays) 遍历数组,for(var i,i< objects.length;i++)与for(var i,n = objects.length; ...
- XMPP之安装mySQL--Mac OS(一)
come from:http://www.cnblogs.com/xiaodao/archive/2013/04/04/2999426.html 一.安装 到MySQL官网上http://dev.my ...
- 【codeforces 782D】 Innokenty and a Football League
[题目链接]:http://codeforces.com/contest/782 [题意] 每个队名有两种选择, 然后第一个选择队名相同的那些队只能选第二种; 让你安排队名 [题解] 首先全都选成第一 ...
- 征服OA 飞鱼工作流程的在线培训课程(两)HTML形成基于
表HTML的重要作用,等效混凝土框架建筑的行,于div在此之前流行.是否所有形式的世界.在角色表页面主要是针对页面布局和定位.通过整合人才规划表设计出合理的页面布局. 当然.更重要的是,存在是表示数据 ...
- docker部署netcore应用(二)
基于第一章已经安装好了docker,这次将把netcore应用部署到docker容器中 开发工具vs2017,准备个DotNet Core的Console应用程序,测试一下 发布DockerTest项 ...
- OVS处理upcall流程分析
处理upcall总体框架: 1.由函数handle_upcalls()批量处理(in batches)的是由内核传上来的dpif_upcalls,会解析出upcall的类型.这里主要看在内核中匹配流表 ...
- 【16.56%】【codeforces 687B】Remainders Game
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- exec 与 open 打开进程
1 exec ?-keepnewline ?-ignorestderr args(?号后面表示可以跟的参数) 这个东西一旦执行 , 没有执行完毕父进程会处于等待中 使用一个或多个子进程运行 由arg ...
- Android, iOS, 各种软件汇总
Android: 长截图:软件叫PPIICC的可以截图之后拼接:有些手机自带截图,比如小米,华为,三星等. 视频:全格式的Kodi XBMC, 一般的:moboplayer, VLC, F蔷:***, ...
- 如何获得 Qt窗口部件在主窗口中的位置--确定鼠标是否在某一控件上与在控件上的位置
用Qt Creator 设计程序时,最方便的就是ui设计器,可以很容易的得到想要的布局. 但是这样自动布局带来的后果是很难知道窗口中某一部件在主窗口中的相对位置. 在处理子窗口鼠标事件时变的很麻烦.主 ...