2012-01-12 35 views
10

Tôi cần tạo chương trình sẽ liên lạc với các chương trình khác trên cùng một máy tính thông qua ổ cắm UDP. Nó sẽ đọc các lệnh từ stdin, và một số lệnh này sẽ làm cho nó gửi/nhận các gói tin mà không dừng thực thi. Tôi đã đọc một số thông tin trên mạng, nhưng vì tôi không quen với lập trình socket và cần thực hiện việc này nhanh chóng, tôi có các câu hỏi sau:Nhận cổng ngẫu nhiên cho ổ cắm UDP

  1. Tôi cần có một cổng không sử dụng ngẫu nhiên cho chương trình để lắng nghe và dự trữ nó để các chương trình khác có thể giao tiếp với điều này và cổng cũng không được chương trình khác bảo lưu. Tôi cũng cần phải lưu trữ số cổng trên một biến để sử dụng trong tương lai.
  2. Kể từ khi giao tiếp là trên các quy trình trên cùng một máy, tôi tự hỏi nếu tôi có thể sử dụng PF_LOCAL.

Ngoài ra, một mẫu mã của việc thiết lập ổ cắm đó sẽ được chào đón, cũng như ví dụ về gửi/nhận chuỗi ký tự.

+0

Đối với nền tảng nào? –

+0

Hệ điều hành Linux sử dụng thư viện standar – rabusmar

+1

Tại sao phải liên lạc giữa các quá trình bằng cách sử dụng ổ cắm? Là nó chỉ vì lợi ích của nó?;) – BlackBear

Trả lời

20

Gọi bind() chỉ định cổng 0. Điều đó sẽ cho phép hệ điều hành chọn một cổng chưa sử dụng. Sau đó, bạn có thể sử dụng getsockname() để truy xuất cổng đã chọn.

+0

Đây là một cách hay để làm điều đó nhưng chắc chắn nó sẽ không phải là một cách ngẫu nhiên để làm điều đó. – dbeer

+1

Tôi cho rằng nếu bạn muốn một cổng thực sự ngẫu nhiên, bạn có thể tiếp tục cố gắng liên kết với ((rand()% 65535) +1) cho đến khi liên kết trả về thành công. – selbie

+2

Nó sẽ được ngẫu nhiên trong đó bạn sẽ không biết những gì cổng được chọn cho đến khi ràng buộc là thành công. Ràng buộc vào cổng 0 cho phép hệ điều hành chọn cổng đầu tiên chưa sử dụng đầu tiên. Nếu 'bind()' thành công, bạn được guarateed để có một cổng mà chỉ được sử dụng bởi bạn và không ai khác. Yêu cầu đã nêu của bạn không yêu cầu nó phải là ngẫu nhiên, chỉ là duy nhất, và nó sẽ được. –

0

Nếu nó là một cổng ngẫu nhiên là thực sự quan trọng, bạn nên làm một cái gì đó như:

srand(time(NULL)); 
rand() % NUM_PORTS; // NUM_PORTS isn't a system #define 

Sau đó xác định rằng cổng trong ràng buộc. Nếu nó không thành công, hãy chọn một cái mới (không cần phải tạo lại máy phát ngẫu nhiên. Nếu cổng ngẫu nhiên không quan trọng, hãy xem câu trả lời của Remy Lebeau.

+1

Bạn sẽ phải theo dõi các cổng bạn đã cố gắng để bạn không cố gắng liên kết với chúng một lần nữa vì chúng không thành công lần đầu tiên. –

+0

Đúng, mặc dù khả năng bạn lặp lại các cổng trong chuỗi giả ngẫu nhiên trước khi tìm một cổng mở là khá thấp. – dbeer

1

Trả lời bởi Remy Lebeau là tốt nếu bạn cần một cổng tạm thời Nó không phải là tốt như vậy nếu bạn cần một cổng dành riêng dai dẳng bởi vì phần mềm khác cũng sử dụng cùng một phương pháp để có được một cổng (bao gồm cả TCP TCP ngăn xếp cần một cổng tạm thời mới cho mỗi kết nối)

Vì vậy, điều sau đây có thể xảy ra :

  1. Bạn gọi bind với 0 và getsockname() để có được một cảng;
  2. sau đó tiết kiệm i t vào cấu hình (hoặc vào một số cấu hình) để sử dụng trong tương lai;
  3. phần mềm cần cổng này bắt đầu và liên kết với cổng.

Sau đó, bạn cần ví dụ: khởi động lại phần mềm:

  1. phần mềm dừng và hủy liên kết cổng: bây giờ cổng có thể được trả về bởi bind (0) và getockname() một lần nữa;
  2. ví dụ: TCP stack cần một cổng và liên kết cổng của bạn;
  3. phần mềm không thể khởi động vì cổng đã bị ràng buộc.

Vì vậy, để "sử dụng trong tương lai", bạn cần một cổng không nằm trong dải cổng không lâu (đó là phạm vi kết nối (máy chủ, 0) trả về cổng).

Giải pháp của tôi cho vấn đề này là tiện ích dòng lệnh port-for.

+2

Rất hiếm khi, nếu bao giờ, bạn sẽ cần phải truy xuất một cổng tạm thời lần đầu tiên và lưu nó để tái sử dụng trong các kết nối tiếp theo. Tôi đã viết mã ổ cắm trong hơn 10 năm và không bao giờ cần phải làm điều đó, không phải một lần. Thông thường, bạn sẽ sử dụng cổng tạm thời mọi lúc (và cho máy chủ, cung cấp cách phát hiện cổng đó động) hoặc người dùng chỉ định cổng cố định trong cấu hình của ứng dụng, trong trường hợp đó người dùng đảm bảo cổng luôn sẵn sàng sử dụng. –

+0

Nếu sự hiểu biết của tôi về câu hỏi là chính xác (đặc biệt là phần "1"), nó yêu cầu điều này. Điều này có thể không phải là trường hợp mặc dù. Các trường hợp sử dụng không phải là để làm cho người sử dụng đảm bảo cổng luôn luôn có sẵn nhưng để làm cho một phần mềm đảm bảo cổng có sẵn. –

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