有如下一个程序,分为客户端和服务器端,客户端使用的是 client1: TIdTCPClient控件 
客户端与服务器端交互的是如下一个结构体来传递信息,
RCommDataBlock:是定义的一个结构体:
PRCommDataBlock = ^RCommDataBlock;    
  RCommDataBlock = Record               
    Cmdtype   : Integer;                  
    cBuffer   : Array[0..1024] of char;
    dwBufSize : DWord;                  
    cPar1: Array[0..19] of char;  
  end;
---------
客户端所有访问服务器的命令都是通过 RequestSv 函数来与服务器交换,获取返回值.
client1.host:=trim(ipstr);             --服务器IP
client1.Port:=StrToInt(trim(portstr)); --我们指定的端口号
EType=Array[0..1024] of char;function RequestSv(var cmdtype:integer;var buffer1:EType; var p1:string;var rsize:DWord):RCommDataBlock;
var
 msg:RCommDataBlock;
begin
 fillchar(msg,sizeof(msg),0);                     
 msg.Cmdtype := cmdtype;
 EType(msg.cBuffer):=buffer1;
 LStrCpy(msg.cPar1,PChar(trim(p1)));
 msg.dwBufSize:=rsize;
               
  client1.WriteBuffer(msg,sizeof(msg)); //提交
  fillchar(msg,sizeof(msg),0);
  client1.ReadBuffer(msg,sizeof(msg));  //反馈 result:=msg;
     
end;
-----------
客户端通过这一函数向服务器发出信息并获取返回信息RCommDataBlock,在客户端程序里解析。现在的问题是如果客户是通过HTTP代理服务器上网的,就无法通过我们指定的端口号来直接访问我们的服务器,
要把如上程序改成支持客户输入代理服务器的IP和端口验证名和密码,支持通过代理来访问我们服务器。这程序该怎么改呢?求详细点的程序,最好在以上程序上修改。

