[Delphi]木马文件传输代码

本文介绍了一个使用 WinSock 的应用程序实例,该程序包括客户端和服务端两部分,能够实现文件的双向传输。服务端负责监听并接收来自客户端的文件,而客户端则用于选择本地文件并发送到指定的服务端。

服务器端:

unitServerFrm;

interface

uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
Dialogs,ComCtrls,StdCtrls,ExtCtrls,WinSock;

type
TfrmMain
= class (TForm)
Panel1:TPanel;
Label1:TLabel;
edtPort:TEdit;
Panel2:TPanel;
stabar:TStatusBar;
SaveDialog:TSaveDialog;
btnListen:TButton;
btnReceive:TButton;
btnStop:TButton;
btnExit:TButton;
procedureFormCreate(Sender:TObject);
procedurebtnExitClick(Sender:TObject);
procedureFormClose(Sender:TObject;varAction:TCloseAction);
procedurebtnListenClick(Sender:TObject);
procedurebtnReceiveClick(Sender:TObject);
procedurebtnStopClick(Sender:TObject);
private
... {Privatedeclarations}
public
... {Publicdeclarations}
StopTrans:Boolean;
// 是否停止传送开关
InTrans:Boolean; // 表示正在接收文件
Server:TSocket; // 定义服务器端的socket句柄
// 自定义过程接收文件
procedureRecvFile(FileName:String);
end;

var
frmMain:TfrmMain;

const
BlockLen
= 1024 * 4 ;

implementation

... {$R*.dfm}

proceduretfrmmain.RecvFile(FileName:String);
var
Ftrans:fileofByte;
Recelen:Integer;
Blockbuf:array[
0 ..BlockLen - 1 ]ofByte;
RecvSocket:TSocket;
ra:Sockaddr_in;
ra_len:integer;
begin
ra_len:
= sizeof (ra);
Recvsocket:
= accept(server,@ra,@ra_len);
assignFile(Ftrans,filename);
rewrite(ftrans);
stoptrans:
= false ;
intrans:
= true ;
recelen:
= recv(recvsocket,Blockbuf,BlockLen, 0 );
while (recelen > 0 )and(notStopTrans) do
begin
BlockWrite(Ftrans,Blockbuf[
0 ],BlockLen);
application.ProcessMessages;
recelen:
= recv(recvsocket,Blockbuf,Blocklen, 0 );
if stoptransthen
begin
CloseFile(Ftrans);
CloseSocket(RecvSocket);
InTrans:
= False;
MessageBox(Handle,
' 停止传输! ' , ' 提示 ' ,MB_OK);
EXIT;
END;
END;
// 关闭文件,接收的SOCKET
CloseFile(Ftrans);
Closesocket(recvsocket);
InTrans:
= False;
if (Recelen = SOCKET_ERROR)then
messagebox(handle,
' 传输异常终止! ' , ' 提示 ' ,MB_OK)
ELSE
MESSAGEBOX(HANDLE,
' 客户端已经关闭连接1,文件可能已经传送完毕了! ' , ' 提示 ' ,MB_OK);

end;

procedureTfrmMain.FormCreate(Sender:TObject);
var
aWSAData:TWSAData;
begin
if WSAStartup($ 0101 ,aWSAData) <> 0 then
raiseException.Create(
' 不能启动WinSock动态链接库 ' );
messageBox(Handle,aWSAdata.szDescription,
' WinSock动态链接库版本 ' ,mb_ok);


end;

procedureTfrmMain.btnExitClick(Sender:TObject);
begin
Close;
end;

procedureTfrmMain.FormClose(Sender:TObject;varAction:TCloseAction);
begin
if InTransthen
if MessageBox(handle, ' 正在接收文件,停止吗? ' , ' 提示 ' ,MB_YESNO) = IDNOthen
abort;

