程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 用Delphi設計代理服務器[正確文章]

用Delphi設計代理服務器[正確文章]

編輯:Delphi

用Delphi設計自己的代理服務器

    筆者在編寫一個上網計費軟件時,涉及到如何對局域網中各工作站上網計費問題。一般來講,這些工作站通過代理服務器上網,而采用現成的代理服務器軟件時,由於代理服務器軟件是封閉的系統,很難編寫程序獲取實時的上網計時信息。因此,考慮是否能編寫自己的代理服務器,一方面解決群體上網,另一方面又解決上網的計費問題呢?
    經過實驗性編程,終於圓滿地解決了該問題。現寫出來,與各位同行分享。

1、 思路
當前流行的浏覽器的系統選項中有一個參數,即“通過代理服務器連接”,經過編程測
試,當局域網中一台工作站指定了該屬性,再發出Internet請求時,請求數據將發送到所指定的代理服務器上,以下為請求數據包示例:
                 GET http://home.microsoft.com/intl/cn/ HTTP/1.0
                 Accept: */*
                 Accept-Language: zh-cn
                 Accept-Encoding: gzip, deflate
                 User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)
                 Host: home.microsoft.com
                 Proxy-Connection: Keep-Alive
其中第一行為目標URL及相關方法、協議,“Host”行指定了目標主機的地址。
由此知道了代理服務的過程:接收被代理端的請求、連接真正的主機、接收主機返回的數據、將接收數據發送到被代理端。
為此可編寫一個簡單的程序,完成上述網絡通信重定向問題。
用Delphi設計時,選用ServerSocket作為與被代理工作站通信的套接字控件,選用ClientSocket動態數組作為與遠程主機通信的套接字控件。
編程時應解決的一個重要問題是多重連接處理問題,為了加快代理服務的速度和被代理端的響應速度,套接字控件的屬性應設為非阻塞型;各通信會話與套接字動態綁定,用套接字的SocketHandle屬性值確定屬於哪一個會話。
通信的銜接過程如下圖所示:

                                  代理服務器
                                 
                                  Serversocket
                        (1)          接  收
         被代理端                   發  送                        遠程主機
                        (6)        (2)      (5)
         Browser                  ClientSocket       (4)            Web Server
                                    接  收
                                    發  送          (3)


(1)、被代理端浏覽器發出Web請求,代理服務器的Serversocket接收到請求。
(2)、代理服務器程序自動創建一個ClientSocket,並設置主機地址、端口等屬性,然後連接遠程主機。
(3)、遠程連通後激發發送事件,將Serversocket接收到的Web請求數據包發送到遠程主機。
(4)、當遠程主機返回頁面數據時,激發ClientSocket的讀事件,讀取頁面數據。
(5)、代理服務器程序根據綁定信息確定屬於ServerSocket控件中的哪一個Socket應該將從主機接收的頁面信息發送到被代理端。
(6)、ServerSocket中的對應Socket將頁面數據發送到被代理端。

2、 程序編寫
使用Delphi設計以上通信過程非常簡單,主要是ServerSocket、ClientSocket的相關事
件驅動程序的程序編寫。下面給出作者編寫的實驗用代理服務器界面與源程序清單,內含簡要功能說明:

unit main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, ScktComp, TrayIcon, Menus, StdCtrls;

type
   session_record=record
      Used: boolean;                       {會話記錄是否可用}
      SS_Handle: integer;                  {代理服務器套接字句柄}
      CSocket: TClientSocket;              {用於連接遠程的套接字}
      Lookingup: boolean;                  {是否正在查找服務器}
      LookupTime: integer;                 {查找服務器時間}
      Request: boolean;                    {是否有請求}
      request_str: string;                 {請求數據塊}
      client_connected: boolean;           {客戶機聯機標志}
      remote_connected: boolean;           {遠程服務器連接標志}
end;

type
  TForm1 = class(TForm)
    ServerSocket1: TServerSocket;
    ClientSocket1: TClientSocket;
    Timer2: TTimer;
    TrayIcon1: TTrayIcon;
    PopupMenu1: TPopupMenu;
    N11: TMenuItem;
    N21: TMenuItem;
    N1: TMenuItem;
    N01: TMenuItem;
    Memo1: TMemo;
    Edit1: TEdit;
    Label1: TLabel;
    Timer1: TTimer;
    procedure Timer2Timer(Sender: TObject);
    procedure N11Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure N21Click(Sender: TObject);
    procedure N01Click(Sender: TObject);
    procedure ServerSocket1ClientConnect(Sender: TObject;
    &nbs

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved