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

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('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.     end;
  360.     1: showmessage('File not found.');
  361.     2: showmessage('Access violation.');
  362.     3: showmessage('Disk full or allocation exceeded.');
  363.     4: showmessage('Illegal TFTP operation.');
  364.     5: showmessage('Unknown transfer ID.');
  365.     6: showmessage('File already exists.');
  366.     7: showmessage('No such user.');
  367.     end;
  368.     block_NO:=0;
  369.     ack_NO:=0;
  370.     read_button.Enabled:=true;
  371.     write_button.Enabled:=true;
  372.     cancel_button.Enabled:=true;
  373.     stop_button.Enabled:=true;
  374.   end;
  375.   end;
  376. end;
  377. procedure TForm1.cancel_buttonClick(Sender: TObject);
  378. begin
  379.   statusbar.Panels.Items[0].Text:='空闲';
  380.   browse_button.Enabled:=false;
  381.   cancel_button.Enabled:=false;
  382.   path_edit.Enabled:=false;
  383.   read_button.Enabled:=true;
  384.   write_button.Enabled:=true;
  385.   stop_button.Enabled:=true;;
  386. end;
  387. procedure TForm1.stop_buttonClick(Sender: TObject);
  388. begin
  389.   stop_button.Enabled:=false;
  390.   apply_button.Enabled:=true;
  391.   client.Active:=false;
  392.   client.Bindings.Items[0].Free;
  393.   statusbar.Panels.Items[0].Text:='空闲';
  394. end;
  395. procedure TForm1.Timer1Timer(Sender: TObject);
  396. var
  397.   i:integer;
  398.   v:real;
  399. begin
  400.   if require1 then
  401.   begin
  402.     reqcount:=reqcount+1;
  403.     for i:=1 to 512 do
  404.       if transframe.info[i]=0 then break;
  405.     client.SendBuffer(remoteIP,remotePort,transframe,i+8);
  406.     if reqcount=5 then
  407.     begin
  408.       showmessage('连接主机超时');
  409.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  410.       logmemo.Lines.Append('连接主机超时');
  411.       block_NO:=0;
  412.       ack_NO:=0;
  413.       read_button.Enabled:=true;
  414.       write_button.Enabled:=true;
  415.       cancel_button.Enabled:=true;
  416.       stop_button.Enabled:=true;
  417.       require1:=false;
  418.       statusbar.Panels.Items[0].Text:='重置';
  419.     end;
  420.   end;
  421.   if require2 then
  422.   begin
  423.     reqcount:=reqcount+1;
  424.     for i:=1 to 512 do
  425.       if transframe.info[i]=0 then break;
  426.     client.SendBuffer(remoteIP,remotePort,transframe,i+8);
  427.     if reqcount=5 then
  428.     begin
  429.       showmessage('连接主机超时');
  430.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  431.       logmemo.Lines.Append('连接主机超时');
  432.       statusbar.Panels.Items[0].Text:='重置';
  433.       block_NO:=0;
  434.       ack_NO:=0;
  435.       read_button.Enabled:=true;
  436.       write_button.Enabled:=true;
  437.       cancel_button.Enabled:=true;
  438.       stop_button.Enabled:=true;
  439.       require2:=false;
  440.     end;
  441.   end;
  442.   if trans then
  443.   begin
  444.     reqcount:=reqcount+1;
  445.     if (reqcount mod 3=0) then
  446.       client.SendBuffer(remoteIP,remotePort,transframe,numread+4);
  447.     if reqcount=9 then
  448.     begin
  449.       showmessage('发送文件超时');
  450.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  451.       logmemo.Lines.Append('发送文件超时');
  452.       block_NO:=0;
  453.       ack_NO:=0;
  454.       read_button.Enabled:=true;
  455.       write_button.Enabled:=true;
  456.       cancel_button.Enabled:=true;
  457.       stop_button.Enabled:=true;
  458.       trans:=false;
  459.       statusbar.Panels.Items[0].Text:='重置';
  460.       timeready:=false;
  461.     end;
  462.   end;
  463.   if acktran then
  464.   begin
  465.     reqcount:=reqcount+1;
  466.     if (reqcount mod 9=0) then
  467.       client.SendBuffer(remoteIP,remotePort,transframe,numread+4);
  468.     if reqcount=20 then
  469.     begin
  470.       showmessage('接收文件超时');
  471.       logmemo.Lines.Append(datetostr(date)+' '+timetostr(now));
  472.       logmemo.Lines.Append('接收文件超时');
  473.       block_NO:=0;
  474.       ack_NO:=0;
  475.       read_button.Enabled:=true;
  476.       write_button.Enabled:=true;
  477.       cancel_button.Enabled:=true;
  478.       stop_button.Enabled:=true;
  479.       trans:=false;
  480.       statusbar.Panels.Items[0].Text:='重置';
  481.       acktran:=false;
  482.       timeready:=false;
  483.     end;
  484.   end;
  485.   if timeready then
  486.   begin
  487.     starttime:=starttime+1;
  488.     if starttime<>0 then
  489.       begin
  490.         v:=count/starttime/1000;
  491.         statusbar.Panels.Items[1].Text:='速度: '+inttostr(trunc(v))+'KB/s';
  492.       end;
  493.   end;
  494. end;
  495. procedure TForm1.trace_buttonClick(Sender: TObject);
  496. begin
  497.   if  not trace then
  498.   begin
  499.     trace:=true;
  500.     trace_button.Caption:='停止';
  501.   end
  502.   else begin
  503.     trace:=false;
  504.     trace_button.Caption:='跟踪';
  505.   end;
  506. end;
  507. procedure TForm1.clear_ButtonClick(Sender: TObject);
  508. begin
  509.   logmemo.Clear;
  510. end;
  511. procedure TForm1.save_buttonClick(Sender: TObject);
  512. begin
  513.   logmemo.Lines.SaveToFile(getcurrentdir+'/save.txt');
  514. end;
  515. end.