Indy 10 TCPServer не связывается с подключенными клиентами в Linux

У меня есть проблема, которая ведет меня вверх по стене . Я пытаюсь перенести серверную часть клиент-серверного приложения Indy 10 в Windows на Linux, чтобы сэкономить средства. Приложение изначально разрабатывалось с использованием Delphi 2010. С тех пор я перенес его на Lazarus / FreePascal, и оно отлично работает на Windows. Учитывая, что Lazarus / FreePascal является мультиплатформенным и бесплатным, он является идеальным кандидатом на работу.

Я перепробовал все возможное, чтобы серверное приложение работало в Linux без успеха. Сервер просто не связывается с подключенными клиентами. Вообще ничего!

Затем я решил вернуться на круги своя. Я попытался получить очень простой пример для работы на Linux. Соответствующие части исходного кода, как показано ниже

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
  s: string;
  i: Integer;
begin
  with AContext.Connection.IOHandler do
  try
    WriteLn('Type an integer and Enter');
    s := ReadLn;
    try
      i := StrToInt(s);
      WriteLn(s + ' squared is ' + IntToStr(i*i));
    except
      WriteLn(s + ' is not an integer');
    end;
  finally
    Free;
  end;
end;

procedure TForm1.FormActivate(Sender: TObject);
var
  Binding: TIdSocketHandle;
begin
  {$IFDEF UNIX}
  Binding := IdTCPServer1.Bindings.Add;
  //Binding.IPVersion := Id_IPv4;   <----- Gives compilation error Error: Identifier not found "Id_IPv4"
  {$ENDIF}
  Binding.IP := '127.0.0.1';
  Binding.Port := 6501;
  IdTCPServer1.Active := True;
end;

end.

Это файл проекта программы squares.lpr

program squares;

{$mode objfpc}{$H+}
// The following line is is necessary for Linux thread support            
{$IFDEF UNIX}{$DEFINE UseCThreads}{$ENDIF}     

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, uSquares
  { you can add units after this };

{$R *.res}

begin
  RequireDerivedFormResource := True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Когда я пытаюсь подключиться к серверу из терминала, используя telnet, я получаю следующий ответ

telnet 127.0.0.1 6501
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
7
Connection closed by foreign host.

Как видите, telnet подключается к серверу. Но первый ответ сервера после подключения клиента «Введите целое число и Enter» не отображается. Кроме того, когда я отправляю число на сервер, например, «7» для квадрата, telnet говорит «Соединение закрыто внешним хостом». Таким образом, клиент telnet также не получает ответы сервера вообще. Я использую версию Indy SVN, поэтому речь не идет о старой версии Indy.

Так что даже этот базовый пример не работает в Linux! Я не знаю, как решить эту проблему, поэтому мне очень нужна ваша помощь. Кроме того, если у вас есть материал, который я могу прочитать о программировании сокетов в Linux с использованием Pascal, я буду очень признателен.

Я использую Lazarus 0.9.31 / FPC 2.4.4 и Indy 10.5.8 на Linux Mint.

JDaniel

linux,delphi,client-server,freepascal,indy10,

1

Ответов: 2


Id_IPv4определяется в IdGlobal.pas, убедитесь, что в вашем usesпредложении указан блок . Обратите внимание, что вы звоните, Bindings.Add()только если определена UNIX, но вы пытаетесь получить доступ к Bindingвнешней стороне блока IFDEF. Вам не нужен блок IFDEF вообще. Indy по умолчанию IPv4.

Что касается проблемы со связью, я не вижу ничего плохого в показанном вами коде, при условии, что FreePascal правильно вызывает, TIdIOHandler.WriteLn()а не какая-то консольная процедура ввода-вывода WriteLn (). Можете ли вы показать код клиента?

На стороне сервера, единственное, о чем я сейчас могу подумать, что это может пойти не так, это возможный сбой в классе TIdTextEncoding в Indy при отправке / получении строк, если вы установили TIdIOHandler.DefStringEncodingсвойство или глобальную GIdDefaultEncodingпеременную в кодировку не по умолчанию. В системах, отличных от Windows, TIdTextEncoding использует библиотеку iconv, и поддержка iconv в Indy, как известно, в настоящее время немного ошибочна. С другой стороны, кодировкой Indy по умолчанию является ASCII, которая вообще не использует iconv, поэтому при ее использовании не должно быть никаких сбоев.


@ Реми Лебо. Я нашел ответ. Я играл с кодировкой текста, пока не получил код, который работает ниже:

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
  s: string;
  i: Integer;
begin
  with AContext.Connection.IOHandler do
  try
    {$IFDEF UNIX}
    DefStringEncoding := TIdTextEncoding.Default
    {$ENDIF}
    WriteLn('Type an integer and Enter');
    s := ReadLn;
    try
      i := StrToInt(s);
      WriteLn(s + ' squared is ' + IntToStr(i*i));
    except
      WriteLn(s + ' is not an integer');
    end;
  finally
    Free;
  end;
end;

procedure TForm1.FormActivate(Sender: TObject);
var
  Binding: TIdSocketHandle;
begin
  {$IFDEF UNIX}
  Binding := IdTCPServer1.Bindings.Add;
  Binding.Port := 6501;
  {$ENDIF}
  {IFDEF MSWINDOWS}
  IdTCPServer1.DefaultPort := 6501
  {$ENDIF} 
  IdTCPServer1.Active := True;
end;

Это ответ telnet:

telnet 127.0.0.1 6501
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Type an integer and Enter
7
7 squared is 49
Connection closed by foreign host.

Однако я все еще хотел бы знать, как я могу установить глобальную переменную GIdDefaultEncoding, чтобы я мог покончить с DefStringEncoding: = TIDTextEncoding.Default . Спасибо за вашу помощь.

Linux, Дельфы, клиент-сервер, FreePascal, indy10,
Похожие вопросы