2009-09-02 36 views
110

Tôi đang cố gắng chơi với giao tiếp giữa các quá trình và vì tôi không thể tìm ra cách sử dụng các đường ống có tên trong Windows, tôi nghĩ tôi sẽ sử dụng các ổ cắm mạng. Mọi thứ xảy ra cục bộ. Máy chủ có thể khởi động các nô lệ trong một tiến trình riêng biệt và lắng nghe trên một số cổng. Các nô lệ làm công việc của họ và gửi kết quả cho chủ. Làm cách nào để tìm ra cổng nào có sẵn? Tôi cho rằng tôi không thể nghe trên cổng 80 hoặc 21?Trên máy chủ cục bộ, làm cách nào để chọn số cổng miễn phí?

Tôi đang sử dụng Python, nếu điều đó làm giảm các lựa chọn.

Cảm ơn!

+1

Ngẫu nhiên, nếu bạn chỉ cần chọn một số cổng ngẫu nhiên hay ngẫu nhiên-ish (tốt nhất là cao hơn so với 1024), thì có lẽ nó sẽ có sẵn . Bạn thậm chí có thể sử dụng cổng 80 hoặc 21 hoặc bất cứ điều gì, miễn là không có chương trình khác đang lắng nghe trên đó. Tại bất kỳ thời điểm nào, trên một hệ thống bình thường, chỉ một phần nhỏ các cổng được sử dụng. –

+17

Chọn một cổng ngẫu nhiên không phải là một ý tưởng hay - hãy để hệ điều hành chọn một cho bạn. – Corehpf

+0

Trên POSIX: http://stackoverflow.com/questions/913501/how-to-let-kernel-choose-a-port-number-in-the-range-1024-5000-in-tcp-socket-pr –

Trả lời

170

Không liên kết với một cổng cụ thể hoặc liên kết với cổng 0, ví dụ: sock.bind(('', 0)). Hệ điều hành sau đó sẽ chọn một cổng có sẵn cho bạn. Bạn có thể nhận được cổng được chọn bằng cách sử dụng sock.getsockname()[1] và chuyển nó cho nô lệ để họ có thể kết nối lại.

+2

Xem http://stackoverflow.com/a/2838309/3538289 để biết ví dụ về 'sock.bind (('', 0))' – cevaris

+4

Làm thế nào để bạn chuyển số cho các nô lệ? Âm thanh như một vấn đề về thịt gà và trứng đối với tôi. – Sebastian

+0

Nếu các nô lệ được tạo sau khi liên kết, bạn chỉ có thể chuyển nó thành một tham số khi tạo chúng. Ngoài ra, bạn có thể ghi nó vào một số bộ nhớ chia sẻ hoặc một tập tin mà cả hai có thể truy cập, hoặc một máy chủ trung tâm truy cập thông qua một số số cổng nổi tiếng có thể theo dõi nó. – mark4o

35

Kết nối ổ cắm vào cổng 0. Cổng ngẫu nhiên miễn phí từ 1024 đến 65535 sẽ được chọn. Bạn có thể truy xuất cổng đã chọn với getsockname() ngay sau bind().

2

Bạn có thể nghe bất kỳ cổng nào bạn muốn; nói chung, các ứng dụng người dùng nên nghe các cổng từ 1024 trở lên (thông qua 65535). Điều chính nếu bạn có số lượng người nghe có thể thay đổi là phân bổ phạm vi cho ứng dụng của bạn - giả sử 20000-21000 và LOẠI TRỪ CATCH. Đó là cách bạn sẽ biết nếu một cổng là không sử dụng được (được sử dụng bởi một quá trình khác, nói cách khác) trên máy tính của bạn.

Tuy nhiên, trong trường hợp của bạn, bạn không nên gặp sự cố khi sử dụng một cổng mã hóa duy nhất cho người nghe của mình, miễn là bạn in thông báo lỗi nếu liên kết không thành công. Lưu ý rằng hầu hết các ổ cắm của bạn (đối với nô lệ) không cần phải ràng buộc rõ ràng với các số cổng cụ thể - chỉ các ổ cắm chờ kết nối đến (như chủ của bạn ở đây) sẽ cần phải được thực hiện một trình lắng nghe và ràng buộc đến một cổng. Nếu một cổng không được chỉ định cho một socket trước khi nó được sử dụng, hệ điều hành sẽ gán một cổng có thể sử dụng cho socket. Khi thầy muốn trả lời một nô lệ gửi dữ liệu, địa chỉ của người gửi có thể truy cập được khi người nghe nhận dữ liệu.

Tôi đoán bạn sẽ sử dụng UDP cho điều này?

6

Vì lợi ích của đoạn gì những kẻ đã giải thích ở trên:

import socket 
from contextlib import closing 

def find_free_port(): 
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: 
     s.bind(('', 0)) 
     return s.getsockname()[1] 
+0

nếu trên localhost: có thể 's.bind (('localhost', 0))' là tốt hơn – codeskyblue

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