2009-06-04 25 views
8

Giả sử tôi muốn chạy dịch vụ TCP/IP trên một số cổng cho IPC. Vì tôi đang chuyển số cổng cho các quy trình tôi muốn giao tiếp với dù sao, số cổng không quan trọng. Cách tốt nhất để có được một số cổng ngẫu nhiên, cao (thường là> 49152) mà vẫn có sẵn từ hệ thống? Có cái gì trong POSIX tôi có thể sử dụng?Nhận số cổng cao, ngẫu nhiên vẫn có sẵn

Tôi biết máy chủ FTP cần điều này thường xuyên.

Trả lời

-9

Cách duy nhất là lặp qua phạm vi cổng mong muốn, cố gắng liên kết một ổ cắm với từng cổng một cho đến khi bạn tìm thấy cổng đó thành công.

+2

Không, nó không phải là cách duy nhất. Ràng buộc vào cổng số không là một cách khác, và một cách tốt hơn vô cùng. QED – EJP

13

Nếu bạn không chỉ định số cổng, HĐH sẽ tự động chọn số ephemeral port cho bạn.

Từ Choosing the Port Number:

phần mềm máy chủ mới nên cố gắng để tránh phụ thuộc vào một số cổng cụ thể, đặc biệt là nếu nó là phần mềm sử dụng cấp mà không ineluctably gắn với một cổng nổi tiếng. May mắn thay, điều này có thể dễ dàng thực hiện bằng cách yêu cầu cổng 0, hướng dẫn hệ thống chọn một số cổng tạm thời.

+1

Có, cổng 0 cho phép hệ điều hành chọn một cổng khả dụng ngẫu nhiên cho bạn. Mặt khác, việc sử dụng cổng 0 không cho phép bạn chỉ định một loạt các cổng cho hệ điều hành để chọn. Ví dụ: nếu bạn đang sử dụng tường lửa/bộ định tuyến thì có thể sử dụng các dải cổng trở nên quan trọng hơn. –

+1

@RemyLebeau Bất kỳ tường lửa nào được cấu hình để chỉ cho phép một loạt các cổng đi được định cấu hình sai và phải được sửa. Vì API Socket không hỗ trợ điều đó, nó đặt gánh nặng lên các ứng dụng mà chúng không thể đáp ứng, cũng như hoàn toàn vô nghĩa từ quan điểm bảo mật. – EJP

+0

@EJP: Bạn đang giả định ràng buộc cổng chỉ được thực hiện cho các kết nối * outbound *. FTP là một ví dụ điển hình về việc khi nào một máy khách có thể cần phải kết nối các ổ cắm cho các kết nối * inbound *, để truyền các chế độ hoạt động. –

5

Cổng tạm thời có thể thực hiện điều đó. Hệ điều hành của bạn sẽ gán cho bạn một cổng từ hồ bơi cổng miễn phí.

Có một số mã C, BSD cấp phép, làm điều này here

Trong Python, bạn có thể chỉ định một socket.AF_INET cặp ('', 0) địa chỉ cho cùng một mục đích, ví dụ sock.bind(('', 0))

+0

Chúng ta nên gọi hàm Python nào với các đối số ('127.0.0.1', 0)? –

+1

@ Nordlöw - [bind] (http://docs.python.org/2/library/socket.html#socket.socket.bind) –

+0

Đây là câu trả lời python: http://bit.ly/1o9GlOY – yucer

0

Bạn có thể sử dụng C thư viện nhỏ của tôi: https://github.com/yegor256/random-tcp-port

Biên dịch nó và chạy trên máy tính của bạn. Nó sẽ xuất ra một cổng TCP ngẫu nhiên.

+3

sau đó sẽ ngay lập tức trở lại có sẵn cho người khác ngay khi nó thoát. Điều này hoàn toàn vô nghĩa. – EJP

+0

Nhưng đây là chính xác những gì bạn đề xuất một vài câu trả lời dưới đây, và tất cả các aswers khác cũng đề nghị :) Thư viện của tôi chỉ làm cho nó dễ dàng hơn để có được – yegor256

+1

Bạn đang làm điều đó sai. Gán các cổng ngẫu nhiên đã là một phần của hệ thống - tất cả những gì bạn phải làm là yêu cầu số cổng 0 và bạn sẽ nhận được một cổng ngẫu nhiên mà bạn có thể nhận được với 'getockname'. Tuy nhiên, nếu bạn đóng ổ cắm, bạn không bảo đảm rằng số cổng cũ sẽ được duy trì. – PSkocik

1

Nếu bạn cố gắng liên kết với cổng số 0, hệ thống sẽ kết nối ổ cắm của bạn với cổng ngẫu nhiên "ephemereal". Sau đó, bạn có thể nhận được cổng với getsockname (trong C).

Trong ruby:

s = TCPServer.new('localhost', 0) #You can also use nil instead of 0 
s.addr[1] #The obtained port number 
+0

Ephemereal? Bao lâu nó sẽ kéo dài? Tôi hy vọng cho đến khi máy chủ dừng lại. – yucer

+0

@yucer Nó có nghĩa là nó không phải là một số cố định liên kết với một dịch vụ cố định cụ thể như 80 cho HTTP. Nó vẫn sẽ kéo dài cho đến khi bạn đóng hoặc cho đến khi hệ điều hành đóng nó cho bạn khi quá trình của bạn chấm dứt. – PSkocik

+0

Tôi nghĩ rằng hàm tạo đã thay đổi. Xem: http://bit.ly/1o9DDJb Ngoài ra thuộc tính addr bây giờ là server_address – yucer