Có bao nhiêu quá trình có thể nghe trên một cổng cụ thể?


7

Có bao nhiêu quá trình có thể lắng nghe trên một cổng cụ thể như 80? và làm thế nào các tiến trình con của một số ứng dụng có thể sử dụng cùng một cổng để lắng nghe? Có sự khác biệt nào giữa việc nghe trên một cổng hoặc thiết lập kết nối nghe không?

Câu trả lời:


8

Q: Có bao nhiêu quá trình có thể lắng nghe trên một cổng cụ thể?

A: nhiều như bạn có thể sinh sản.

Tuy nhiên, đối với SOCK_STREAMổ cắm ít nhất và trừ khi bạn sử dụng SO_REUSEPORTtùy chọn (mới trong Linux 3.9), một quy trình không thể liên kết ổ cắm với điểm cuối cục bộ (địa chỉ + cổng cho TCP, tên tệp cho Unix ...) nếu có một ổ cắm khác bị ràng buộc cái đó (hoặc một cái nghe trên cổng đó với địa chỉ ký tự đại diện).

Vì vậy, trừ khi bạn sử dụng SO_REUSEPORT, cách duy nhất để có các quy trình khác nhau lắng nghe trên cùng một cổng là có các mô tả tệp tương ứng của chúng trỏ đến cùng một mô tả tệp mở (vào cùng một ổ cắm).

Điều đó xảy ra tự động khi bạn fork()một quá trình. Nếu fd 3 trỏ đến ổ cắm TCP đang nghe trên địa chỉ ký tự đại diện và cổng 12345, cả hai quá trình sau ngã ba sẽ lắng nghe trên cổng đó trên fd đó ( zshcú pháp bên dưới):

$ zmodload zsh/net/tcp
$ ztcp -ld 3 12345
$ sleep 10 &
$ lsof -ni tcp:12345
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
zsh     26277 stephane    3u  IPv4 506354      0t0  TCP *:12345 (LISTEN)
sleep   26988 stephane    3u  IPv4 506354      0t0  TCP *:12345 (LISTEN)

Đối với các quy trình không liên quan, cách duy nhất (mà tôi biết) cho một quy trình để có quyền truy cập vào ổ cắm nghe đó là sử dụng SCM_RIGHTcơ chế để truyền fds (thực sự giống như mô tả tệp mở ) giữa các quy trình sử dụng ổ cắm miền unix.

Bạn sẽ nhận thấy rằng một đối số listen()tồn đọng .

Ngay khi có một ổ cắm lắng nghe điểm cuối đã cho, kernel sẽ bắt đầu chấp nhận các kết nối đến điểm cuối đó ( backlog là một gợi ý cho kernel về số lượng nó có thể chấp nhận mà acceptứng dụng không thể chỉnh sửa được ).

Sau đó, quá trình đầu tiên thực hiện accept()trên bất kỳ fds nào trỏ đến ổ cắm nghe (hoặc bất kỳ ổ cắm nghe nào SO_REUSEPORT) sẽ nhận được kết nối đến. accept()tạo một ổ cắm mới và trả về một fd mới cho điều đó socket. Đổi lại, fd đó có thể được nhân đôi (một fd mới trỏ đến cùng một ổ cắm) và các tiến trình con sẽ kế thừa ổ cắm được kết nối đó giống như cách chúng nghe.


3

Câu trả lời này thảo luận về TCP trên IPv4.

Chỉ có một quá trình có thể lắng nghe các kết nối mới. Bạn sẽ gặp lỗi "địa chỉ đã sử dụng" nếu có nhiều hơn một quy trình cố gắng yêu cầu cùng một cổng.

Điều này hoàn toàn khác với số lượng quy trình đang tích cực sử dụng cổng đó.

Có một cái nhìn vào đầu ra sau đây:

remote          local        state
*:*           - 4.3.2.1:5000 LISTENING
1.2.3.4:12345 - 4.3.2.1:5000 CONNECTED
4.5.6.7:83247 - 4.3.2.1:5000 CONNECTED

Những gì cần phải là duy nhất, là 4-tuple (remote-ip, remote-port, local-ip, local-port). Vì (remote-ip, remote-port)ở trạng thái LISTENING là một *:*, chỉ có một quá trình có thể lắng nghe.

Ứng dụng nghe sẽ bắt đầu một luồng / tác vụ / tiến trình mới trên mỗi kết nối đến.


1
Bạn chỉ có thể liên kết với địa chỉ được chỉ định (chứ không phải *) và nhớ rằng IPv4 và IPv6 là các ngăn xếp riêng biệt.
pawel7318

Bạn có thể có một số quy trình nghe trên cùng một giao thức: address: port miễn là trên các mô tả tệp chia sẻ cùng một mô tả tệp đang mở (như trẻ em thừa hưởng fds hoặc fds được truyền bằng SCM_RIGHTS).
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.