2012-06-07 18 views
6

Tôi vẫn quen với Indy, là hệ thống ổ cắm đa luồng với khả năng rộng lớn. Một trong những điều lớn tôi đã thấy là làm thế nào một ổ cắm máy chủ có thể có một số ràng buộc khác nhau. Ví dụ, bạn có thể có 3 bindings cho 3 cổng trên cùng một địa chỉ IP. Tôi đang sử dụng Indy 10 trên Delphi XE2.Sử dụng nhiều ràng buộc của Indy Server làm ổ cắm riêng biệt?

Tôi đang tái xây dựng một hệ thống cũ của tôi trong đó sử dụng cái cũ lỗi thời TServerSocketTClientSocket thành phần từ ScktComps và tái làm nó với Indy TIdTCPServerTIdTCPClient. Hệ thống cũ thực sự bao gồm 3 cổng máy chủ/máy khách hoàn toàn khác nhau trên mỗi đầu, mỗi socket phục vụ một mục đích riêng biệt, và làm việc cùng nhau - tương tự như cách FTP sử dụng một socket cho dữ liệu nhị phân và socket khác cho các lệnh.

Có thể bắt chước ba ổ cắm máy chủ/máy khách riêng biệt trong cùng một thành phần bằng cách sử dụng các ràng buộc này không? Nó sẽ là tuyệt vời nếu tôi có thể tuyên bố chỉ một ổ cắm máy chủ với 3 cổng bị ràng buộc, và giống nhau trên máy khách, kết nối với 3 cổng khác nhau trên máy chủ. Tất cả những gì tôi muốn làm là loại bỏ sự cần thiết phải tạo ra 3 thành phần máy chủ/máy khách riêng biệt và kết hợp chúng thành một.

Trả lời

12

Có, bạn có thể sử dụng một TIdTCPServer để quản lý nhiều cổng cùng một lúc. Về phía máy khách, bạn vẫn cần 3 thành phần máy khách riêng biệt để kết nối với các cổng khác nhau.

Tạo 3 mục trong bộ sưu tập TIdTCPServer.Bindings, một cho mỗi IP/Cổng cục bộ mà bạn muốn nghe, trong đó thuộc tính TIdSocketHandle.Port sẽ là tương đương với thuộc tính TServerSocket.Port. TServerSocket không hỗ trợ liên kết với một IP cụ thể (mặc dù nó có thể được thực hiện với một số công việc thủ công), nhưng thuộc tính TIdSocketHandle.IP được sử dụng cho mục đích đó, trong đó một chuỗi trống tương đương với INADDR_ANY.

Trong TIdCPServer.OnConnect, TIdCPServer.OnDisconnect, và TIdCPServer.OnExecute sự kiện, bạn có thể sử dụng TIdContext.Binding.IPTIdContext.Binding.Port thuộc tính để phân biệt mà ràng buộc socket gọi được kết nối với.

Việc sử dụng phổ biến này là hỗ trợ các máy khách SSL và không phải SSL trên các cổng khác nhau, chẳng hạn như cho các giao thức như POP3 và SMTP hỗ trợ SSL/TLS ngầm định và rõ ràng trên các cổng khác nhau. TIdHTTPServer thực hiện điều này để hỗ trợ các URL HTTPHTTPS trên một máy chủ (bạn có thể sử dụng TIdHTTPServer.OnQuerySSLPort để tùy chỉnh cổng nào sử dụng SSL/TLS so với không).

Ví dụ:

procedure TForm1.StartButtonCick(Sender: TObject); 
begin 
    IdTCPServer1.Active := False; 
    IdTCPServer1.Bindings.Clear; 

    with IdTCPServer1.Bindings.Add do 
    begin 
    IP := ...; 
    Port := 2000; 
    end; 

    with IdTCPServer1.Bindings.Add do 
    begin 
    IP := ...; 
    Port := 2001; 
    end; 

    with IdTCPServer1.Bindings.Add do 
    begin 
    IP := ...; 
    Port := 2002; 
    end; 

    IdTCPServer1.Active := True; 
end; 

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); 
begin 
    case AContext.Binding.Port of 
    2000: begin 
     // do something... 
    end; 
    2001: begin 
     // do something else... 
    end; 
    2002: begin 
     // do yet something else ... 
    end; 
    end; 
end; 
+0

Awesome, chỉ tự hỏi là mỗi cổng sử dụng thread riêng của mình hoặc có lẽ hầu hết tất cả 3 trong thread bối cảnh tương tự? –

+1

Mỗi mục trong bộ sưu tập 'Bindings' chạy trong chuỗi riêng của nó chấp nhận các kết nối gửi đến trên cổng tương ứng của nó. Mỗi kết nối máy khách được chấp nhận sau đó cũng chạy trong chuỗi riêng của nó. Vì vậy, nếu bạn có 3 mục 'Bindings' và 3 máy khách kết nối, đó là 6 luồng đang chạy. –

+0

Hoàn hảo, đó là chính xác những gì tôi muốn. –

Các vấn đề liên quan