2013-10-09 106 views
0

我在動態創建某些INDY通信時遇到問題。我之前沒有使用過Indy,也無法讓服務器正確設置。我得到了錯誤10061.我在防火牆上添加了一條規則以允許此應用程序和端口。它適用於如果我使用TServerSocket和TClientSocket但我需要使用Indy。Indy動態創建服務器客戶端連接錯誤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; 

而且,啓動它,你只需要像這樣設置Active爲:

fIdTCPServer1.Active := True; 
+0

謝謝,這是完美的。 – runfastman

0

你的代碼有幾個問題。

  1. 您正在濫用TIdTCPServer.Bindings,並且您沒有正確激活服務器。

  2. 您呼叫的OnExecute事件ShowMessage(),但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