Unit1.pas
上传用户:wshicoco
上传日期:2009-03-23
资源大小:1150k
文件大小:16k
源码类别:

Ftp服务器

开发平台:

Delphi

  1. unit Unit1;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5.   Dialogs, StdCtrls, ComCtrls, ExtCtrls, IdBaseComponent, IdComponent,
  6.   IdUDPBase, IdUDPServer, IdUDPClient,IdSocketHandle, IdIPWatch;
  7. type
  8.   TForm1 = class(TForm)
  9.     PageControl1: TPageControl;
  10.     TabSheet1: TTabSheet;
  11.     TabSheet2: TTabSheet;
  12.     apply_button: TButton;
  13.     Label1: TLabel;
  14.     Label2: TLabel;
  15.     Label3: TLabel;
  16.     Label4: TLabel;
  17.     locIP_edit: TEdit;
  18.     locPort_edit: TEdit;
  19.     remoteIP_edit: TEdit;
  20.     remotePort_edit: TEdit;
  21.     read_button: TButton;
  22.     StatusBar: TStatusBar;
  23.     write_button: TButton;
  24.     Timer1: TTimer;
  25.     logmemo: TMemo;
  26.     path_edit: TEdit;
  27.     browse_button: TButton;
  28.     OpenDialog1: TOpenDialog;
  29.     client: TIdUDPServer;
  30.     cancel_button: TButton;
  31.     stop_button: TButton;
  32.     trace_button: TButton;
  33.     IPWatch: TIdIPWatch;
  34.     clear_Button: TButton;
  35.     save_button: TButton;
  36.     procedure FormCreate(Sender: TObject);
  37.     procedure apply_buttonClick(Sender: TObject);
  38.     procedure read_buttonClick(Sender: TObject);
  39.     procedure browse_buttonClick(Sender: TObject);
  40.     procedure write_buttonClick(Sender: TObject);
  41.     procedure clientUDPRead(Sender: TObject; AData: TStream;
  42.       ABinding: TIdSocketHandle);
  43.     procedure cancel_buttonClick(Sender: TObject);
  44.     procedure stop_buttonClick(Sender: TObject);
  45.     procedure Timer1Timer(Sender: TObject);
  46.     procedure trace_buttonClick(Sender: TObject);
  47.     procedure clear_ButtonClick(Sender: TObject);
  48.     procedure save_buttonClick(Sender: TObject);
  49.   private
  50.     { Private declarations }
  51.   public
  52.     { Public declarations }
  53.   end;
  54. type
  55.   rflip=record
  56.     a1:byte;
  57.     a2:byte;
  58.   end;
  59.   frame=record
  60.     op:word;
  61.     info:array[1..514]of byte;
  62.   end;
  63. var
  64.   Form1: TForm1;
  65.   remoteIP:string;
  66.   remoteport:integer;
  67.   locport:integer;
  68.   transmode,last:boolean;
  69.   filename:string;
  70.   transFrame,recFrame:frame;
  71.   from_file,to_file:file;
  72.   ack_NO,block_NO:word;
  73.   numwrite,numread:integer;
  74.   require1,require2,trans:boolean;
  75.   reqcount,transcount:longint;
  76.   count:longint;
  77.   starttime:longint;
  78.   timeready,trace,acktran:boolean;
  79. implementation
  80. {$R *.dfm}
  81. function selfinc(a:word):word;
  82. var
  83.   x:word;
  84. begin
  85.   x:=a;
  86.   if x=65535 then selfinc:=0
  87.   else begin
  88.     x:=x+1;
  89.     selfinc:=x;
  90.   end;
  91. end;
  92. function flipout(orig:word):rflip;
  93. var
  94.   a:byte;
  95.   s:rflip;
  96. begin
  97.   s:=rflip(orig);
  98.   a:=s.a1;
  99.   s.a1:=s.a2;
  100.   s.a2:=a;
  101.   flipout:=s;
  102. end;
  103. function flipin(a1,a2:byte):word;
  104. var
  105.   a:rflip;
  106. begin
  107.   a.a1:=a2;
  108.   a.a2:=a1;
  109.   flipin:=word(a);
  110. end;
  111. procedure TForm1.FormCreate(Sender: TObject);
  112. begin
  113.   statusbar.Panels.Items[0].Text:='空闲';
  114.   remoteIP:='127.0.0.1';
  115.   remoteport:=1000;
  116.   locport:=1000;
  117.   opendialog1.InitialDir:=getcurrentdir;
  118.   block_NO:=0;
  119.   ack_NO:=0;
  120.   require1:=false;
  121.   require2:=false;
  122.   trans:=false;
  123.   reqcount:=0;
  124.   transcount:=0;
  125.   timeready:=false;
  126.   trace:=false;
  127.   acktran:=false;
  128.   locIP_edit.Text:=IPWatch.LocalIP;
  129. end;
  130. procedure TForm1.apply_buttonClick(Sender: TObject);
  131. begin
  132.   client.Active:=false;
  133.   locport:=strtoint(locPort_edit.Text);
  134.   remoteIP:=remoteIP_edit.Text;
  135.   remotePort:=strtoint(remotePort_edit.Text);
  136.   write_button.Enabled:=true;
  137.   read_button.Enabled:=true;
  138.   client.DefaultPort:=locport;
  139.   client.Bindings.Add;
  140.   client.Bindings.Items[0].Port:=locport;
  141.   client.Active:=true;
  142.   apply_button.Enabled:=false;
  143.   stop_button.Enabled:=true;
  144.   statusbar.Panels.Items[0].Text:='目标绑定';
  145.   logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  146.   logmemo.Lines.Append('绑定远程目标:'+remoteIP+'端口 '+inttostr(remoteport));
  147. end;
  148. procedure TForm1.read_buttonClick(Sender: TObject);
  149. begin
  150.   stop_button.Enabled:=false;
  151.   read_button.Enabled:=false;
  152.   write_button.Enabled:=false;
  153.   browse_button.Enabled:=true;
  154.   cancel_button.Enabled:=true;
  155.   browse_button.Caption:='确定';
  156.   path_edit.Enabled:=true;
  157.   transmode:=true;
  158. end;
  159. procedure TForm1.browse_buttonClick(Sender: TObject);
  160. var
  161.   i,j:integer;
  162. const
  163.   mode='octet';
  164. begin
  165.   if transmode then
  166.   begin
  167.     starttime:=0;
  168.     timeready:=true;
  169.     count:=0;
  170.     browse_button.Enabled:=false;
  171.     cancel_button.Enabled:=false;
  172.     filename:=path_edit.Text;
  173.     transframe.op:=word(flipout(1));
  174.     for i:=1 to length(filename) do
  175.       transframe.info[i]:=ord(filename[i]);
  176.     transframe.info[length(filename)+1]:=0;
  177.     for j:=length(filename)+2 to length(filename)+7 do
  178.       transframe.info[j]:=ord(mode[j-length(filename)-1]);
  179.     transframe.info[length(filename)+7]:=0;
  180.     client.SendBuffer(remoteIP,remotePort,transframe,length(filename)+9);
  181.     filename:=getcurrentdir+''+filename;
  182.     assignfile(to_file,filename);
  183.     rewrite(to_file,1);
  184.     require1:=true;
  185.     reqcount:=0;
  186.     statusbar.Panels.Items[0].Text:='读文件请求';
  187.     logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  188.     logmemo.Lines.Append('RRQ to    '+remoteIP);
  189.     logmemo.text:=logmemo.Text+'01';
  190.     for i:=1 to 514 do
  191.       if transframe.info[i]<>0 then
  192.         logmemo.text:=logmemo.Text+(chr(transframe.info[i]))
  193.       else break;
  194.     logmemo.Text:=logmemo.Text+'0octet0';
  195.   end
  196.   else begin
  197.     if opendialog1.Execute then
  198.     begin
  199.       starttime:=0;
  200.       timeready:=true;
  201.       browse_button.Enabled:=false;
  202.       cancel_button.Enabled:=false;
  203.       filename:=opendialog1.FileName;
  204.       path_edit.Text:=filename;
  205.       for i:=length(fileName) downto 1 do
  206.       if fileName[i]='' then
  207.         break;
  208.       j:=1;
  209.       while i<length(filename) do
  210.       begin
  211.         transframe.info[j]:=ord(filename[i+1]);
  212.         i:=i+1;
  213.         j:=j+1;
  214.       end;
  215.       transframe.info[j]:=0;
  216.       for i:=j+1 to j+6 do
  217.         transframe.info[i]:=ord(mode[i-j]);
  218.       transframe.info[j+6]:=0;
  219.       transframe.op:=word(flipout(2));
  220.       client.SendBuffer(remoteIP,remotePort,transframe,j+8);
  221.       assignfile(from_file,filename);
  222.       reset(from_file,1);
  223.       last:=false;
  224.       require2:=true;
  225.       reqcount:=0;
  226.       statusbar.Panels.Items[0].Text:='写文件请求';
  227.       count:=0;
  228.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  229.       logmemo.Lines.Append('WRQ to    '+remoteIP);
  230.       logmemo.text:=logmemo.Text+'02';
  231.       for i:=1 to 514 do
  232.       if transframe.info[i]<>0 then
  233.         logmemo.text:=logmemo.Text+(chr(transframe.info[i]))
  234.       else break;
  235.       logmemo.Text:=logmemo.Text+'0octet0';
  236.     end;
  237.   end;
  238. end;
  239. procedure TForm1.write_buttonClick(Sender: TObject);
  240. begin
  241.   stop_button.Enabled:=false;
  242.   read_button.Enabled:=false;
  243.   write_button.Enabled:=false;
  244.   browse_button.Enabled:=true;
  245.   cancel_button.Enabled:=true;
  246.   browse_button.Caption:='本地浏览';
  247.   path_edit.Enabled:=false;
  248.   transmode:=false;
  249.   
  250. end;
  251. procedure TForm1.clientUDPRead(Sender: TObject; AData: TStream;
  252.   ABinding: TIdSocketHandle);
  253. var
  254.   i:integer;
  255.   temp:array[1..512] of byte;
  256. begin
  257.   adata.ReadBuffer(recframe,adata.Size);
  258.   case word(flipout(recframe.op)) of
  259.   3:begin
  260.     if (flipin(recframe.info[1],recframe.info[2])=selfinc(ack_NO)) then
  261.     begin
  262.       statusbar.Panels.Items[0].Text:='接收文件';
  263.       require1:=false;
  264.       acktran:=false;
  265.       for i:=1 to adata.Size-4 do
  266.         temp[i]:=recframe.info[i+2];
  267.       blockwrite(to_file,temp,adata.size-4,numwrite);
  268.       count:=count+numwrite;
  269.       if trace then begin
  270.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  271.       logmemo.Lines.Append('Data to local    ');
  272.       logmemo.text:=logmemo.Text+'03'+inttostr(recframe.info[1])+inttostr(recframe.info[2]);
  273.       logmemo.Text:=logmemo.Text+'   信息长度  '+inttostr(numwrite)+'  byte';
  274.       end;
  275.       ack_NO:=ack_NO+1;
  276.       transframe.op:=word(flipout(4));
  277.       transframe.info[1]:=flipout(ack_NO).a1;
  278.       transframe.info[2]:=flipout(ack_NO).a2;
  279.       client.SendBuffer(remoteIP,remotePort,transframe,4);
  280.       acktran:=true;
  281.       reqcount:=0;
  282.       if trace then begin
  283.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  284.       logmemo.Lines.Append('ACK to '+remoteIP+'    ');
  285.       logmemo.text:=logmemo.Text+'04'+inttostr(transframe.info[1])+inttostr(transframe.info[2]);
  286.       end;
  287.       if numwrite<512 then
  288.       begin
  289.         closefile(to_file);
  290.         numwrite:=0;
  291.         ack_NO:=0;
  292.         read_button.Enabled:=true;
  293.         write_button.Enabled:=true;
  294.         stop_button.Enabled:=true;
  295.         path_edit.Enabled:=false;
  296.         statusbar.Panels.Items[0].Text:='接收完毕';
  297.         logmemo.Lines.Append('文件接受完毕');
  298.         timeready:=false;
  299.         acktran:=false;
  300.       end;
  301.     end;
  302.   end;
  303.   4:begin
  304.     if (flipin(recframe.info[1],recframe.info[2])=block_NO) then
  305.     begin
  306.       trans:=false;
  307.       if last then block_NO:=0
  308.       else begin
  309.         if trace then begin
  310.           logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  311.           logmemo.Lines.Append('ACK to local   ');
  312.           logmemo.text:=logmemo.Text+'04'+inttostr(recframe.info[1])+inttostr(recframe.info[2]);
  313.         end;
  314.         statusbar.Panels.Items[0].Text:='发送文件';
  315.         require2:=false;
  316.         block_NO:=block_NO+1;
  317.         blockread(from_file,temp,512,numread);
  318.         transframe.op:=word(flipout(3));
  319.         transframe.info[1]:=flipout(block_NO).a1;
  320.         transframe.info[2]:=flipout(block_NO).a2;
  321.         for i:=3 to numread+2 do
  322.         transframe.info[i]:=temp[i-2];
  323.         client.SendBuffer(remoteIP,remotePort,transframe,numread+4);
  324.         trans:=true;
  325.         reqcount:=0;
  326.         if trace then begin
  327.           logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  328.           logmemo.Lines.Append('Data to '+remoteIP+'   ');
  329.           logmemo.text:=logmemo.Text+'03'+inttostr(transframe.info[1])+inttostr(transframe.info[2]);
  330.           logmemo.Text:=logmemo.Text+' 信息长度  '+inttostr(numread)+'  byte';
  331.         end;
  332.         if numread<512 then
  333.         begin
  334.           statusbar.Panels.Items[0].Text:='发送完毕';
  335.           logmemo.Lines.Append('文件发送完毕');
  336.           closefile(from_file);
  337.           last:=true;
  338.           numread:=0;
  339.           cancel_button.Enabled:=true;
  340.           read_button.Enabled:=true;
  341.           write_button.Enabled:=true;
  342.           stop_button.Enabled:=true;
  343.           timeready:=false;
  344.         end;
  345.         count:=count+numread;
  346.       end;
  347.     end;
  348.   end;
  349.   5:begin
  350.     logmemo.Lines.Append(datetostr(date)+'   '+timetostr(now));
  351.     logmemo.Lines.Append('error: code='+inttostr(flipin(recframe.info[1],recframe.info[2])));
  352.     require1:=false;
  353.     case flipin(recframe.info[1],recframe.info[2]) of
  354.     0:begin
  355.        filename:='';
  356.        for i:=3 to adata.Size-2 do
  357.          filename:=filename+chr(recframe.info[i]);
  358.        showmessage(filename);
  359.        logmemo.Lines.Append(filename);
  360.     end;
  361.     1: begin
  362.       showmessage('File not found.');
  363.       logmemo.Lines.Append(datetostr(date)+'   '+timetostr(now));
  364.       logmemo.Lines.Append('error: code=1');
  365.       logmemo.Lines.Append('File not found');
  366.     end;
  367.     2:begin
  368.       showmessage('Access violation.');
  369.       logmemo.Lines.Append(datetostr(date)+'   '+timetostr(now));
  370.       logmemo.Lines.Append('error: code=1');
  371.       logmemo.Lines.Append('Access violation.');
  372.     end;
  373.     3: begin
  374.       showmessage('Disk full or allocation exceeded.');
  375.       logmemo.Lines.Append(datetostr(date)+'   '+timetostr(now));
  376.       logmemo.Lines.Append('error: code=1');
  377.       logmemo.Lines.Append('Disk full or allocation exceeded.');
  378.     end;
  379.     4:begin
  380.       showmessage('Illegal TFTP operation.');
  381.       logmemo.Lines.Append(datetostr(date)+'   '+timetostr(now));
  382.       logmemo.Lines.Append('error: code=1');
  383.       logmemo.Lines.Append('Illegal TFTP operation.');
  384.     end;
  385.     5:begin
  386.       showmessage('Unknown transfer ID.');
  387.       logmemo.Lines.Append(datetostr(date)+'   '+timetostr(now));
  388.       logmemo.Lines.Append('error: code=1');
  389.       logmemo.Lines.Append('Unknown transfer ID.');
  390.     end;
  391.     6:begin
  392.       showmessage('File already exists.');
  393.       logmemo.Lines.Append(datetostr(date)+'   '+timetostr(now));
  394.       logmemo.Lines.Append('error: code=1');
  395.       logmemo.Lines.Append('File already exists.');
  396.     end;
  397.     7:begin
  398.       showmessage('No such user.');
  399.       logmemo.Lines.Append(datetostr(date)+'   '+timetostr(now));
  400.       logmemo.Lines.Append('error: code=1');
  401.       logmemo.Lines.Append('No such user.');
  402.     end;
  403.     end;
  404.     block_NO:=0;
  405.     ack_NO:=0;
  406.     read_button.Enabled:=true;
  407.     write_button.Enabled:=true;
  408.     cancel_button.Enabled:=true;
  409.     stop_button.Enabled:=true;
  410.   end;
  411.   end;
  412. end;
  413. procedure TForm1.cancel_buttonClick(Sender: TObject);
  414. begin
  415.   statusbar.Panels.Items[0].Text:='空闲';
  416.   browse_button.Enabled:=false;
  417.   cancel_button.Enabled:=false;
  418.   path_edit.Enabled:=false;
  419.   read_button.Enabled:=true;
  420.   write_button.Enabled:=true;
  421.   stop_button.Enabled:=true;;
  422. end;
  423. procedure TForm1.stop_buttonClick(Sender: TObject);
  424. begin
  425.   stop_button.Enabled:=false;
  426.   apply_button.Enabled:=true;
  427.   client.Active:=false;
  428.   client.Bindings.Items[0].Free;
  429.   statusbar.Panels.Items[0].Text:='空闲';
  430. end;
  431. procedure TForm1.Timer1Timer(Sender: TObject);
  432. var
  433.   i:integer;
  434.   v:real;
  435. begin
  436.   if require1 then
  437.   begin
  438.     reqcount:=reqcount+1;
  439.     for i:=1 to 512 do
  440.       if transframe.info[i]=0 then break;
  441.     client.SendBuffer(remoteIP,remotePort,transframe,i+8);
  442.     if reqcount=5 then
  443.     begin
  444.       showmessage('连接主机超时');
  445.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  446.       logmemo.Lines.Append('连接主机超时');
  447.       block_NO:=0;
  448.       ack_NO:=0;
  449.       read_button.Enabled:=true;
  450.       write_button.Enabled:=true;
  451.       cancel_button.Enabled:=true;
  452.       stop_button.Enabled:=true;
  453.       require1:=false;
  454.       statusbar.Panels.Items[0].Text:='重置';
  455.     end;
  456.   end;
  457.   if require2 then
  458.   begin
  459.     reqcount:=reqcount+1;
  460.     for i:=1 to 512 do
  461.       if transframe.info[i]=0 then break;
  462.     client.SendBuffer(remoteIP,remotePort,transframe,i+8);
  463.     if reqcount=5 then
  464.     begin
  465.       showmessage('连接主机超时');
  466.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  467.       logmemo.Lines.Append('连接主机超时');
  468.       statusbar.Panels.Items[0].Text:='重置';
  469.       block_NO:=0;
  470.       ack_NO:=0;
  471.       read_button.Enabled:=true;
  472.       write_button.Enabled:=true;
  473.       cancel_button.Enabled:=true;
  474.       stop_button.Enabled:=true;
  475.       require2:=false;
  476.     end;
  477.   end;
  478.   if trans then
  479.   begin
  480.     reqcount:=reqcount+1;
  481.     if (reqcount mod 3=0) then
  482.       client.SendBuffer(remoteIP,remotePort,transframe,numread+4);
  483.     if reqcount=9 then
  484.     begin
  485.       showmessage('发送文件超时');
  486.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  487.       logmemo.Lines.Append('发送文件超时');
  488.       block_NO:=0;
  489.       ack_NO:=0;
  490.       read_button.Enabled:=true;
  491.       write_button.Enabled:=true;
  492.       cancel_button.Enabled:=true;
  493.       stop_button.Enabled:=true;
  494.       trans:=false;
  495.       statusbar.Panels.Items[0].Text:='重置';
  496.       timeready:=false;
  497.     end;
  498.   end;
  499.   if acktran then
  500.   begin
  501.     reqcount:=reqcount+1;
  502.     if (reqcount mod 9=0) then
  503.       client.SendBuffer(remoteIP,remotePort,transframe,numread+4);
  504.     if reqcount=20 then
  505.     begin
  506.       showmessage('接收文件超时');
  507.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  508.       logmemo.Lines.Append('接收文件超时');
  509.       block_NO:=0;
  510.       ack_NO:=0;
  511.       read_button.Enabled:=true;
  512.       write_button.Enabled:=true;
  513.       cancel_button.Enabled:=true;
  514.       stop_button.Enabled:=true;
  515.       trans:=false;
  516.       statusbar.Panels.Items[0].Text:='重置';
  517.       acktran:=false;
  518.       timeready:=false;
  519.     end;
  520.   end;
  521.   if timeready then
  522.   begin
  523.     starttime:=starttime+1;
  524.     if starttime<>0 then
  525.       begin
  526.         v:=count/starttime/1000;
  527.         statusbar.Panels.Items[1].Text:='速度: '+inttostr(trunc(v))+'KB/s';
  528.       end;
  529.   end;
  530. end;
  531. procedure TForm1.trace_buttonClick(Sender: TObject);
  532. begin
  533.   if  not trace then
  534.   begin
  535.     trace:=true;
  536.     trace_button.Caption:='停止跟踪';
  537.   end
  538.   else begin
  539.     trace:=false;
  540.     trace_button.Caption:='跟踪传输';
  541.   end;
  542. end;
  543. procedure TForm1.clear_ButtonClick(Sender: TObject);
  544. begin
  545.   logmemo.Clear;
  546. end;
  547. procedure TForm1.save_buttonClick(Sender: TObject);
  548. begin
  549.   logmemo.Lines.SaveToFile(getcurrentdir+'/save.txt');
  550. end;
  551. end.