基于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的文件传输作了一个初步 ...
随机推荐
- Android.app.SuperNotCalledException错误
- ::): FATAL EXCEPTION: main - ::): android.app.SuperNotCalledException: Activity {com.solar/com.sol ...
- 【HDU5748】Bellovin
Description Peter has a sequence and he define a function on the sequence -- , where is the length ...
- 【t084】数列
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 一个数列定义如下:f(1) = 1,f(2) = 1,f(n) = (A * f(n - 1) + B ...
- 【t080】遗址
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 很久很久以前有一座寺庙,从上往下看寺庙的形状正好是一个正方形,在4个角上竖立着圆柱搭建而成.现在圆柱都 ...
- 支付宝开发之手机网站支付(H5支付)
其实官方的文档中:https://docs.open.alipay.com/203 介绍的已经很详细了,我就实地的看文档操作了一遍,具体步骤如下: 一.创建应用 流程如下: 首先要有支付宝开放平台: ...
- 三步学会用spring开发OSGI——(第一步:环境篇)
Spring-DM是什么 Spring-DM 指的是Spring Dynamic Modules. dm Server 是一个完全模块化部署的,基于OSGi的Java服务器,为运行企业Java应用和S ...
- js进阶 9-12 js如何实现级联菜单 (章节测试)
js进阶 9-12 js如何实现级联菜单 (章节测试) 一.总结 一句话总结: 1.js如何实现级联菜单 ? 二维数组,以第一级菜单的文本值做键,以对应的二级菜单选项的文本做值 2.用哪个属性可以获 ...
- 物理引擎UIDynamic
nUIDynamic n什么是UIDynamic pUIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 p可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 ü重力. ...
- AR Drone系列之:使用ROS catkin创建package并使用cv_bridge实现对ar drone摄像头数据的处理
1 开发环境 Ubuntu 12.04 ROS Hydro 2 前提 可參考这篇blog:http://blog.csdn.net/yake827/article/details/44564057 b ...
- Cocos2d-x V3.2+Cocos Studio1.6 实现一个简单的uibutton点击功能
好久没写博客了 这几天在学习cocos studio,这个软件可以很方便的设计游戏的一些界面,并导入到cocos2dx中,今天就用button来做个样例 首先我们打开Cocos Studio1.6,选 ...