首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编写Delphi代码的Indy 10到C ++ Builder的Indy 10

编写Delphi代码的Indy 10到C ++ Builder的Indy 10
EN

Stack Overflow用户
提问于 2015-06-27 19:54:26
回答 1查看 508关注 0票数 1

我刚开始学习C ++生成器。三天前,我安装了Embarcadero。C++Builder®2010。这门语言对我来说很有趣。

在Delphi中,我通常使用Indy 9和10的TIdMappedPortTCP编写一个简单的代理服务器,通常在数据通过代理时使用它的OnExecute和OnOutboundData事件来修改数据。

因为我是C ++ Builder的新手,所以我不知道如何将我的++代码转换成完全正确的C++ Builder代码。

我尝试并尝试了许多方法,包括阅读几本书,其中一本是Borland C ++ Builder -- Herbert Schildt的完整参考,以及增加知识。不幸的是,书中根本没有讨论过与我的状况有关的非常重要的事情。另外,我在谷歌上找到了参考资料,但我没有找到。

所以,我大胆地请求你的帮助。我真的需要它。请帮帮我!非常感谢。

下面是我的Indy 10的Delphi代码,我想写到C ++生成器。

代码语言:javascript
复制
......

procedure TForm.IdMappedPortTCP1Execute(AContext: TIdContext);
var
Mydata, NetData: string;
begin
  if (Pos('HTTP',netstring(AContext)) <> 0) or (Pos('GET',netstring(AContext)) <> 0) then begin
   NetData := netstring(AContext);
   TIdMappedPortContext(AContext).OutboundClient.IOHandler.Write(AddHeader(netstring(AContext),'Connection: Keep-Alive'));
     Sleep(1000);
     Mydata  := 'GET http://website.com/ HTTP/1.1'+#13#10+'Host: website.com'#13#10;
     NetData := Mydata + Netdata;
   TIdMappedPortContext(AContext).NetData := netbyte(Netdata);
   TIdMappedPortContext(AContext).OutboundClient.IOHandler.Write(netbyte(Mydata + NetData));
  end;
end;

......
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-28 00:23:21

C++Builder的直译如下所示:

代码语言:javascript
复制
......

String __fastcall AddHeader(String S, String Header)
{
    S = StringReplace(S, "\r\n\r\n", "\r\n" + Header + "\r\n\r\n", TReplaceFlags() << rfReplaceAll);
    return S;
}

void __fastcall TForm::IdMappedPortTCP1Execute(TIdContext *AContext)
{
    String Mydata, NetData;

    if ((netstring(AContext).Pos("HTTP") != 0) || (netstring(AContext).Pos("GET") != 0))
    {
        NetData = netstring(AContext);
        TIdMappedPortContext(AContext)->OutboundClient->IOHandler->Write(AddHeader(netstring(AContext), "Connection: Keep-Alive"));
        Sleep(1000);
        Mydata = "GET http://website.com/ HTTP/1.1\r\nHost: website.com\r\n";
        NetData = Mydata + Netdata;
        static_cast<TIdMappedPortContext*>(AContext)->NetData = netbyte(Netdata);
        static_cast<TIdMappedPortContext*>(AContext)->OutboundClient->IOHandler->Write(netbyte(Mydata + NetData));
    }
}

......

以下是一个略为浓缩的版本:

代码语言:javascript
复制
......

String __fastcall AddHeader(String S, String Header)
{
    return StringReplace(S, "\r\n\r\n", "\r\n" + Header + "\r\n\r\n", TReplaceFlags() << rfReplaceAll);
}

void __fastcall TForm::IdMappedPortTCP1Execute(TIdContext *AContext)
{
    String NetData = netstring(AContext);
    if ((NetData.Pos("HTTP") != 0) || (NetData.Pos("GET") != 0))
    {
        Sleep(1000);
        String Mydata = "GET http://website.com/ HTTP/1.1\r\nHost: website.com\r\n" + AddHeader(NetData, "Connection: Keep-Alive");
        static_cast<TIdMappedPortContext*>(AContext)->NetData = netbyte(Mydata);
    }
}

......

但无论是哪种方式,这肯定不是在Indy中实现可行的HTTP代理的可靠方法。事实上,Indy 10为此引入了一个特定的TIdHTTPProxyServer组件。您应该认真考虑使用它而不是TIdMappedPortTCP。例如,在TIdHTTPProxyServer中可以这样做:

代码语言:javascript
复制
class TIdHTTPProxyServerContextAccess : public TIdHTTPProxyServerContext
{
public:
    void SetCommand(String Value) { FCommand = Value; }
    void SetDocument(String Value) { FDocument = Value; }
    void SetTarget(String Value) { FTarget = Value; }
};

void __fastcall TForm1.IdHTTPProxyServer1HTTPBeforeCommand(TIdHTTPProxyServerContext *AContext)
{
    static_cast<TIdHTTPProxyServerContextAccess*>(AContext)->SetCommand("GET");
    static_cast<TIdHTTPProxyServerContextAccess*>(AContext)->SetTarget ("http://website.com/");
    static_cast<TIdHTTPProxyServerContextAccess*>(AContext)->SetDocument("/");

    AContext->Headers->Values["Host"] = "website.com";
    AContext->Headers->Values["Connection"] = "Keep-Alive";

    /*
    the original code was not changing the Host/Port where the
    HTTP request was being sent to.  But if you needed to,
    you can do it like this... 

    static_cast<TIdTCPClient*>(AContext->OutboundClient)->Host = "website.com";
    static_cast<TIdTCPClient*>(AContext->OutboundClient)->Port = 80;
    */
}

Update:您链接到的netstring()netbyte()函数具有语法错误,并且有不必要的开销(不需要仅为了将字符串转换为字节数组而涉及MIME,反之亦然,Indy具有专门用于此目的的函数)。以下是修正后的版本:

代码语言:javascript
复制
String __fastcall netstring(TIdMappedPortContext* AContext)
{
    return BytesToStringRaw(AContext->NetData);
}

TIdBytes __fastcall netbyte(String S)
{
    return ToBytes(S, IndyTextEncoding_8Bit());
}

因此,您实际上可以完全消除这些功能:

代码语言:javascript
复制
void __fastcall TForm::IdMappedPortTCP1Execute(TIdContext *AContext)
{
    TIdMappedPortContext *ctx = static_cast<TIdMappedPortContext*>(AContext)
    String NetData = BytesToStringRaw(ctx->NetData);
    if ((NetData.Pos("HTTP") != 0) || (NetData.Pos("GET") != 0))
    {
        Sleep(1000);
        String Mydata = "GET http://website.com/ HTTP/1.1\r\nHost: website.com\r\n" + AddHeader(NetData, "Connection: Keep-Alive");
        ctx->NetData = ToBytes(Mydata);
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31092912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档