IFSERVER
<> INVALID_SOCKETTHEN
CLOSESOCKET(SERVER);
// 释放winsock动态链接库所创建的资源
if WSACleanup <> 0 then
messagebox(handle,
' 清除Winsock动态链接库错误! ' , ' 提示 ' ,MB_OK)
ELSE
messagebox(handle,
' 清除Winsock动态链接库成功! ' , ' 提示 ' ,MB_OK);

end;

procedureTfrmMain.btnListenClick(Sender:TObject);
var
ca:SOCKADDR_IN;
begin
// 创建服务器端SOCKET
Server: = Socket(PF_INET,SOCK_STREAM,IPPROTO_IP);
IFserver
= invalid_socketthen
begin
stabar.SimpleText:
= ' 创建接收SOCKET错误1 ' ;
exit;
end;
// 绑定服务器端SOCKET
ca.sin_family: = PF_INET;
CA.sin_port:
= htons(strtoint(trim(edtPort.Text)));
ca.sin_addr.S_addr:
= INADDR_ANY;
if bind(server,ca, sizeof (ca)) = socket_errorthen
begin
stabar.SimpleText:
= ' 绑定socket错误,请更改接收端口 ' ;
closeSocket(server);
exit;
end
else
stabar.SimpleText:
= ' 绑定接收端socket成功! ' ;

// 开始监听
listen(server, 5 );
btnlisten.Enabled:
= False;
btnstop.Enabled:
= true ;

end;

procedureTfrmMain.btnReceiveClick(Sender:TObject);
begin
if (server = INVALID_SOCKET)THEN
BEGIN
MESSAGEBOX(HANDLE,
' 还没有进行监听,请先进行监听! ' , ' 提示 ' ,MB_OK);
EXIT;
END;
IFSaveDialog.ExecuteTHEN
RECVFILE(SaveDialog.FileName);

end;

procedureTfrmMain.btnStopClick(Sender:TObject);
begin
STOPTRANS:
= TRUE;
IFSERVER
<> INVALID_SOCKETTHENcLOSESOCKET(SERVER);
// 此处需要说明
server: = INVALID_SOCKET;
bTNSTOP.Enabled:
= fALSE;
BTNlISTEN.Enabled:
= TRUE;
end;

end.

客户端:

unitClientFrm;

interface

uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
Dialogs,StdCtrls,ComCtrls,WinSock;

type
TfrmMain
= class (TForm)
opendfile:TOpenDialog;
Label1:TLabel;
edtIP:TEdit;
Label2:TLabel;
edtPort:TEdit;
StatusBar:TStatusBar;
btnConnect:TButton;
btnSend:TButton;
btnStop:TButton;
btnExit:TButton;
ProgressBar:TProgressBar;
procedureFormCreate(Sender:TObject);
procedurebtnExitClick(Sender:TObject);
procedureFormClose(Sender:TObject;varAction:TCloseAction);
procedurebtnConnectClick(Sender:TObject);
procedurebtnSendClick(Sender:TObject);
procedurebtnStopClick(Sender:TObject);
private
... {Privatedeclarations}
Client:TSocket;
public
... {Publicdeclarations}
StopTrans:Boolean;
// 是否停止发送的开发
InTrans:Boolean; // 表示是否正在传送文件
procedureTransFile(FileName:String); // 传递文件的过程
end;

const BlockLen = 1024 * 4 ; // 每次发送的最大数据量

var
frmMain:TfrmMain;

implementation

... {$R*.dfm}

