2013-04-10 29 views
5

Tôi đang cố tạo ứng dụng trò chuyện java cho lớp mạng của mình. Hiện tại, tôi đang cố gắng kết nối với ai đó đằng sau một bộ định tuyến khác. Cách tôi có dự án của tôi ngay bây giờ là tôi có một chương trình máy khách và một chương trình máy chủ. Chương trình khách hàng đầu tiên đăng nhập vào chương trình máy chủ ghi nhật ký IP và cổng của họ trong cơ sở dữ liệu và sau đó máy chủ cung cấp cho họ danh sách bạn bè của họ bằng IP và cổng của họ. Sau đó, máy khách đóng kết nối đến máy chủ và cố gắng kết nối với một máy khách khác bằng cách sử dụng thông tin mà máy chủ gửi trả về. Cho đến nay chương trình của tôi chỉ hoạt động kết nối với máy chủ và nhận IP và cổng của bạn bè nhưng khi tôi sử dụng các giá trị đó để kết nối với ứng dụng khách khác mà tôi không thể kết nối.Java nat traversal cho ứng dụng chat

socket = new Socket(); 
socket.setReuseAddress(true); 
socket.setKeepAlive(true); 
socket.setSoLinger(true, 10); 
socket.bind(new InetSocketAddress(Port)); 
socket.connect(new InetSocketAddress(host, SERVER_PORT)); 
reusePort = socket.getLocalPort(); 

Trên đây là đoạn mã java được sử dụng để kết nối với máy chủ sau đó là những gì tôi làm ở phía máy khách.

ss = new ServerSocket(reusePort); 

Vì vậy bây giờ về mặt kỹ thuật tôi đang lắng nghe trên cổng cùng tôi đã sử dụng để kết nối đến máy chủ mà được đăng nhập và là retrievable cho khách hàng khác và có trong bảng NAT với ip và cổng của tôi. Tôi không chắc chắn những gì tôi đang thiếu hoặc nếu có một số giao thức hoặc một cái gì đó mà tôi phải làm. Tôi đã nhìn vào lỗ hổng TCP và UDP nhưng tôi không chắc chắn làm thế nào mà thực sự được thực hiện hoặc làm thế nào để thực hiện nó.

Mọi đề xuất sẽ được đánh giá cao.

+1

Tôi thấy bạn đã chấp nhận câu trả lời, nhưng có vẻ như bạn muốn xem xét "Lỗ Puching". Câu trả lời được chấp nhận không thực sự trả lời câu hỏi của bạn, nhưng thay vào đó yêu cầu bạn cho phép tất cả thông tin của ứng dụng của bạn đi qua Máy chủ của bạn và dường như bạn muốn kết nối trực tiếp với khách hàng của mình. –

+0

hey bạn đã tìm thấy câu trả lời của bạn. làm ơn giúp tôi. tôi đang gặp vấn đề tương tự. –

+0

Bản sao có thể có của [STUN, TURN, thư viện ICE cho Java] (http://stackoverflow.com/questions/2039147/stun-turn-ice-library-for-java) –

Trả lời

1

Nếu bạn muốn gửi tin nhắn, bạn cần phải thiết lập chuyển tiếp cổng trên bất kỳ thiết bị nào hoạt động như máy chủ (bất kỳ thiết bị nào tạo máy chủ socket). Chuyển tiếp cổng được thực hiện trên Router. Lý do bạn không thể kết nối với máy khách khác là vì chúng ẩn đằng sau tường lửa router của chúng. Địa chỉ của họ với phần còn lại của thế giới thực sự là địa chỉ của bộ định tuyến, không phải của máy tính vật lý của họ. Trên mạng nội bộ của họ, họ có một địa chỉ khác rồi những gì phần còn lại của thế giới nhìn thấy, và router tìm ra thông điệp nào từ thế giới bên ngoài cần được gửi tới khách hàng dựa trên bảng dịch địa chỉ.

Với kiến ​​trúc của bạn, điều này có nghĩa là tất cả khách hàng cần phải có bộ định tuyến chuyển tiếp cổng, điều này tất nhiên không khả thi (hãy tưởng tượng gtalk hoặc mục đích yêu cầu người dùng thực hiện chuyển tiếp cổng).

Kiến trúc phổ biến hơn là để Máy chủ thực hiện công việc truyền phát lại tin nhắn cho các khách hàng được kết nối và duy trì các bảng để tra cứu mà nói chuyện với ai. Bằng cách này có một máy chủ duy nhất sẽ cần một ip tĩnh (hoặc được chuyển tiếp cổng), và tất cả người dùng chỉ đơn giản là các máy khách kết nối với socket máy chủ và đọc các tin nhắn từ nó.

Đối với mã thực tế mô tả kiến ​​trúc thứ hai, vui lòng xem http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html. Sau đó, máy đang chạy mã máy chủ hoặc cần một ip tĩnh hoặc nếu nó là đằng sau một router cần lưu lượng từ cổng nó đang lắng nghe để được chuyển tiếp.

Vì vậy, trên mã máy chủ, bạn sẽ liên kết với ip được chỉ định từ bộ định tuyến của bạn (ví dụ như 192.168.1.2 tại một số cổng nói 5000). Sau đó vào trang cấu hình router của bạn (có thể là 192.168.1.1 xem http://www.wikihow.com/Port-Forward/Open-Ports-on-a-Linksys-Router), và chuyển tiếp cổng 5000 đến địa chỉ 192.168.1.2.

+0

Cảm ơn tigger! Tôi làm như bây giờ có cổng máy chủ của tôi chuyển tiếp đến X phía sau router của tôi, tôi đang nghĩ đến việc chuyển sang kiến ​​trúc thứ hai mà bạn đề xuất (nhờ liên kết, có thể khó sàng lọc mặc dù google đôi khi lol) và có mỗi khách hàng duy trì kết nối duy nhất với máy chủ và máy chủ sau đó chuyển tiếp bất kỳ thứ gì đến chúng thông qua nó. Tuy nhiên, tôi sẽ lộn xộn hơn một chút với những gì tôi có sau đó chuyển đổi khi tôi hết thời gian. Cảm ơn đã giúp đỡ. – DarkLazar

+0

ok vì vậy bạn đang nói rằng khi chúng tôi không thể đi đến mỗi và mọi bộ định tuyến, chúng tôi đi qua, và làm cổng chuyển tiếp. vì vậy chúng ta nên sử dụng một máy chủ và để cho nó thực hiện công việc. (hãy sửa tôi nếu tôi sai). chính xác thì máy chủ sẽ làm gì? xin vui lòng tha thứ cho tôi nếu câu hỏi của tôi là lẻ, tôi mới vào mạng. –

+0

@DarkLazar Đó có phải là cách khách hàng torrent hoạt động không? Hay họ sử dụng một số cách khác để đạt được điều này? Có cách nào dễ hơn để thực hiện việc này không? (như một thư viện) – goodbytes

1

Giao thức thiết lập kết nối tương tác (ICE) kết hợp các giao thức NAT khác nhau như giao thức STUN và TURN để cung cấp cơ chế mạnh mẽ cho phép giao thức dựa trên Offer/Answer như SIP và XMPP đi qua NAT.

Dự án này cung cấp triển khai Java giao thức ICE có thể sử dụng được bởi cả ứng dụng SIP và XMPP.Dự án cũng cung cấp các tính năng như chia sẻ ổ cắm và hỗ trợ cho Pseudo TCP.

ice4j được duy trì bởi cộng đồng Jitsi.

ice4j

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