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