procedureTfrmMain.TransFile(FileName:String);
// 传递文件的过程
var
Ftrans:fileofByte;
Flen:integer;
BlockNum,RemainLen:integer;
BlockBuf:array[
0 ..BlockLen - 1 ]ofByte;
i:integer;
SendLen:Integer;
begin
assignFile(Ftrans,filename);
reset(Ftrans);
Flen:
= FileSize(Ftrans);
BlockNum:
= FlendivBlockLen;
progressBar.Max:
= 1 + BlockNum;
RemainLen:
= FlenmodBlockLen;
StopTrans:
= False;
InTrans:
= True;
SendLen:
= 1 ;
for i: = 0 toBlockNum - 1 do
begin
if (StopTrans)or(SendLen <= 0 )thenBreak;
BlockRead(Ftrans,Blockbuf[
0 ],BlockLen);
SendLen:
= Send(Client,Blockbuf,BlockLen, 0 );
ProgressBar.Position:
= i;
Application.processMessages;
end;
if StopTransthen
begin
CloseFile(Ftrans);
InTrans:
= False;
StatusBar.SimpleText:
= '' ;
MessageBox(Handle,
' 停止传输! ' , ' 提示 ' ,mb_ok);
progressbar.Position:
= 0 ;
exit;
end;
if (SendLen <= 0 )then
begin
CloseFile(Ftrans);
InTrans:
= False;
StatusBar.SimpleText:
= '' ;
messagebox(handle,
' 传出异常终止! ' , ' 提示 ' ,MB_OK);
progressBar.Position:
= 0 ;
exit;
end;
if remainLen > 0 then
begin
BlockRead(Ftrans,BlockBuf[
0 ],RemainLen);
SendLen:
= send(client,BlockBuf,Remainlen, 0 );
if (sendLen <= 0 )then
begin
closeFile(Ftrans);
InTrans:
= False;
StatusBar.SimpleText:
= '' ;
messagebox(handle,
' 传输异常终止! ' , ' 提示 ' ,mb_ok);
progressBar.Position:
= 0 ;
exit;
end;
end;
progressBar.Position:
= ProgressBar.Max;
CloseFile(Ftrans);
InTrans:
= False;
StatusBar.SimpleText:
= '' ;
messagebox(handle,
' 传输完成! ' , ' 提示 ' ,mb_ok);
progressbar.Position:
= 0 ;

end;


procedureTfrmMain.FormCreate(Sender:TObject);
var
aWSAData:TWSAData;
begin
if WSAStartup($ 0101 ,aWSAData) <> 0 then
raiseException.Create(
' 不能启动WinSock动态链接库 ' );
messageBox(Handle,aWSAdata.szDescription,
' WinSock动态链接库版本 ' ,mb_ok);


end;

procedureTfrmMain.btnExitClick(Sender:TObject);
begin
Close;
end;

procedureTfrmMain.FormClose(Sender:TObject;varAction:TCloseAction);
begin
if InTransthen
if MessageBox(handle, ' 正在传输文件,停止吗? ' , ' 提示 ' ,MB_YESNO) = IDNOthen
abort;
// 释放winsock动态链接库所创建的资源
if WSACleanup <> 0 then
messagebox(handle,
' 清除Winsock动态链接库错误! ' , ' 提示 ' ,MB_OK)
ELSE
messagebox(handle,
' 清除Winsock动态链接库成功! ' , ' 提示 ' ,MB_OK);
CloseSocket(Client);
end;

procedureTfrmMain.btnConnectClick(Sender:TObject);
var
ca:SOCKADDR_IN;
hostaddr:u_long;
begin
Client:
= Socket(PF_INET,SOCK_STREAM,IPPROTO_IP);
IFCLIENT
= INVALID_SOCKETTHEN
BEGIN
StatusBar.SimpleText:
= ' 为连接远程服务器端创建COSKET错误! ' ;
exit;
end;
ca.sin_family:
= PF_INET;
CA.sin_port:
= HTONS(STRTOINT(TRIM(EDTpORT.Text)));
HOSTADDR:
= INET_ADDR(PCHAR(TRIM(EDTIP.Text)));
// 判断IP是否合法
if (hostaddr = - 1 )then
begin
StatusBar.SimpleText:
= ' 主机IP地址: ' + trim(edtip.Text) + ' 错误 ' ;
exit;
end
else
ca.sin_addr.S_addr:
= hostaddr;
// 连接服务器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值