解决方案 »

  1.   

    HTTP代理服務器是這麼玩的.
    我用c寫通過代理取網頁資料.Delphi也差不多.
    socket <---> proxy <--->web主機
    1. gethostbyname 
    2. socket
    3. connect <proxy主機 ,proxy port>
    4. hostsend(sockfd, "GET %s HTTP/1.0\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s   \r\n\r\n", url,
                            "Pragma:no-cache",
                            "Accept-Encoding:GZIP",
                            "Connection:close",
                            "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT5)"
                             "Proxy-Authorization: Basic Z2FuZacoOnB5f2lhxkw="
                            );
         url如"http://www.csdn.net/" 5. recv socket使用這種方式,因為HTTP沒有會話狀態,你可能需要做WebService,
    如果HTTP proxy支持CONNECT,或是使用socks5 Proxy ,那將會簡單得多了.
      

  2.   

    首先谢谢 gangjh!
    要说明一下,客户端和服务器端都是C/S结构的,没有做WebService接口,客户端使用的是client1: TIdTCPClient控件,服务器端是使用的IdTCPServer控件.
    现在代码已经调整到可以支持socks代理登陆,想实现客户端能通过HTTP代理来登陆我们的服务器.
      

  3.   

    求簡單可以試用一下httptunnel ,
    就不用改你的程序了.
      

  4.   

    Synapse的組件TTCPBlockSocket等內有提供httptunnel
      

  5.   

    谢谢gangjh!
    非常不好意思,要问你个很幼稚的问题,无论使用什么控件,是不是通过HTTP代理服务器就只能访问WebService接口呢??
    现在目前服务器端就只有一套C/S结构的.
      

  6.   

    我看了好多代码,发现无论是用什么语言或者控件来实现通过HTTP代理服务器,最终访问的都是IE地址啊,但目前我们要访问的服务器端是没有部署WebService接口的.那照目前情况看是不是根本就无法通过HTTP代理服务器来访问服务器端程序呢???
      

  7.   

    httptunnel,就是一種IP隧道技術.
    httptunnel Sever端bind到 Web 端口80
    httptunnel client再將數據包轉發到--forward-port.你的程序連接到httptunnel client端的--forward-port即可.我試驗過在公司內部使用http tunnel穿過HTTP Proxy,用putty連到家里的linux (ssh) 主機.
      

  8.   

    httptunnel client再將數據包轉發到--forward-port :是不是就是最终的服务器的IP和端口呢?
      

  9.   

    请问使用httptunnel,是不是就可以不修改最终访问的服务器端程序,客户使用的HTTP代理服务器,只单纯在客户端程序里修改,是不?
    还有,大侠是否可提供Synapse的組件TTCPBlockSocket的下载地址呢?
    不胜感激!!
      

  10.   

    下載這個httptunnel程序,就不用改程序,不要synapse的TTCPBlockSocket組件了都可以了.
    需要在客戶端先啟動htc程序.樓主好好研究一下.
    http://eduardo.cobian.free.fr/gnuht/Win32/
      

  11.   

    楼上:你好
    如果照你说的就要多启动一个程序,方法不行,我现在就是要在我目前的程序里改的.我已经转了Synapse的組件TTCPBlockSocket,再研究一下.
      

  12.   

    TO gangjh:你好!
    你说的解决办法还不是我要的,你提到的hts 需要运行在代理服务器端,是吧?这点我们是控制不了的.
      

  13.   

    我希望的效果是,最好不要也不可能在客户的代理服务器上打主意,最好也不要在客户端在运行一个软件.目前我们的服务器端程序(客户登陆后最终要访问的服务器)是C/S结构的,没有WebService接口,又不能在客户使用的HTTP代理服务器上打主意,是不是就不可能实现通过HTTP代理来登陆呢?
      

  14.   

    建议用 ics 
    或着 直接用
    http + iis +isapi delphi在这方面 很好用
      

  15.   

    hts不是在proxy服務端. 是在你的Data Server端.
    htc 在客戶端.
      

  16.   

    将一个局域网的AD0的mis程序升级到互联网的方法:
    1。直接用tcpip:1433连接。“ 路由后的内网”,“代理” 好像有些问题?
       ok,俺用VNN,或者VPN。虽然有点不顾江湖道义。但也是一种方法。
       这一招的名称叫做:“它山之石”
    2。TWebConnection/TSocketConnection。改起来也快。偷懒的人可以
       如下处理:DataSetProvider使用[poAllowCommandText],然后写一
       个工具,替换修改*.pas,*.dfm的代码(控件名字无需改,只改定义
       ,然后就是
       SQL.Clear            >  CommandText:=''
       SQL.Text:='???????'  >  CommandText:=  '???????'
       SQL.Add('????')      > CommandText:=CommandText+'????'#13#10
       )。几百窗体的普通程序也用不了一两天。
       
       这一招的名称叫做:“见山不是山,见水不是水”,看上去是个
       ADOQuery(名字:“ADOQry_select”),其实是个ClientDataSet。(这是
       同事说的)
       
       ps:改之前要备份好。改完了顺道改了delphi自带的
       httpsrvr 或者scktsrvr (个人建议)。
    3。使用ADO2.5以后的新特性(流支持 见附录),改了ADODB.pas。
       例如
       在TADOConnection加
       public
         Httphost: string;
         HttpConnected: boolean;
        我用了HTTP,其实也可用udp,tcpip等等,你要不嫌慢用串口也行。
        另外写了几个函数(见附录)。我把改了的ADODB.pas复制的我的程序
        目录里,加了一句
        ADOConnection1.Httphost := 'http://220.203.0.??/svr/sql.dll/sql';
        编译一下,运行,俺的程序就 晃晃悠悠的运行在web服务器的数据库下
        了。另外我做了
      

  17.   

    俺之所以这样用的 原因:
        1。以前的程序可以轻松的使用互联网的数据库
           只需根据设置决定是否执行
           ADOConn.Httphost := 'http://220.203.0.??/svr/sql.dll/sql';
        2。WebConnection速度慢,SocketConnection大数据量下也不好。
        3。这样改的程序可以可以通过设置在局域网中依然用原来的
           模式(速度快)。例如
             if DebugHook=0 then
                ADOConn.Httphost := 'http://220.203.0.??/logserver/sql.dll/sql'
                else
                ....................
           这样可以在delphi 调试时连本地库(速度快 呵呵)。
           一句话,就是灵活了。         
        缺点:
          事务 与WebConnection 一样,自己处理。
        
        其实 这种方法是邪派的,不过我经常遇到一些问题,时间紧,就只好用邪派的招数了。
        以前要一天内将一个access的程序(我记得好像是121个窗体)改到sql server上,同时
        access的版本也要一直继续下去,因为客户的环境不一样。当时我也是改了ADODB.pas,
        主要是加了一个sql转换的环节,即将access的某些函数转为sql server 的,如:
        trim()  >  ltrim(rtrim())  instr > charindex 等 另外配合一些sql server 自定义
        的函数 。
        正统的做法,改成b/s的吧。因为如果使用web的数据,整体的设计思路不一样,例如,如
        果要用WebConnection 你要注意连接的次数,事物处理,脱机时的处理。注意这是正统,
        不是正确,正确的方法要视情况定,时间,人手,性能要求,后续发展。。
      

  18.   

    http://www.delphibbs.com/delphibbs/dispq.asp?lid=3303659
      

  19.   

    TO gangjh:
    那还是要在服务器端运行个软件.我就想知道,照我目前系统的情况(服务器的设计已经说明了),是不是我们的服务器的设计(加上不能在我们的服务器和用户使用的HTTP代理服务器上运行其他东西)就决定了无法通过HTTP代理服务器来访问它呢??
      

  20.   

    客戶公司使用了HTTP  proxy,
    一般來說, 就限制了客戶公司內部電腦只能訪問外網Web端口,一般允許80,8080通過.
    1. 首先,需要欺騙HTTP  PROXY,認為你的Server為 WEB端口.需要修改你的服務端程序在80端口監聽.或使用hts轉發.
    2. 這時,如果你的Server是WEB,客戶瀏覽器通過Proxy就可以訪問了. 但你現在不是.
       如果PROXY支持CONNECT方法,這時你的Client程序發出CONNET dataserver,Proxy會忠實轉發Client以及Server間的數據包.
       否則你可以用htc將數據包還原. 3 .如需訪問SQL Server(1433).
    htc  ----------------> http proxy -----------> hts ---------> db serve
    (localhost:1433)      (proxyhost:80)         (sql_srv:80)   (sql_srv:1080)討論技術可以這麼做,和客戶協商裝個socks5 Sever是個好方法.