在Delphi中,无法从TIdHTTP连接到TIdHTTPServer。

3

我有一个使用Delphi编写的应用程序,其中包含 TIdHTTPServerTIdHTTP,以下是我的代码:

// This is for activating the HTTPServer - works as expected
HTTPServer1.Bindings.Add.IP := '127.0.0.1';
HTTPServer1.Bindings.Add.Port := 50001;
HTTPServer1.Active := True;

这是我的HTTPServer的OnCommandGet过程:
procedure TDataForm.HttpServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  AResponseInfo.ContentText := 'Hello, user';
end;

我不知道为什么这个程序不起作用:

procedure TDataForm.btnHTTPSendGetClick(Sender: TObject);
var
  HTTPClient : TIdHTTP;
  responseStream : TMemoryStream;
begin
  HTTPClient := TIdHTTP.Create;
  responseStream := TMemoryStream.Create;
  try
    try
      HTTPClient.Get('http://127.0.0.1:50001', responseStream);
    except on e : Exception do begin
      showmessage('Could not send get request to localhost, port 50001');
    end;
    end;
  finally
    FreeAndNil(HTTPClient);
    FreeAndNil(responseStream);
  end;
end;

如果我通过浏览器连接,就可以在浏览器中看到“你好,用户”,但是如果我尝试使用btnHTTPSendGetClick,我的程序会崩溃,没有任何异常或其他信息。有人可以帮助我修复我的代码吗?


你使用的是哪个版本的Delphi和Indy?你的代码为什么会在没有异常的情况下崩溃? - Remy Lebeau
@Remy,我在Delphi XE5上使用Indy 10,并在你回答后解释了崩溃的情况。我尝试了你所有的建议,但它仍然会崩溃。 - Viktor Anastasov
1个回答

6

HTTPServer1.Bindings.Add.IP := '127.0.0.1';
HTTPServer1.Bindings.Add.Port := 50001;

这是新手常见的错误。您正在创建两个绑定,一个绑定到127.0.0.1:DefaultPort,另一个绑定到0.0.0.0:50001。您需要一个绑定,而不是两个绑定,并将其绑定到127.0.0.1:50001。

with HTTPServer1.Bindings.Add do begin
  IP := '127.0.0.1';
  Port := 50001;
end;

或者:

HTTPServer1.Bindings.Add.SetBinding('127.0.0.1', 50001, Id_IPv4);

或者:

HTTPServer1.DefaultPort := 50001;
HTTPServer1.Bindings.Add.IP := '127.0.0.1';

话虽如此,您的服务器响应是不完整的。请尝试使用以下方法:

procedure TDataForm.HttpServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  AResponseInfo.ResponseNo := 200;
  AResponseInfo.ContentType := 'text/plain';
  AResponseInfo.ContentText := 'Hello, user';
end;

它怎么没有异常就崩溃了?嗯,你知道的,我的窗体变得模糊并显示“(未响应)”,几分钟后仍然是这样,所以我必须手动结束它。 - Viktor Anastasov
2
@Roman_Bezjak:这意味着您的应用程序被锁定在繁忙的循环中,无法响应窗口消息... - whosrdaddy
@whosrdaddy 我明白了...但是我真的不知道该怎么修复这个问题 :( - Viktor Anastasov
@whosrdaddy 和 @Remy - 我已经解决了,原来我在测试的时候尝试去改变一个 TMemo,但没有使用 TIdCriticalSection。在去掉它之后,现在它完美地运作了。感谢你们及时和充分的帮助,伙计们 :) - Viktor Anastasov
3
使用关键部分无法保护对UI控件的访问,这种方法行不通。您必须与主线程同步,以便主线程是唯一直接访问UI的线程。想要触及UI的其他线程必须请求主线程代表它们执行操作。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接