2013-10-09 3 views
0

У меня возникли проблемы с динамическим созданием некоторого сообщения INDY. Я раньше не использовал Indy, и я не могу настроить сервер правильно. Я получаю ошибку 10061. Я добавил правило к стене огня, чтобы это приложение и порт. Он работает, если я использую TServerSocket и TClientSocket, но мне нужно использовать Indy.Ошибка подключения клиента клиента Indy Dynamic 10061

Этот код не работает

procedure TForm3.Button3Click(Sender: TObject); 
var 
    temp   : TIdSocketHandles; 

begin 
    fIdTCPServer1 := TIdTCPServer.Create(nil); 
    fIdTCPClient1 := TIdTCPClient.Create(nil); 
    temp := TIdSocketHandles.Create(fIdTCPServer1); 
    temp.Add.IP := 'xxx.xx.xxx.xx';//'localhost'; //gave error when tryingn to use local host 
    temp.Add.Port := 20200; 

    fIdTCPServer1.Bindings := temp; 
    fIdTCPServer1.OnExecute := IdTCPServer1Execute; 
    fIdTCPServer1.StartListening(); 


    fIdTCPClient1.Port := 20200; 
    fIdTCPClient1.Host := 'xxx.xx.xxx.xx';//'localhost'; 
    fIdTCPClient1.Connect; //error 10061 here 

    fIdTCPClient1.IOHandler.WriteLn('Some message'); 
end; 
procedure TForm3.IdTCPServer1Execute(AContext: TIdContext); 
var 
    inStr : String; 

begin 
    inStr := AContext.Connection.IOHandler.ReadLn; 
    ShowMessage('Server received : ' + inStr); 
end; 

Этот код работает

procedure TForm3.Button1Click(Sender: TObject); 
begin 
    serverSocket1 := TServerSocket.Create(nil); 
    clientSocket1 := TClientSocket.Create(nil); 

    serverSocket1.Port := 20200; 
    serverSocket1.OnClientRead := ServerSocket1ClientRead; 
    serverSocket1.Active := True; 


    clientSocket1.Port := 20200; 
    clientSocket1.Host := 'localhost'; 
    clientSocket1.Active := True; 
    clientSocket1.Socket.SendText('Some message'); 
end; 

procedure TForm3.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); 
var 
    inStr : String; 
begin 
    inStr := Socket.ReceiveText(); 
    ShowMessage('Server received : ' + inStr); 
end; 

ответ

1

Вам нужно установить как IP адрес и port на каждой привязки.

// Here you're adding a binding and setting only the IP address 
temp.Add.IP := 'xxx.xx.xxx.xx'; 
// Here you're adding another binding and setting only the port 
temp.Add.Port := 20200; 

Вот простой способ сделать это правильно:

with fIdTCPServer1.Bindings.Add do 
begin 
    IP := '127.0.0.1'; // Use IP address, not host name. Localhost = 127.0.0.1 
    Port := 20200; 
end; 

Вот другой, более многословным, способ сделать это (добавить IdSocketHandle к вашей статье изез):

var 
    socketHandle: TIdSocketHandle; 
begin 
    socketHandle := fIdTCPServer1.Bindings.Add; 
    socketHandle.IP := '127.0.0.1'; 
    socketHandle.Port := 20200; 
end; 

Также , чтобы запустить его, вам просто нужно установить значение «Актив» в true следующим образом:

fIdTCPServer1.Active := True; 
+0

Спасибо, что было идеально. – runfastman

0

Есть несколько проблем с вашим кодом.

  1. Вы неправильно используете TIdTCPServer.Bindings, и вы не активируете сервер правильно.

  2. вы звоните ShowMessage() в OnExecute события, но TIdTCPServer многопоточный компонент (каждый подключенный клиент работает в своем собственном потоке) и ShowMessage() не поточно-.

  3. у вас есть некоторые потенциальные утечки памяти в вашем коде.

Попробуйте вместо этого:

procedure TForm3.Button3Click(Sender: TObject); 
var 
    temp : TIdSocketHandle; 
begin 
    if fIdTCPServer1 = nil then 
    begin 
    fIdTCPServer1 := TIdTCPServer.Create(Self); 
    temp := fIdTCPServer1.Bindings.Add; 
    temp.IP := 'xxx.xx.xxx.xx';//'localhost'; //gave error when tryingn to use local host 
    temp.Port := 20200; 
    fIdTCPServer1.OnExecute := IdTCPServer1Execute; 
    fIdTCPServer1.Active := True; 
    end; 

    if fIdTCPClient1 = nil then 
    begin 
    fIdTCPClient1 := TIdTCPClient.Create(Self); 
    fIdTCPClient1.Port := 20200; 
    fIdTCPClient1.Host := 'xxx.xx.xxx.xx';//'localhost'; 
    end; 

    fIdTCPClient1.Connect; 
    fIdTCPClient1.IOHandler.WriteLn('Some message'); 
end; 

procedure TForm3.IdTCPServer1Execute(AContext: TIdContext); 
var 
    inStr : String; 
begin 
    inStr := AContext.Connection.IOHandler.ReadLn; 
    Windows.MessageBox(0, PChar(inStr), PChar('Server received'), MB_OK); 
end; 
+0

Спасибо, я понял, что это не спасет поток, и может иметь утечки памяти, но я просто пытался создать быстрый и короткий пример. Приятно отметить, что хотя никто не пытается просто скопировать то, что я сделал. – runfastman

Смежные вопросы