基于IOCP的高速文件传输代码
//服务端:
const //transmit用的参数 TF_USE_KERNEL_APC = $20; //命令类型 CMD_CapScreen = 2000; CMD_CapVideo = 2001; CMD_CapAudio = 2002; CMD_GetSystemInfo = 2003; CMD_TransmitFiles = 2004; //通用数据传输包体封装type //每个完整数据的头描述 TPacketHeader = packed record PacketCMD : Word; //包类型 DataLength : Word; //包体长度 IsCompressed : Boolean; //包体是否为压缩数据 end; TBytes = array [0..65535] of Byte; TPacketBody = packed record Data : TBytes; end; //完整的数据包 TPacketInfo = packed record Header : TPacketHeader; Body : TPacketBody; end; //文件发送包 TFileSendPacket = packed record FileName : array [0..127] of Char; FileSize : LongWord; StartWritePositon : LongWord; hFile : THandle; end;function TServerClientSocket.TransFile(FileName: string;StartWritePositon:LongWord): Boolean;var hFile : THandle; NumberOfByteSend : LongWord; Block:PBlock; PacketInfo: TPacketInfo; FileSendPacket : TFileSendPacket; AFileName : string[128]; TransmitFileBuffers : TTransmitFileBuffers;begin if not FileExists(FileName) then begin Result := False; Exit; end; hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); //如果文件打开错误,则退出 if hFile = INVALID_HANDLE_VALUE then begin Result := False; Closehandle(hFile); Exit; end; //得到需要传输的字节数 NumberOfByteSend := windows.GetFileSize(hFile, nil) - StartWritePositon; if NumberOfByteSend <= 0 then begin Closehandle(hFile); Exit; end; Block := AllocBlock; Block.Data.Event := seFileSend; Block.Data.Overlapped.Offset := StartWritePositon; AFileName := ExtractFileName(FileName); FillChar(PacketInfo,SizeOf(TPacketInfo),0); FillChar(FileSendPacket,SizeOf(TFileSendPacket),0); Move(AFileName[1],FileSendPacket.FileName,length(AFileName)); FileSendPacket.FileSize := NumberOfByteSend; FileSendPacket.StartWritePositon := StartWritePositon; FileSendPacket.hFile := hFile; PacketInfo.Header.PacketCMD := CMD_TransmitFiles; PacketInfo.Header.DataLength := Sizeof(TFileSendPacket); PacketInfo.Header.IsCompressed := False; Move(FileSendPacket,PacketInfo.Body.Data,SizeOf(TFileSendPacket)); Move(PacketInfo,Block^.Data.Buffer,SizeOf(TPacketHeader) + SizeOf(TFileSendPacket)); //传输文件前发送的包 TransmitFileBuffers.Head := @Block^.Data.Buffer[0]; TransmitFileBuffers.HeadLength := SizeOf(TPacketHeader) + SizeOf(TFileSendPacket); //传输文件完毕后发送的包 TransmitFileBuffers.Tail := nil; TransmitFileBuffers.TailLength := 0; LogMsg('开始发送文件:' + FileName + ' Size=' + IntToStr(NumberOfByteSend)); //发送命令,并将文件名、继传点、需要传输的大小传递过去 if not TransmitFile(SocketHandle, hFile, NumberOfByteSend, MAX_BUFSIZE, @Block^.Data.Overlapped, @TransmitFileBuffers, TF_USE_KERNEL_APC) then begin if GetLastError <> ERROR_IO_PENDING then begin Result := False; Exit; end; end; Result := True;end;//如果发送完毕,可以接收到重叠IO的返回结果 case Block^.Data.Event of seFileSend: begin Block.IsUse := False; Move(Block.Data.Buffer,PacketInfo,SizeOf(TPacketHeader) + SizeOf(TFileSendPacket)); if PacketInfo.Header.PacketCMD = CMD_TransmitFiles then begin FillChar(FileSendPacket,SizeOf(TFileSendPacket),0); Move(PacketInfo.body.data,FileSendPacket,SizeOf(TFileSendPacket)); Closehandle(FileSendPacket.hFile); //发送完毕,关闭文件句柄 end; LogMsg('文件:' + StrPas(FileSendPacket.FileName) + ' 发送完毕!'); if not PrepareRecv() then Result := RESPONSE_FAIL; end; seRead: 。。。。。。。 //客户端:procedure TrecvThread.Execute;var PacketInfo : TPacketInfo; str: string; FileSendPacket:TFileSendPacket; FileStream:TFileStream; FileName :string; RecBuf:array[0..1023] of Char; RemainByts,RecvedBytes:Integer;begin while (not self.Terminated ) DO begin cs.CheckForDisconnect(False); if cs.ClosedGracefully then begin Fmm.Lines.Add('链路断开!'); self.Terminate; end; cs.ReadBuffer(PacketInfo.Header,SizeOf(TPacketHeader)); cs.ReadBuffer(PacketInfo.Body.Data, PacketInfo.Header.DataLength); if PacketInfo.Header.PacketCMD = CMD_TransmitFiles then begin Move(PacketInfo.Body.Data,FileSendPacket,PacketInfo.Header.DataLength); FileName := StrPas(FileSendPacket.FileName); try FileStream := TFileStream.Create('C:\'+ FileName, fmCreate or fmOpenWrite); Fmm.Lines.Add('接收:' + FileName + ' Size=' + IntToStr(FileSendPacket.FileSize)); RecvedBytes := 0; while (RecvedBytes < FileSendPacket.FileSize) do begin if FileSendPacket.FileSize <= 1024 then begin cs.ReadBuffer(RecBuf,FileSendPacket.FileSize); RecvedBytes := FileSendPacket.FileSize; FileStream.WriteBuffer(RecBuf,RecvedBytes); Break; end else begin cs.ReadBuffer(RecBuf,1024); RecvedBytes := RecvedBytes + 1024; FileStream.WriteBuffer(RecBuf,1024); RemainByts := FileSendPacket.FileSize - RecvedBytes; if RemainByts <= 1024 then begin cs.ReadBuffer(RecBuf,RemainByts); RecvedBytes := RecvedBytes + RemainByts; FileStream.WriteBuffer(RecBuf,RemainByts); Break; end; end; end; finally FileStream.Free; end; end; end;end;http://www.delphi6.com/thread-554.htm
基于IOCP的高速文件传输代码的更多相关文章
- Tftp文件传输服务器(基于UDP协议)
一个简单的UDP服务端与客户端 服务端: from socket import * #创建套接字 udp_server = socket(AF_INET,SOCK_DGRAM) msg_server ...
- WCF大文件传输服务
由于项目需要,自己写一个基于WCF的大文件传输服务雏形.觉得有一定的参考价值,因此放在网上分享. 目前版本为v1.1特点如下: 1.文件传输端口为18650 2.上传和下载文件 3.支持获取文件传输状 ...
- vsftpd-基于ftp协议的文件传输服务器软件
第一部分:在Linux上部署vsftpd服务 1. vsftpd简介 1.1 vsftpd是什么? ftp(File Transfer Protocol)文件传输协议.(实现不同操作系统之间文件的传输 ...
- QT从入门到入土(九)——TCP/IP网络通信(以及文件传输)
引言 TCP/IP通信(即SOCKET通信)是通过网线将服务器Server端和客户机Client端进行连接,在遵循ISO/OSI模型的四层层级构架的基础上通过TCP/IP协议建立的通讯.控制器可以设置 ...
- Python之路(第三十二篇) 网络编程:udp套接字、简单文件传输
一.UDP套接字 服务端 # udp是无链接的,先启动哪一端都不会报错 # udp没有链接,与tcp相比没有链接循环,只有通讯循环 server = socket.socket(socket.AF_I ...
- Python实现终端FTP文件传输
实现终端FTP文件传输 代码结构: .├── client.py├── readme.txt└── server.py 运行截图: readme.txt tftp文件服务器 项目功能: * 客户端有简 ...
- Python自带HTTP文件传输服务
一行命令搭建一个基于python的http文件传输服务 由于今天朋友想要一个文件,而我恰好有,因为这个文件比较大,网速不是很给力,所以想到了python自己有这么一个功能,这样不仅不需要下载其他软件, ...
- Java基于Socket文件传输示例(转)
最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加 ...
- Java基于Socket文件传输示例
http://www.blogjava.net/sterning/archive/2007/10/13/152508.html 最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步 ...
随机推荐
- #308 (div.2) B. Vanya and Books
1.题目描写叙述:点击打开链接 2.解题思路:本题要求统计数位的个数,简单的试验一下发现有例如以下规律:一个n位数的个数有9*(10^n)个.因此全部n位数的数位是n*9*(10^n)个.因此能够利用 ...
- strong & weak 的理解
import "ViewController.h" @interface ViewController () /*weak*/ @property (nonatomic,weak) ...
- 在CentOS上使用Nginx和Tomcat搭建高可用高并发网站
目录 目录 前言 创建CentOS虚拟机 安装Nginx 安装Tomcat 安装lvs和keepalived 反向代理 部署网站 搭建数据库 编写网站项目 解决session一致性 注意 参考资料 前 ...
- 联想笔记本装win7
http://jingyan.baidu.com/article/7c6fb42862d63a80642c90b8.html http://bbs.thinkworldshop.com.cn/thre ...
- 《学习opencv》笔记——关于一些画图的函数
画图函数 (1)直线cvLine函数 其结构 void cvLine(//画直线 CvArr* array,//画布图像 CvPoint pt1,//起始点 CvPoint pt2,//终点 CvSc ...
- .net程序客户端更新方案
原文:.net程序客户端更新方案 客户端程序一个很大的不便的地方就是程序集更新,本文这里简单的介绍一种通用的客户端更新方案.这个方案依赖程序集的动态加载,具体方案如下: 将程序集存储在一个文件数据库中 ...
- 有奖试读&征文--当青春遇上互联网,是否能点燃你的创业梦
时至今日,互联网已经切入我们每一个人的工作.生活和学习的每一个角落.利用互联网这个工具,有人游戏,有人购物,有人上课,有人交友,而有那么一部分人去利用它完毕人生最完美的逆袭.相信每一个人心中都有个创业 ...
- 【44.19%】【codeforces 608D】Zuma
time limit per test2 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...
- 【非常高%】【codeforces 733B】Parade
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- Android之消息推送实现
在开发Android和iPhone应用程序时,我们往往需要从服务器不定的向手机客户端即时推送各种通知消息,iPhone上已经有了比较简单的和完美的推送通知解决方案,可是Android平台上实现起来却相 ...