2012-01-17 53 views
13

Có ai có thể đưa ra ví dụ về lỗ đục lỗ UDP không?Thuật toán đục lỗ UDP

Thực ra, tôi muốn viết một chương trình trò chuyện mà mọi người có thể trò chuyện khi họ biết IP của nhau. Nhưng cả hai máy này sẽ nằm sau một bộ định tuyến tường lửa. Vì vậy, tôi cần phải đấm một lỗ để giao tiếp.

Tôi muốn một chức năng như vậy trên gọi hàm, một lỗ sẽ bị đấm và truyền thông trong tương lai sẽ di chuyển trên một cách dễ dàng - nếu đó không phải là quá nhiều để yêu cầu :)

+1

dupe có thể có của: http://stackoverflow.com/questions/8523330/programming-p2p-application/8524609#8524609 – selbie

+0

Không có chức năng đơn giản mà bạn chỉ có thể gọi đó là ý chí giải quyết tất cả các vấn đề về NAT traversal của bạn. Xem liên kết ở trên để có một cuộc thảo luận dài hơn về NAT traversal và P2P. – selbie

Trả lời

18

ngắn trả lời: nó có thể' t được thực hiện một cách đáng tin cậy.

Câu trả lời dài:

"Hole Punching" đề cập đến kích hoạt quy tắc NAT tự động của bộ định tuyến để cho phép lưu lượng truy cập đến. Khi bạn gửi một gói UDP ra, router (thường) tạo ra một quy tắc tạm thời ánh xạ địa chỉ nguồn và cổng của bạn đến địa chỉ đích và cổng, và ngược lại. Các gói UDP trở về từ địa chỉ đích và cổng (và không có gói nào khác) được chuyển tới địa chỉ nguồn và cổng gốc (và không có cổng nào khác). Quy tắc này sẽ hết thời gian chờ sau một vài phút không hoạt động.

Làm điều này để làm việc khi cả hai điểm cuối phía sau NAT hoặc tường lửa sẽ yêu cầu cả hai điểm cuối gửi gói đến nhau cùng một lúc. Điều này có nghĩa là cả hai bên cần phải biết các địa chỉ IP và số cổng công khai của nhau và cần phải truyền đạt thông tin này cho nhau bằng một số phương tiện khác.

Không có cách nào để chương trình trực tiếp xác định địa chỉ IP công khai của chính nó nếu nó nằm sau NAT (nó sẽ chỉ thấy địa chỉ riêng của nó, chẳng hạn như 192.168.x.x). Nhưng vì bạn giả sử rằng con người liên quan biết địa chỉ IP của nhau, những con người đó có thể chỉ cần gõ vào địa chỉ của người kia.

Nhưng điểm bắt thực sự là không có cách nào để chương trình trực tiếp xác định số cổng mà bộ định tuyến đang sử dụng ở phía công cộng. Chương trình của bạn có thể bị ràng buộc với 12345 trên máy cục bộ, nhưng bộ định tuyến có thể ánh xạ tới hầu hết mọi cổng ở phía công cộng. (Hãy tưởng tượng hai máy tính trên mạng cục bộ của bạn gửi cả hai từ cổng 12345, rõ ràng là router sẽ phải ánh xạ một trong số chúng tới một số khác.) Vì vậy, mặc dù bạn và con người có thể biết số cổng địa phương bạn đang bị ràng buộc, không có cách nào để biết số cổng mà router sẽ hiển thị cho thế giới.

+9

Seth - Bạn phác thảo các vấn đề của NAT traversal rất tốt, nhưng bạn làm cho nó có vẻ như nó là một vấn đề không thể giải quyết. Nhưng trong thực tế, một sự kết hợp của STUN, TURN, ICE, và một dịch vụ tín hiệu đáng tin cậy làm cho kết nối P2P rất đáng tin cậy. Đặt nó theo một cách khác - máy chủ trên các nút trợ giúp internet công khai được kết nối trực tiếp. – selbie

+0

Bạn chính xác là vấn đề phần lớn sẽ biến mất * nếu * bạn có thể tiếp cận một cách đáng tin cậy một chuyển tiếp của bên thứ ba. @ c.adhityaa đã không thực sự nói rằng giao tiếp trực tiếp là một yêu cầu, vì vậy tôi nên hỏi. Ngoài ra, nếu bạn thư giãn yêu cầu độ tin cậy, sau đó có cả hai đồng nghiệp gửi nhau một vài datagrams một lần thứ hai ngoài có thể làm việc phần lớn thời gian.Tôi đang sử dụng để đối phó với tường lửa của công ty, vì vậy tôi có thể quá bi quan về những gì mạng sẽ cho phép. –

7

Thư viện mạng của Lidgren có chức năng này được tích hợp sẵn. Sau khi thêm thư viện vào ứng dụng của bạn, bạn sẽ khởi tạo một NetServer, có hai NetClients kết nối, và gọi NetServer.Introduce().

Liên kết đến Lidgren: https://github.com/lidgren/lidgren-network-gen3