delphi 自带的TIdFtpServer和TIdFtpClient组件,在实际应用中发现,只能单线程传输较小的文件。有很大局限性。决定自己写一个文件传输系统。该传输系统经测试,可以同时传输100个文件以上,超过4G大小的文件,支持断点续传。同时支持对文件夹的压缩传输。基本满足业务的要求。现在把服务器端和客户端代码粘贴如下:
一、服务器端
unit uTransFileSrv;
interface
uses winsock,windows,graphics,classes,uStr,uFuncs,system.zip,uConfig;
const
wm_user=$0400;
wm_TransData=wm_user+100+1;
MAXBUF=8192;
MAXPATH=260;
UID:integer=8888;//包头标识;
VER:integer=1002;
ENC:integer=7620;
CMD_READY:integer=1001;//准备好命令;
CMD_FILE_LIST=4001;//列举目录;传递绝对路径;
CMD_FILE_TRANS=4002;//文件传输
CMD_FILE_DEL=4003;//删除文件
type
POrderHeader=^stOrderHeader;
stOrderHeader=packed record
uid:DWORD;
Ver:DWORD;
Enc:DWORD;
id:DWORD;
pid:DWORD;
cmd:DWORD;
len:DWORD;
dat:pointer;
end;
TThreadType=(FTransFile,FGetRet,FTypeClient,FListenSocket,FMainThread,FTransfer,FTransferMain,FRecvData,FListFile );
Torder=(FStart,Fclose);
TAPIFlag=(FWSAStartup,Fsocket,Fsetsockopt,Fbind,Flisten,Faccept,Frecv,FcreateFile,FGetFileSize,Fsend,FRecv2,
FWriteFile,FSetFilePointer,Frecv_S,FSetFilePointer_S,FReadFile_S,FReadFile_S1,Fsend_S,Fcreatethread,
FGetFileAttributes,FDirectoryCompression,FDirectoryCompression_1,FDirectoryDecompression_1,FDirectoryDecompression,
Fdeletefile,FRecv3,FCreateDIBSection,FNull,FthreadStart,FthreadEnd,Fverify,FPackageEnd);
TAPIType=(Fwindows,Fsock);
TRequestType=(RTransFile,RListFile,RRecvData);
pSocket=^stSocket;
stSocket=packed record
socketHandle:tsocket;
addr:tsockaddr;
addrLen:integer;
end;
pRunAPIInfo=^stRunAPIInfo;
stRunAPIInfo=packed record
aAPI:TAPIFlag;
APIType:TAPIType;
result:integer;
errCode:integer;
Info:array[0..1023] of ansiChar;
end;
pTransRate=^stTransRate;
stTransRate=packed record
Transed:cardinal;
TransedHigh:cardinal;
Speed:int64;
end;
pFileInfo=^stFileInfo;
stFileInfo=packed record
hFile:cardinal;
isUpLoad:bool;
FileName:array[0..MAXPATH-1] of ansiChar;
FileSize:cardinal;
FileSizeHigh:cardinal;
ClientFileSize:cardinal;
ClientFileSizeHigh:cardinal;
end;
pSendMsgTo=^stSendMsgTo;
stSendMsgTo=packed record
hform:hwnd;
msgType:cardinal;
end;
pThreadInfo=^stThreadInfo;
stThreadInfo=packed record
threadType:TThreadType;
active:bool;
hThread:cardinal;
threadID:cardinal;
end;
pMainTread=^stMainTread;
stMainTread=packed record
threadType:TThreadType;
order:Torder;
num:integer;
end;
pListenSocket=^stListenSocket;
stListenSocket=packed record
thread:stThreadInfo;
runAPI:stRunAPIInfo;
sendMsg:stSendMsgTo;
socket:stSocket;
wsadata: TWSAData;
port:DWORD;
num:integer;
end;
pTypeCS=^stTypeCS;
stTypeCS=packed record
thread:stThreadInfo;
runAPI:stRunAPIInfo;
sendMsg:stSendMsgTo;
socket:stSocket;
TransType:TThreadType;
oh:stOrderHeader;
num:integer;
end;
pTransFilesCS=^stTransFilesCS;
stTransFilesCS=packed record
thread:stThreadInfo;
runAPI:stRunAPIInfo;
sendMsg:stSendMsgTo;
socket:stSocket;
fileInfo:stFileInfo;
transRate:stTransRate;
end;
pSvrAddr=^stSvrAddr;
stSvrAddr=packed record
port:Word;
case flg:byte of
0:(IP:array[0..15] of ansiChar);
1:(DN:array[0..30] of ansiChar);
end;
stRequestFileInfo=packed record
fileName:array[0..MAXPATH-1] of ansiChar;
bUpLoad:bool;
end;//
pTransFilesInfo=^stTransFilesInfo;
stTransFilesInfo=packed record
clientFile:array[0..MAX_PATH-1] of ansiChar;
serverFile:array[0..MAX_PATH-1] of ansiChar;
iRootDir:DWORD;
bUpLoad:bool;
bFolder:bool;
bCompleteDel:bool;
end;
pRecvDataCS=^stRecvDataCS;
stRecvDataCS=packed record
thread:stThreadInfo;
runAPI:stRunAPIInfo;
sendMsg:stSendMsgTo;
socket:stSocket;
oh:stOrderHeader;
transRate:stTransRate;
num:integer;
data:pointer;
dataSize:integer;
end;
pListFileCS=^stListFileCS;
stListFileCS=packed record
thread:stThreadInfo;
runAPI:stRunAPIInfo;
sendMsg:stSendMsgTo;
socket:stSocket;
oh:stOrderHeader;
transRate:stTransRate;
num:integer;
filename:array[0..MAX_PATH-1] of ansiChar;
end;
function VerifyOH(oh:stOrderHeader) :boolean;//校验包头;
function formatOH(var oh:stOrderHeader) :stOrderHeader;//格式化包头;
procedure TransDataThread(pLisenSocketInfo:pointer);stdcall;
//function RunAPIOK(pThreadDataInfo:pointer):bool;stdcall;
procedure GetAPIErrCode(pRun:pRunAPIInfo);stdcall;
procedure TransTypeThread(pClientSocketInfo:pointer);stdcall;
procedure TransDirThread(pTransFilesInfo:pointer);stdcall;
function TransDirAPI(pTransFilesInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
procedure TransFileThread(pTransFileInfo:pointer);stdcall;
function TransFileAPI(pTransFileInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
function TransTypeAPI(pTransTypeInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
function TransDataAPI(pLisenSocketInfo:pointer;FAPI:TAPIFlag):bool;stdcall;
procedure RecvDataThread(pRecvInfo:pointer);stdcall;
function RecvDataAPI(pRcvDataInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
procedure ListFileThread(pListInfo:pointer);stdcall;
function ListFileAPI(pListInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
function getListFileInfo():ansiString;
var
workdir,upDir,downDir:ansiString;
pDatas:tlist;
implementation
function getListFileInfo():ansiString;
var
filename:array[0..MAX_PATH-1] of ansiChar;
filesize:array[0..31] of ansiChar;
wfd:WIN32_FIND_DATAA;
hFindFile:THANDLE;
//fa:ansiChar;
begin
result:='';
strcopy(filename,pansichar(ansiString(uConfig.updir)));
strcat(filename,pansichar('\*'));
hFindFile:=FindFirstFileA(filename,wfd);
if hFindFile=INVALID_HANDLE_VALUE then exit;
while(FindNextFileA(hFindFile,wfd))do
begin
if(wfd.cFileName[0]='.')then continue;
if(wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)<>0 then continue;
inttostr(wfd.nFileSizeLow,filesize);
result:=result+wfd.cFileName+';'+filesize+#13#10;
end;
Windows.FindClose(hFindFile);
end;
procedure ListFileThread(pListInfo:pointer);stdcall;
var
pData:pListFileCS;
len,i:cardinal;
fileList:ansiString;
begin
pData:=pListInfo;
ListFileAPI(pData,FthreadStart);
try
fileList:=getListFileInfo();
len:=length(fileList);
if(len=0)then exit;
pdata^.oh.len:=len;
pData^.runAPI.result:=send(pData^.socket.socketHandle,pdata^.oh,sizeof(stOrderHeader),0);
if not ListFileAPI(pData,Fsend) then exit;
i:=1;
pData^.runAPI.result:=0;
while len>0 do
begin
pData^.runAPI.result:=send(pData^.socket.socketHandle,fileList[i],len,0);
if not ListFileAPI(pData,Fsend) then exit;
i:=i+pData^.runAPI.result;
len:=len-pData^.runAPI.result;
end;
finally
ListFileAPI(pData,FthreadEnd);
//sendMessage(pData^.sendMsg.hform,pData^.sendMsg.msgType,0,integer(pData));
end;
end;
function ListFileAPI(pListInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
label 1;
var
pData:pListFileCS;
pRun:pRunAPIInfo;
pThreadDataInfo:pThreadInfo;
pSock:pSocket;
pMsg:pSendMsgTo;
begin
result:=true;
pThreadDataInfo:=pListInfo;
pData:=pListInfo;
pRun:=pRunAPIInfo(pansiChar(pData)+sizeof(stThreadInfo));
pMsg:=pSendMsgTo(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo));
pSock:=pSocket(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo)+sizeof(stSendMsgTo));
pRun^.aAPI:=FAPI;
case pData^.runAPI.aAPI of
FthreadStart:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'列文件线程开始!');
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
Fsend:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>SOCKET_ERROR then exit;
strcopy(pRun^.Info,'发送数据失败!');
end;//Fsend
FthreadEnd:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'列文件线程结束!');
SendMessage(pMsg^.hform,pMsg^.msgType,1,integer(pData));
goto 1;
end;
end;//case
GetAPIErrCode(pRun);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
result:=false;
1:
closesocket(pSock^.socketHandle);
pThreadDataInfo^.active:=false;
if (pData^.oh.Dat<>nil) then begin freemem(pData^.oh.Dat);pData^.oh.Dat:=nil;end;
dispose(pData);
end;
procedure TransDataThread(pLisenSocketInfo:pointer);stdcall;
var
flag:bool;
pData:pListenSocket;
pClient:pTypeCS;
begin
with pData^.runAPI,pData^.socket do
begin
pData:=pLisenSocketInfo;
TransDataAPI(pData,FthreadStart);
pData^.runAPI.result:=WSAStartup($0202,pData^.wsadata);
if not TransDataAPI(pData,FWSAStartup) then exit;
pData^.runAPI.result:=socket(AF_INET, SOCK_STREAM, 0); //SOCK_DGRAM
if not TransDataAPI(pData,Fsocket) then exit;
pData^.socket.socketHandle:=pData^.runAPI.result;
pData^.runAPI.result:=setsockopt(pData^.socket.socketHandle,SOL_SOCKET,SO_REUSEADDR,@flag,sizeof(flag));
if not TransDataAPI(pData,Fsetsockopt) then exit;
zeromemory(@(pData^.socket.addr),sizeof(pData^.socket.addr));
pData^.socket.addr.sin_family:=AF_INET;
pData^.socket.addr.sin_port:=htons(pData^.PORT);
pData^.socket.addr.sin_addr.s_addr:=htonl(INADDR_ANY);
pData^.runAPI.result:=bind(pData^.socket.socketHandle,pData^.socket.addr,sizeof(pData^.socket.addr));
if not TransDataAPI(pData,Fbind) then exit;
pData^.runAPI.result:=listen(pData^.socket.socketHandle,5);
if not TransDataAPI(pData,Flisten) then exit;
end;//with
while true do
begin
new(pClient);
pClient^.thread.active:=true;
pClient^.thread.threadType:=FTypeClient;
pClient^.sendMsg.hform:=pData^.sendMsg.hform;
pClient^.sendMsg.msgType:=pData^.sendMsg.msgType;
zeromemory(@(pClient^.socket.Addr),sizeof(pClient^.socket.addr));
pClient^.socket.AddrLen:=sizeof(pClient^.socket.addr);
pClient^.num:=pData^.num;
//pClient^.socket.socketHandle:=Accept(pData^.socket.socketHandle,@(pClient^.socket.Addr),@(pClient^.socket.AddrLen));
pData^.runAPI.result:=Accept(pData^.socket.socketHandle,@(pClient^.socket.Addr),@(pClient^.socket.AddrLen));
if not TransDataAPI(pData,Faccept) then
begin
dispose(pClient);
if pData^.runAPI.errCode=WSAENOTSOCK then
begin
pData^.thread.active:=false;
closesocket(pData^.socket.socketHandle);
WSACleanup();
dispose(pData);
exit;
end
else begin
continue;
end;//if
end;
pClient^.socket.socketHandle:=pData^.runAPI.result;
pData^.runAPI.result:=createthread(nil,0,@TransTypeThread,pClient,0,pClient^.thread.threadID);
if not TransDataAPI(pData,Fcreatethread) then
begin
dispose(pClient);
continue;
end;
pClient^.thread.hThread:=pData^.runAPI.result;
end;//while
end;
function TransDataAPI(pLisenSocketInfo:pointer;FAPI:TAPIFlag):bool;stdcall;
var
pData:pListenSocket;
pRun:pRunAPIInfo;
pThreadDataInfo:pThreadInfo;
pSock:pSocket;
pMsg:pSendMsgTo;
begin
result:=true;
pThreadDataInfo:=pLisenSocketInfo;
pData:=pLisenSocketInfo;
pRun:=pRunAPIInfo(pansiChar(pData)+sizeof(stThreadInfo));
pMsg:=pSendMsgTo(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo));
pSock:=pSocket(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo)+sizeof(stSendMsgTo));
pRun^.aAPI:=FAPI;
case pRun^.aAPI of
FthreadStart:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'主线程开始!');
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
FWSAStartup:
begin
pRun^.APIType:=Fsock;
if pRun^.result=0 then exit;
strcopy(pRun^.Info,'初始化WS2_32.DLL失败!错误代码是:');
end;//FWSAStartup
Fsocket:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>INVALID_SOCKET then
begin
strcopy(pRun^.Info,'创建侦听socket!');
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
strcopy(pRun^.Info,'创建socket失败!!错误代码是:');
end;//Fsocket
Fsetsockopt:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>SOCKET_ERROR then exit;
strcopy(pRun^.Info,'setsockopt失败!错误代码是:');
end;//Fsetsockopt
Fbind:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>SOCKET_ERROR then exit;
strcopy(pRun^.Info,'绑定socket失败!错误代码是:');
end;//Fbind
Flisten:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>SOCKET_ERROR then
begin
strcopy(pRun^.Info,'服务处于等待中...');
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
strcopy(pRun^.Info,'侦听端口失败!错误代码是:');
end;//Flisten
Faccept:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>INVALID_SOCKET then exit;
strcopy(pRun^.Info,'接受连接失败!错误代码是:');
GetAPIErrCode(pRun);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;//Faccept
FcreateThread:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>0 then exit;
strcopy(pRun^.Info,'创建线程失败!错误代码是:');
GetAPIErrCode(pRun);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;//
end;//case
GetAPIErrCode(pRun);
pThreadDataInfo^.active:=false;
closesocket(pSock^.socketHandle);
WSACleanup();
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
dispose(pData);
result:=false;
end;
procedure TransTypeThread(pClientSocketInfo:pointer);stdcall;
var
pData:pTypeCS;
bTransType:TRequestType;
pTF:pTransFilesCS;
pRD:pRecvDataCS;
pLF:pListFileCS;
begin
pData:=pClientSocketInfo;
TransTypeAPI(pData,FthreadStart);
pData^.runAPI.result:=Recv(pData^.socket.socketHandle,pData^.oh,sizeof(stOrderHeader),0);
if not TransTypeAPI(pData,Frecv) then exit;
//verify connect validity:
if not TransTypeAPI(pData,Fverify) then exit;
if pData^.oh.cmd=CMD_FILE_TRANS then bTransType:=RTransFile
else if pData^.oh.cmd=CMD_FILE_LIST then bTransType:=RListFile
else bTransType:=RRecvData;
case bTransType of
RTransFile:
begin
new(pTF);
pTF^.thread.threadType:=FTransFile;
pTF^.sendMsg:=pData^.sendMsg;
pTF^.socket:=pData^.socket;
pTF^.thread.active:=true;
pData^.TransType:=pTF^.thread.threadType;
pData^.runAPI.result:=createthread(nil,0,@TransDirThread,pTF,0,pTF^.thread.threadID);
if not TransTypeAPI(pData,Fcreatethread) then
begin
dispose(pTF);
exit;
end;
pTF^.thread.hThread:=pData^.runAPI.result;
end;
RListFile:
begin
new(pLF);
zeromemory(pLF,sizeof(stListFileCS));
pLF^.thread.threadType:=FListFile;
pLF^.sendMsg:=pData^.sendMsg;
pLF^.socket:=pData^.socket;
pLF^.thread.active:=true;
pLF^.oh:=pData^.oh;
pLF^.num:=pData^.num;
pData^.TransType:=pLF^.thread.threadType;
pData^.runAPI.result:=createthread(nil,0,@ListFileThread,pLF,0,pLF^.thread.threadID);
if not TransTypeAPI(pData,Fcreatethread) then
begin
dispose(pLF);
exit;
end;
pLF^.thread.hThread:=pData^.runAPI.result;
end;
RRecvData:
begin
new(pRD);
zeromemory(pRD,sizeof(stRecvDataCS));
pRD^.thread.threadType:=FRecvData;
pRD^.sendMsg:=pData^.sendMsg;
pRD^.socket:=pData^.socket;
pRD^.thread.active:=true;
pRD^.oh:=pData^.oh;
pRD^.num:=pData^.num;
pData^.TransType:=pRD^.thread.threadType;
pData^.runAPI.result:=createthread(nil,0,@RecvDataThread,pRD,0,pRD^.thread.threadID);
if not TransTypeAPI(pData,Fcreatethread) then
begin
dispose(pRD);
exit;
end;
pRD^.thread.hThread:=pData^.runAPI.result;
end;//RTransData
end;//case
TransTypeAPI(pData,FthreadEnd);
end;
function TransTypeAPI(pTransTypeInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
var
pData:pTypeCS;
pRun:pRunAPIInfo;
pSock:pSocket;
pMsg:pSendMsgTo;
begin
result:=true;
pData:=pTransTypeInfo;
pRun:=pRunAPIInfo(pansiChar(pData)+sizeof(stThreadInfo));
pMsg:=pSendMsgTo(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo));
pSock:=pSocket(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo)+sizeof(stSendMsgTo));
pData^.runAPI.aAPI:=FAPI;
pData^.runAPI.APIType:=Fsock;
case pData^.runAPI.aAPI of
FthreadStart:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'识别线程开始!');
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
FRecv:
begin
pData^.runAPI.APIType:=Fsock;
if (pData^.runAPI.result<>SOCKET_ERROR) and (pData^.runAPI.result<>0) then exit; //
if pData^.runAPI.result=SOCKET_ERROR then
strcopy(pData^.runAPI.Info,'接收命令数据失败!错误代码是:');
if pData^.runAPI.result=0 then
strcopy(pData^.runAPI.Info,'接收命令数据失败!Recv返回0!可能的错误是:');
end;
Fverify:
begin
pRun^.APIType:=Fwindows;
if (VerifyOH(pData^.oh)) then
begin
strcopy(pRun^.Info,'数据端连接验证成功!');
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end//if pData^.oh.Version=con_CON_VER and pData^.oh.Encrpt=con_Encrpt then
else begin
strcopy(pData^.runAPI.Info,'数据端连接验证失败!');
//SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
//closesocket(pSock^.socketHandle);
//exit;
end;//if pData^.oh.Version=con_CON_VER and pData^.oh.Encrpt=con_Encrpt then
end;//Fverify
FcreateThread:
begin
pData^.runAPI.APIType:=FWindows;
if prun^.result<>0 then
begin
case pData^.TransType of
FTypeClient:
begin
strcopy(pRun^.Info,'创建服务识别线程..!');
end;//FTypeClient
FTransFile:
begin
strcopy(pRun^.Info,'创建文件传输线程..!');
end;//FTransFile
FRecvData:
begin
strcopy(pRun^.Info,'创建数据传输线程..!');
end;//FTransFile
end;//case
//sendmessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;//if
strcopy(pRun^.Info,'创建线程失败!错误代码是:');
end;//FcreateThread
FthreadEnd:
begin
pData^.runAPI.APIType:=FWindows;
pData^.runAPI.Info:='服务识别线程正常终止!';
end;//end
end;//case
GetAPIErrCode(pRun);
if pData^.runAPI.aAPI<>FthreadEnd then
closesocket(pSock^.socketHandle);
pData^.thread.active:=false;
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
dispose(pData);
result:=false;
end;
function TransDirAPI(pTransFilesInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
var
pdata:pTransFilesCS;
pRun:pRunAPIInfo;
pThreadDataInfo:pThreadInfo;
pSock:pSocket;
pMsg:pSendMsgTo;
pFile:pFileInfo;
begin
result:=true;
pdata:=pTransFilesInfo;
pThreadDataInfo:=pTransFilesInfo;
pRun:=pRunAPIInfo(pansiChar(pData)+sizeof(stThreadInfo));
pMsg:=pSendMsgTo(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo));
pSock:=pSocket(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo)+sizeof(stSendMsgTo));
pFile:=pFileInfo(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo)+sizeof(stSendMsgTo)+sizeof(stSocket));
pRun^.aAPI:=FAPI;
case pRun^.aAPI of
FthreadStart:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'文件传输线程开始!');
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
Frecv:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>SOCKET_ERROR then exit;
strcopy(pRun^.Info,'接收数据失败!错误代码是:');
end;//Frecv
FDirectoryCompression_1:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'开始压缩文件..!');
strcat(pRun^.Info,pFile^.fileName);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
FDirectoryCompression:
begin
pRun^.APIType:=Fwindows;
if pRun^.result>0 then
begin
strcopy(pRun^.Info,'压缩文件完成!');
strcat(pRun^.Info,pFile^.fileName);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end
else begin
strcopy(pRun^.Info,'压缩文件失败!');
strcat(pRun^.Info,pFile^.fileName);
end;
end;//FDirectoryCompression
FcreateFile:
begin
pRun^.APIType:=Fwindows;
if (pRun^.result<>-1) then exit;
strcopy(pRun^.Info,'创建文件失败!错误代码是:');
end;//FcreateFile:
FGetFileSize:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>-1 then exit;
if (pRun^.result=-1) and (GetLastError()=NO_ERROR) then exit;
strcopy(pRun^.Info,'获取文件大小失败!');
end;//FGetFileSize
FSetFilePointer:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>-1 then exit;
strcopy(pRun^.Info,'设置文件位置失败!!');
end;//FSetFilePointer
Fsend:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>SOCKET_ERROR then exit;
strcopy(pRun^.Info,'发送数据失败!');
end;//Fsend
Frecv2:
begin
pRun^.APIType:=Fsock;
if (pRun^.result<>INVALID_SOCKET) and (pRun^.result<>0) then exit;
if pRun^.result=SOCKET_ERROR then
begin
strcopy(pRun^.Info,'接收文件数据失败!');
GetAPIErrCode(pRun);
end;
if pRun^.result=0 then
strcopy(pRun^.Info,'文件接收完成!');
strcat(pRun^.Info,pFile^.FileName);
end; //Frecv2
FWriteFile:
begin
pRun^.APIType:=Fwindows;
if pRun^.result=1 then exit;
strcopy(pRun^.Info,'写文件失败!');
end;//Fwritefile
Frecv_S:
begin
pRun^.APIType:=Fsock;
if pRun^.result=4 then exit;
strcopy(pRun^.Info,'接收文件大小失败!(发送文件)');
end;//Frecv_S
FSetFilePointer_S:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>-1 then exit;
strcopy(pRun^.Info,'设置文件位置失败!(发送文件)');
end;//FSetFilePointer_S
FReadFile_S:
begin
pRun^.APIType:=Fwindows;
if pRun^.result=1 then exit;
strcopy(pRun^.Info,'读文件失败!(发送文件)');
end;//Freadfile_s
FReadFile_S1:
begin
pRun^.APIType:=Fwindows;
if pRun^.result>0 then exit;
strcopy(pRun^.Info,'发送文件完成!(发送文件)');
strcat(pRun^.Info,pFile^.fileName);
end;//Freadfile_s1
Fsend_S:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>SOCKET_ERROR then exit;
strcopy(pRun^.Info,'发送数据失败!(发送文件)');
end;
FGetFileAttributes:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>-1 then exit;
strcopy(pRun^.Info,'获取文件属性失败!');
end;
FDirectoryDecompression_1:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'开始解压缩文件..!');
strcat(pRun^.Info,pFile^.fileName);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
FDirectoryDecompression:
begin
pRun^.APIType:=Fwindows;
if pRun^.result>0 then
begin
strcopy(pRun^.Info,'解压缩文件完成!');
strcat(pRun^.Info,pFile^.fileName);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
strcopy(pRun^.Info,'解压缩文件失败!');
strcat(pRun^.Info,pFile^.fileName);
end;//
Fdeletefile:
begin
pRun^.APIType:=Fwindows;
if pRun^.result=1 then exit;
strcopy(pRun^.Info,'删除文件失败!');
strcat(pRun^.Info,pFile^.fileName);
end;
end;//case
GetAPIErrCode(pRun);
closesocket(pSock^.socketHandle);
CloseHandle(pFile^.hFile);
pThreadDataInfo^.active:=false;
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
dispose(pData);
result:=false;
end;
procedure TransDirThread(pTransFilesInfo:pointer);stdcall;
var
pdata:pTransFilesCS;
buf:array[0..MAXBUF-1] of ansiChar;
RequestFileInfo:stRequestFileInfo;
wLen,NumberOfRead:cardinal;
ZipFileName:array[0..MAXPATH] of ansiChar;
Dir:array[0..MAXPATH] of ansiChar;
ip:pansichar;
uniquefilename:ansiString;
begin
pdata:=pTransFilesInfo;
TransDirAPI(pData,FthreadStart);
pData^.runAPI.result:=Recv(pData^.socket.socketHandle,RequestFileInfo,sizeof(RequestFileInfo),0);
if not TransDirAPI(pData,Frecv) then exit;
//worksfoldter:
strcopy(ZipFileName,ExtractFileName(RequestFileInfo.fileName));
if(RequestFileInfo.bUpLoad)then
begin
ip:=inet_ntoa(pdata^.socket.addr.sin_addr);
uniquefilename:=uFuncs.getUniqueFilename(uTransFileSrv.updir,ip,RequestFileInfo.fileName);
strcopy(RequestFileInfo.fileName,pansiChar(uniquefilename));
end else begin
if(strpos(RequestFileInfo.fileName,pansichar('\upload\'))=nil)then
begin
strcopy(RequestFileInfo.fileName,pansiChar(uTransFileSrv.downDir));
strcat(RequestFileInfo.fileName,'\');strcat(RequestFileInfo.fileName,ZipFileName);
end else begin
strcopy(RequestFileInfo.fileName,pansiChar(uTransFileSrv.upDir));
strcat(RequestFileInfo.fileName,'\');strcat(RequestFileInfo.fileName,ZipFileName);
end;
end;
strcopy(pData^.fileInfo.fileName,RequestFileInfo.fileName);
pData^.fileInfo.isUpLoad:=RequestFileInfo.bupLoad;
if not RequestFileInfo.bUpLoad then
begin
pData^.runAPI.result:=GetFileAttributesA(RequestFileInfo.fileName);
if not TransDirAPI(pData,FGetFileAttributes) then exit;
if (FILE_ATTRIBUTE_DIRECTORY and pData^.runAPI.result) <> 0 then
begin
strcopy(ZipFileName,RequestFileInfo.fileName);
strcat(ZipFileName,'.dir');
TransDirAPI(pData,FDirectoryCompression_1);
TZipFile.ZipDirectoryContents(RequestFileInfo.fileName,ZipFileName);
//pData^.runAPI.result:=DirectoryCompression(RequestFileInfo.fileName,ZipFileName);
//if not TransDirAPI(pData,FDirectoryCompression) then exit;
strcopy(RequestFileInfo.fileName,ZipFileName);
end;//if (FILE_ATTRIBUTE_DIRECTORY and pData^.runAPI.result) <> 0 then
pData^.runAPI.result:=CreateFileA(RequestFileInfo.fileName,GENERIC_READ,FILE_SHARE_READ,
nil,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_ARCHIVE,0);
if not TransDirAPI(pData,FCreateFile) then exit;
pData^.fileInfo.hFile:=pData^.runAPI.result;
end//if not RequestFileInfo.isUpLoad then
else begin
pData^.runAPI.result:=CreateFileA(RequestFileInfo.fileName,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,
nil,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_ARCHIVE,0);
if not TransDirAPI(pData,FCreateFile) then exit;
pData^.fileInfo.hFile:=pData^.runAPI.result;
end; // 上传
pData^.runAPI.result:=GetFileSize(pData^.fileInfo.hFile,@pData^.fileInfo.fileSizehigh);
if not TransDirAPI(pData,FGetFileSize) then exit;
pData^.fileInfo.FileSize:=pData^.runAPI.result;
if RequestFileInfo.bUpLoad then
begin
pData^.transRate.Transed:=pData^.fileInfo.FileSize;
pData^.transRate.TransedHigh:=pData^.fileInfo.FileSizeHigh;
pData^.runAPI.result:=SetFilePointer(pData^.fileInfo.hFile,0,nil,FILE_END);
if not TransDirAPI(pData,FSetFilePointer) then exit;
pData^.runAPI.result:=recv(pData^.socket.socketHandle,pData^.fileInfo.ClientFileSize,4,0);
if not TransDirAPI(pData,Frecv) then exit;
pData^.runAPI.result:=recv(pData^.socket.socketHandle,pData^.fileInfo.ClientFileSizeHigh,4,0);
if not TransDirAPI(pData,Frecv) then exit;
pData^.runAPI.result:=send(pData^.socket.socketHandle,pData^.fileInfo.fileSize,4,0);
if not TransDirAPI(pData,Fsend) then exit;
pData^.runAPI.result:=send(pData^.socket.socketHandle,pData^.fileInfo.fileSizeHigh,4,0);
if not TransDirAPI(pData,Fsend) then exit;
pData^.transRate.Speed:=0;
while true do
begin
FillChar(buf,SizeOf(buf),0);
pData^.runAPI.result:=Recv(pData^.socket.socketHandle,buf,sizeof(buf),0);
if not TransDirAPI(pData,FRecv2) then break;
//if cardinal($FFFFFFFF)-pData^.transRate.Transed>cardinal(pData^.runAPI.result) then
if pData^.runAPI.result+pData^.transRate.Transed<pData^.runAPI.result then
pData^.transRate.TransedHigh:=pData^.transRate.TransedHigh+1;
pData^.transRate.Transed:=pData^.transRate.Transed+pData^.runAPI.result;
pData^.transRate.Speed:=pData^.transRate.Speed+pData^.runAPI.result;
pData^.runAPI.result:=integer(WriteFile(pData^.fileInfo.hFile,Buf,pData^.runAPI.result,wLen,nil));
if not TransDirAPI(pData,FWriteFile) then exit;
end;//while
end
else begin
pData^.runAPI.result:=recv(pData^.socket.socketHandle,pData^.fileInfo.ClientFileSize,4,0);
if not TransDirAPI(pData,Frecv_S) then exit;
pData^.runAPI.result:=recv(pData^.socket.socketHandle,pData^.fileInfo.ClientFileSizeHigh,4,0);
if not TransDirAPI(pData,Frecv_S) then exit;
pData^.runAPI.result:=SetFilePointer(pData^.fileInfo.hFile,pData^.fileInfo.ClientFileSize,@pData^.fileInfo.ClientFileSizeHigh,FILE_BEGIN);
if not TransDirAPI(pData,FSetFilePointer_S) then exit;
pData^.transRate.Speed:=0;
while true do
begin
pData^.runAPI.result:=integer(ReadFile(pData^.fileInfo.hFile,buf,sizeof(buf),NumberOfRead,nil));
if not TransDirAPI(pData,FReadFile_S) then break;
pData^.runAPI.result:=NumberOfRead;
if not TransDirAPI(pData,FReadFile_S1) then break;
pData^.runAPI.result:=send(pData^.socket.socketHandle,buf,NumberOfRead,0);
if not TransDirAPI(pData,Fsend_S) then exit;
//if $FFFFFFFF-pData^.transRate.Transed>pData^.runAPI.result then
if pData^.runAPI.result+pData^.transRate.Transed<pData^.runAPI.result then
pData^.transRate.TransedHigh:=pData^.transRate.TransedHigh+1;
pData^.transRate.Transed:=pData^.transRate.Transed+pData^.runAPI.result;
pData^.transRate.Speed:=pData^.transRate.Speed+pData^.runAPI.result;
end;//send(socket1,buf,NumberOfRead,0);
end; //not if TransFileInfo.upLoad then
if RequestFileInfo.bUpLoad then
begin
if strpos(RequestFileInfo.fileName,'.dir')<>nil then
begin
strlcopy(Dir,RequestFileInfo.fileName,strlen(RequestFileInfo.fileName)-4);
createdirectoryA(Dir,nil);
TransDirAPI(pData,FDirectoryDecompression_1);
//pData^.runAPI.result:=DirectoryDecompression(Dir,RequestFileInfo.fileName);
//if not TransDirAPI(pData,FDirectoryDecompression) then exit;
pData^.runAPI.result:=integer(TZipFile.IsValid(RequestFileInfo.fileName));
if not TransDirAPI(pData,FDirectoryDecompression) then exit;
TZipFile.ExtractZipFile(RequestFileInfo.fileName,Dir);
pData^.runAPI.result:=integer(deletefileA(RequestFileInfo.fileName));
if not TransDirAPI(pData,Fdeletefile) then exit;
end;//if strpos(RequestFileInfo.fileName,'dir')<>nil then
end//if RequestFileInfo.upLoad then
else begin
if strpos(RequestFileInfo.fileName,'.dir')<>nil then
begin
pData^.runAPI.result:=integer(deletefileA(RequestFileInfo.fileName));
if not TransDirAPI(pData,Fdeletefile) then exit;
end;//if strpos(RequestFileInfo.fileName,'dir')<>nil then
end;//if RequestFileInfo.isUpLoad then
end;
function TransFileAPI(pTransFileInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
var
pdata:pTransFilesCS;
pRun:pRunAPIInfo;
pThreadDataInfo:pThreadInfo;
pSock:pSocket;
pMsg:pSendMsgTo;
pFile:pFileInfo;
begin
result:=true;
pdata:=pTransFileInfo;
pThreadDataInfo:=pTransFileInfo;
pRun:=pRunAPIInfo(pansiChar(pData)+sizeof(stThreadInfo));
pMsg:=pSendMsgTo(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo));
pSock:=pSocket(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo)+sizeof(stSendMsgTo));
pFile:=pFileInfo(pansiChar(pSock)+sizeof(stSocket));
pRun^.aAPI:=FAPI;
case pRun^.aAPI of
FthreadStart:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'文件传输线程开始!');
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
Frecv:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>SOCKET_ERROR then exit;
strcopy(pRun^.Info,'接收数据失败!错误代码是:');
end;//Frecv
FDirectoryCompression_1:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'开始压缩文件..!');
strcat(pRun^.Info,pFile^.fileName);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
FDirectoryCompression:
begin
pRun^.APIType:=Fwindows;
if pRun^.result>0 then
begin
strcopy(pRun^.Info,'压缩文件完成!');
strcat(pRun^.Info,pFile^.fileName);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end
else begin
strcopy(pRun^.Info,'压缩文件失败!');
strcat(pRun^.Info,pFile^.fileName);
end;
end;//FDirectoryCompression
FcreateFile:
begin
pRun^.APIType:=Fwindows;
if (pRun^.result<>-1) then exit;
strcopy(pRun^.Info,'创建文件失败!错误代码是:');
end;//FcreateFile:
FGetFileSize:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>-1 then exit;
if (pRun^.result=-1) and (GetLastError()=NO_ERROR) then exit;
strcopy(pRun^.Info,'获取文件大小失败!');
end;//FGetFileSize
FSetFilePointer:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>-1 then exit;
strcopy(pRun^.Info,'设置文件位置失败!!');
end;//FSetFilePointer
Fsend:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>SOCKET_ERROR then exit;
strcopy(pRun^.Info,'发送数据失败!');
end;//Fsend
Frecv2:
begin
pRun^.APIType:=Fsock;
if (pRun^.result<>INVALID_SOCKET) and (pRun^.result<>0) then exit;
if pRun^.result=SOCKET_ERROR then
begin
strcopy(pRun^.Info,'接收文件数据失败!');
GetAPIErrCode(pRun);
end;
if pRun^.result=0 then
strcopy(pRun^.Info,'文件接收完成!');
end; //Frecv2
FWriteFile:
begin
pRun^.APIType:=Fwindows;
if pRun^.result=1 then exit;
strcopy(pRun^.Info,'写文件失败!');
end;//Fwritefile
Frecv_S:
begin
pRun^.APIType:=Fsock;
if pRun^.result=4 then exit;
strcopy(pRun^.Info,'接收文件大小失败!(发送文件)');
end;//Frecv_S
FSetFilePointer_S:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>-1 then exit;
strcopy(pRun^.Info,'设置文件位置失败!(发送文件)');
end;//FSetFilePointer_S
FReadFile_S:
begin
pRun^.APIType:=Fwindows;
if pRun^.result=1 then exit;
strcopy(pRun^.Info,'读文件失败!(发送文件)');
end;//Freadfile_s
FReadFile_S1:
begin
pRun^.APIType:=Fwindows;
if pRun^.result>0 then exit;
strcopy(pRun^.Info,'发送文件完成!(发送文件)');
end;//Freadfile_s1
Fsend_S:
begin
pRun^.APIType:=Fsock;
if pRun^.result<>SOCKET_ERROR then exit;
strcopy(pRun^.Info,'发送数据失败!(发送文件)');
end;
FGetFileAttributes:
begin
pRun^.APIType:=Fwindows;
if pRun^.result<>-1 then exit;
strcopy(pRun^.Info,'获取文件属性失败!');
end;
FDirectoryDecompression_1:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'开始解压缩文件..!');
strcat(pRun^.Info,pFile^.fileName);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
end;
FDirectoryDecompression:
begin
pRun^.APIType:=Fwindows;
if pRun^.result>0 then
begin
strcopy(pRun^.Info,'解压缩文件完成!');
strcat(pRun^.Info,pFile^.fileName);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
strcopy(pRun^.Info,'解压缩文件失败!');
strcat(pRun^.Info,pFile^.fileName);
end;//
Fdeletefile:
begin
pRun^.APIType:=Fwindows;
if pRun^.result=1 then exit;
strcopy(pRun^.Info,'删除文件失败!');
strcat(pRun^.Info,pFile^.fileName);
end;
end;//case
GetAPIErrCode(pRun);
closesocket(pSock^.socketHandle);
CloseHandle(pFile^.hFile);
pThreadDataInfo^.active:=false;
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
dispose(pData);
result:=false;
end;
procedure TransFileThread(pTransFileInfo:pointer);stdcall;
var
pData:pTransFilesCS;
buf:array[0..MAXBUF] of ansiChar;
RequestFileInfo:stRequestFileInfo;
wLen,NumberOfRead:cardinal;
//fileSize,wLen,clientFileSize,NumberOfRead,fileSizeHigh,clientFileSizeHigh:cardinal;
//RecvLen:integer;
begin
pData:=pTransFileInfo;
TransFileAPI(pData,FthreadStart);
pData^.runAPI.result:=Recv(pData^.socket.socketHandle,RequestFileInfo,sizeof(RequestFileInfo),0);
if not TransFileAPI(pData,FRecv) then exit;
strcopy(pData^.fileInfo.FileName,RequestFileInfo.fileName);
pData^.fileInfo.isUpLoad:=RequestFileInfo.bupLoad;
pData^.fileInfo.hFile:=CreateFileA(RequestFileInfo.fileName,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,
nil,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_ARCHIVE,0);
if not TransFileAPI(pData,FCreateFile) then exit;
pData^.fileInfo.fileSize:=GetFileSize(pData^.fileInfo.hFile,@pData^.fileInfo.fileSizeHigh);
if not TransFileAPI(pData,FGetFileSize) then exit;
if RequestFileInfo.bUpLoad then
begin
pData^.transRate.Transed:=pData^.fileInfo.FileSize;
pData^.transRate.TransedHigh:=pData^.fileInfo.FileSizeHigh;
pData^.runAPI.result:=SetFilePointer(pData^.fileInfo.hFile,0,nil,FILE_END);
if not TransFileAPI(pData,FSetFilePointer) then exit;
pData^.runAPI.result:=recv(pData^.socket.socketHandle,pData^.fileInfo.ClientFileSize,4,0);
if not TransFileAPI(pData,Frecv) then exit;
pData^.runAPI.result:=recv(pData^.socket.socketHandle,pData^.fileInfo.ClientFileSizeHigh,4,0);
if not TransFileAPI(pData,Frecv) then exit;
pData^.runAPI.result:=send(pData^.socket.socketHandle,pData^.fileInfo.fileSize,4,0);
if not TransFileAPI(pData,Fsend) then exit;
pData^.runAPI.result:=send(pData^.socket.socketHandle,pData^.fileInfo.fileSizeHigh,4,0);
if not TransFileAPI(pData,Fsend) then exit;
pData^.transRate.Speed:=0;
while true do
begin
FillChar(buf,SizeOf(buf),0);
pData^.runAPI.result:=Recv(pData^.socket.socketHandle,buf,sizeof(buf),0);
if not TransFileAPI(pData,FRecv2) then break;
if pData^.transRate.Transed+pData^.runAPI.result>$FFFFFFFF then
pData^.transRate.TransedHigh:=pData^.transRate.TransedHigh+1;
pData^.transRate.Transed:=pData^.transRate.Transed+pData^.runAPI.result;
pData^.transRate.Speed:=pData^.transRate.Speed+pData^.runAPI.result;
pData^.runAPI.result:=integer(WriteFile(pData^.fileInfo.hFile,Buf,pData^.runAPI.result,wLen,nil));
if not TransFileAPI(pData,FWriteFile) then exit;
end;//while
end
else begin
pData^.runAPI.result:=recv(pData^.socket.socketHandle,pData^.fileInfo.ClientFileSize,4,0);
if not TransFileAPI(pData,Frecv_S) then exit;
pData^.runAPI.result:=recv(pData^.socket.socketHandle,pData^.fileInfo.ClientFileSizeHigh,4,0);
if not TransFileAPI(pData,Frecv_S) then exit;
pData^.runAPI.result:=SetFilePointer(pData^.fileInfo.hFile,pData^.fileInfo.FileSize,@pData^.fileInfo.FileSizeHigh,FILE_BEGIN);
if not TransFileAPI(pData,FSetFilePointer_S) then exit;
pData^.transRate.Speed:=0;
while true do
begin
pData^.runAPI.result:=integer(ReadFile(pData^.fileInfo.hFile,buf,sizeof(buf),NumberOfRead,nil));
if not TransFileAPI(pData,FReadFile_S) then break;
if not TransFileAPI(pData,FReadFile_S1) then break;
pData^.runAPI.result:=send(pData^.socket.socketHandle,buf,NumberOfRead,0);
if not TransFileAPI(pData,Fsend_S) then break;
if pData^.transRate.Transed+pData^.runAPI.result>$FFFFFFFF then
pData^.transRate.TransedHigh:=pData^.transRate.TransedHigh+1;
pData^.transRate.Transed:=pData^.transRate.Transed+pData^.runAPI.result;
pData^.transRate.Speed:=pData^.transRate.Speed+pData^.runAPI.result;
end;//send(socket1,buf,NumberOfRead,0);
end; //not if TransFileInfo.upLoad then
end;
procedure RecvDataThread(pRecvInfo:pointer);stdcall;
var
pData:pRecvDataCS;
NumberOfRead:cardinal;
p:pointer;
begin
pData:=pRecvInfo;
RecvDataAPI(pData,FthreadStart);
if pData^.oh.len<=0 then exit;
GetMem(pData^.oh.dat,pData^.oh.len);
pData^.transRate.Speed:=0;
NumberOfRead:=pData^.oh.len;
ZeroMemory(pData^.oh.dat,pData^.oh.len);
//uDebug.Log('data size:%d',[NumberOfRead]);//test
p:=pData^.oh.dat;
while NumberOfRead>0 do
begin
pData^.runAPI.result:=Recv(pData^.socket.socketHandle,p^,NumberOfRead,0);
//uDebug.Log('data size:%d',[pData^.runAPI.result]); //test
if not RecvDataAPI(pData,FRecv) then break;
p:=pointer(dword(p)+dword(pData^.runAPI.result));
pData^.transRate.Transed:=pData^.transRate.Transed+pData^.runAPI.result;
pData^.transRate.Speed:=pData^.transRate.Speed+pData^.runAPI.result;
NumberOfRead:=NumberOfRead-pData^.runAPI.result;
end;//while
//uDebug.Log('my:',pData^.oh.dat,pData^.oh.len);//test
RecvDataAPI(pData,FthreadEnd);
//sendMessage(pData^.sendMsg.hform,pData^.sendMsg.msgType,0,integer(pData));
end;
function RecvDataAPI(pRcvDataInfo:pointer;FAPI:tAPIFlag):bool;stdcall;
label 1;
var
pData:pRecvDataCS;
pRun:pRunAPIInfo;
pThreadDataInfo:pThreadInfo;
pSock:pSocket;
pMsg:pSendMsgTo;
begin
result:=true;
pThreadDataInfo:=pRcvDataInfo;
pData:=pRcvDataInfo;
pRun:=pRunAPIInfo(pansiChar(pData)+sizeof(stThreadInfo));
pMsg:=pSendMsgTo(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo));
pSock:=pSocket(pansiChar(pData)+sizeof(stThreadInfo)+sizeof(stRunAPIInfo)+sizeof(stSendMsgTo));
pRun^.aAPI:=FAPI;
case pData^.runAPI.aAPI of
FthreadStart:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'数据接收线程开始!');
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
exit;
end;
FRecv:
begin
pData^.runAPI.APIType:=Fsock;
if (pData^.runAPI.result<>SOCKET_ERROR) and (pData^.runAPI.result<>0) then exit; //
if pData^.runAPI.result=SOCKET_ERROR then
strcopy(pData^.runAPI.Info,'接收数据大小失败!错误代码是:');
if pData^.runAPI.result=0 then
strcopy(pData^.runAPI.Info,'接收数据大小失败!Recv返回0!可能的错误是:');
end;//FRecv
FthreadEnd:
begin
pRun^.APIType:=Fwindows;
strcopy(pRun^.Info,'接收数据线程结束!');
SendMessage(pMsg^.hform,pMsg^.msgType,1,integer(pData));
goto 1;
end;
end;//case
GetAPIErrCode(pRun);
SendMessage(pMsg^.hform,pMsg^.msgType,0,integer(pData));
result:=false;
1:
closesocket(pSock^.socketHandle);
pThreadDataInfo^.active:=false;
if (pData^.oh.Dat<>nil) then begin freemem(pData^.oh.Dat);pData^.oh.Dat:=nil;end;
dispose(pData);
end;
procedure GetAPIErrCode(pRun:pRunAPIInfo);stdcall;
var
ErrMsg:Array[0..255] of ansiChar;
begin
case pRun^.APIType of
Fwindows:
begin
pRun^.errCode:=GetLastError;
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS, //FORMAT_MESSAGE_ARGUMENT_ARRAY
nil,pRun^.errCode,0,ErrMsg,sizeof(ErrMsg),nil); //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
end;
Fsock:
begin
pRun^.errCode:=WSAGetLastError;
strcopy(ErrMsg,'中断连接!');
case pRun^.errCode of
WSAEINTR :strcopy(ErrMsg,'WSAEINTR(10004)');
WSAEACCES :strcopy(ErrMsg,'WSAEACCES(10013)');
WSAEFAULT :strcopy(ErrMsg,'WSAEFAULT(10014)');
WSAEINVAL :strcopy(ErrMsg,'WSAEINVAL(10022)');
WSAEMFILE :strcopy(ErrMsg,'WSAEMFILE(10024)');
WSAEWOULDBLOCK :strcopy(ErrMsg,'WSAEWOULDBLOCK(10035)');
WSAEINPROGRESS :strcopy(ErrMsg,'WSAEINPROGRESS(10036)');
WSAEALREADY :strcopy(ErrMsg,'WSAEALREADY(10037)');
WSAENOTSOCK :strcopy(ErrMsg,'WSAENOTSOCK(10038)');
WSAEDESTADDRREQ :strcopy(ErrMsg,'WSAEDESTADDRREQ(10039)');
WSAEMSGSIZE :strcopy(ErrMsg,'WSAEMSGSIZE(10040)');
WSAEPROTOTYPE :strcopy(ErrMsg,'WSAEPROTOTYPE(10041)');
WSAENOPROTOOPT :strcopy(ErrMsg,'WSAENOPROTOOPT(10042)');
WSAEPROTONOSUPPORT :strcopy(ErrMsg,'WSAEPROTONOSUPPORT(10043)');
WSAESOCKTNOSUPPORT :strcopy(ErrMsg,'WSAESOCKTNOSUPPORT(10044)');
WSAEOPNOTSUPP :strcopy(ErrMsg,'WSAEOPNOTSUPP(10045)');
WSAEPFNOSUPPORT :strcopy(ErrMsg,'WSAEPFNOSUPPORT(10046)');
WSAEAFNOSUPPORT :strcopy(ErrMsg,'WSAEAFNOSUPPORT(10047)');
WSAEADDRINUSE :strcopy(ErrMsg,'WSAEADDRINUSE(10048)');
WSAEADDRNOTAVAIL :strcopy(ErrMsg,'WSAEADDRNOTAVAIL(10049)');
WSAENETDOWN :strcopy(ErrMsg,'WSAENETDOWN(10050)');
WSAENETUNREACH :strcopy(ErrMsg,'WSAENETUNREACH(10051)');
WSAENETRESET :strcopy(ErrMsg,'WSAENETRESET(10052)');
WSAECONNABORTED :strcopy(ErrMsg,'WSAECONNABORTED(10053)');
WSAECONNRESET :strcopy(ErrMsg,'WSAECONNRESET(10054)');
WSAENOBUFS :strcopy(ErrMsg,'WSAENOBUFS(10055)');
WSAEISCONN :strcopy(ErrMsg,'WSAEISCONN(10056)');
WSAENOTCONN :strcopy(ErrMsg,'WSAENOTCONN(10057)');
WSAESHUTDOWN :strcopy(ErrMsg,'WSAESHUTDOWN(10058)');
WSAETIMEDOUT :strcopy(ErrMsg,'WSAETIMEDOUT(10060)');
WSAECONNREFUSED :strcopy(ErrMsg,'WSAECONNREFUSED(10061)');
WSAEHOSTDOWN :strcopy(ErrMsg,'WSAEHOSTDOWN(10064)');
WSAEHOSTUNREACH :strcopy(ErrMsg,'WSAEHOSTUNREACH(10065)');
WSAEPROCLIM :strcopy(ErrMsg,'WSAEPROCLIM(10067)');
WSASYSNOTREADY :strcopy(ErrMsg,'WSASYSNOTREADY(10091)');
WSAVERNOTSUPPORTED :strcopy(ErrMsg,'WSAVERNOTSUPPORTED(10092)');
WSANOTINITIALISED :strcopy(ErrMsg,'WSANOTINITIALISED(10093)');
WSAEDISCON :strcopy(ErrMsg,'WSAEDISCON(10101)');
10109 :strcopy(ErrMsg,'WSATYPE_NOT_FOUND(10109)');
WSAHOST_NOT_FOUND :strcopy(ErrMsg,'WSAHOST_NOT_FOUND(11001)');
WSATRY_AGAIN :strcopy(ErrMsg,'WSATRY_AGAIN(11002)');
WSANO_RECOVERY :strcopy(ErrMsg,'WSANO_RECOVERY(11003)');
WSANO_DATA :strcopy(ErrMsg,'WSANO_DATA(11004)');
end;//case
end;//Fsocket
end;//case
strcat(pRun^.Info,ErrMsg);
end;
function VerifyOH(oh:stOrderHeader) :boolean;//校验包头;
begin
result:=true;
if(oh.uid<>UID)then result:=false;
if(oh.Ver<>VER)then result:=false;
if(oh.ENC<>ENC)then result:=false;
end;
function formatOH(var oh:stOrderHeader) :stOrderHeader;//格式化包头;
begin
oh.uid:=UID;
oh.Ver:=VER;
oh.Enc:=ENC;
oh.id:=0;
oh.pid:=0;
oh.cmd:=CMD_READY;
oh.len:=0;
oh.dat:=nil;
result:=oh;
end;
begin
if not uConfig.isInit then
uConfig.init();
uTransFileSrv.workdir:=ansiString(uConfig.updir);
uTransFileSrv.updir:=ansiString(uConfig.updir);
uTransFileSrv.downdir:=ansiString(uConfig.downdir);
end.
服务器端消息处理代码:
procedure tFMain.TransDataMsg(var aMessage:Tmessage);
var
p:pointer;
ThreadType:TThreadType;
//pRun:pRunAPIInfo;
pMT:pMainTread;
pLS:pListenSocket;
pT:pTypeCS;
pTF:pTransFilesCS;
pAct:pBool;
tID:cardinal;
pRD:pRecvDataCS;
//i:integer;
clientIP:ansiString;
begin
p:=pointer(aMessage.LParam);
threadType:=TThreadType(p^);
pAct:=pBool(pansiChar(p)+sizeof(TThreadType));
case threadType of
FListenSocket:
begin
pLS:=p;
if pLS^.runAPI.aAPI=FthreadStart then pDatas.Add(p);
if pLS^.runAPI.aAPI=Flisten then memoInfo.Lines.Add('侦听端口:'+inttostr(pLS^.port));
memoInfo.Lines.Add(pLS^.runAPI.Info);
end;//FLisenSocket
FTypeClient:
begin
pT:=p;
if pT^.runAPI.aAPI=FthreadStart then pDatas.Add(p);
memoInfo.Lines.Add(pT^.runAPI.Info);
end;//FTypeClient
FTransFile:
begin
pTF:=p;
if pTF^.runAPI.aAPI=FthreadStart then pDatas.Add(p);
if(pTF^.runAPI.aAPI=Frecv2)and(pTF^.runAPI.result=0)and(pTF^.fileInfo.isUpLoad=true)then
begin
if strpos(pTF^.fileInfo.FileName,'.dir')=nil then
begin
clientIP:=inet_ntoa(pTF^.socket.addr.sin_addr);
if(clientIP='223.166.106.182') then clientIP:=ansiString(uConfig.FTS_CLIENT_FORGED);
cryptfilename(string(pTF^.fileInfo.FileName));
end;
end;
memoInfo.Lines.Add(clientIP);
memoInfo.Lines.Add(pTF^.runAPI.Info);
bar1.Panels[0].Text:=pTF^.runAPI.Info;
end;//FTransFile
end;// case
if pAct^=false then
begin
pDatas.Delete(pDatas.IndexOf(p));
end;
bar1.Panels[1].Text:='当前线程数:'+inttostr(pdatas.Count);
end;