简体   繁体   English

Java套接字端口转发

[英]Java Socket port forwarding

I made a networked game in Java using Sockets. 我使用Sockets用Java制作了一个网络游戏。 It works great, except... only through my LAN. 效果很好,除非...仅通过我的局域网。 :/ What I want to be able to do is set it up so that I can start the server running on my home computer and send the client code, in an executable jar, to someone else, and have them be able to launch it and connect through the internet. :/我想要做的就是设置它,以便我可以启动在家用计算机上运行的服务器,并将客户端代码在可执行jar中发送给其他人,并让他们能够启动它并通过互联网连接。 But like... I have no idea how to set up my modem & router for that. 但是就像...我不知道如何为此设置调制解调器和路由器。 :( I have a wireless Clear modem, for which the configuration page looks like this: :(我有一个无线Clear调制解调器,其配置页面如下所示:

http://imageshack.us/photo/my-images/254/modem.jpg http://imageshack.us/photo/my-images/254/mo​​dem.jpg

And a Netgear router, whose page looks like this: 还有一个Netgear路由器,其页面如下所示:

http://imageshack.us/photo/my-images/443/routerq.jpg http://imageshack.us/photo/my-images/443/routerq.jpg

Right now, in the client and server runner classes, I pass my PC's private IP address along with my chosen port number to the ServerSocket and Socket objects. 现在,在客户机和服务器运行程序类中,我将PC的专用IP地址以及选择的端口号传递给ServerSocket和Socket对象。 I hear that Sockets are able to be either UDP or TCP, depending on how you set them up, or something...? 我听说套接字可以是UDP或TCP,这取决于您如何设置它们,或其他...。 I don't do anything like that though, I just instantiate them and pass them the 2 values, and off they go... 我什么也不做,我只是实例化它们并将它们传递给两个值,然后它们就消失了……

In the code for the server: 在服务器代码中:

ServerSocket sock = new ServerSocket();
sock.bind(new InetSocketAddress(IP, 9001));

Code for the client: 客户端代码:

Socket sock = new Socket(IP, 9001);

So also, I would need to know how to change the code accordingly with the changes to my router/modem settings. 因此,我还需要知道如何通过更改路由器/调制解调器设置来相应地更改代码。

"IP" is a String representing my computer's private IP, 192.168.1.10, and the program only works if that is the string I pass to the Socket & ServerSocket. “ IP”是代表我的计算机的专用IP 192.168.1.10的字符串,并且仅当该字符串是我传递给Socket&ServerSocket的字符串时,该程序才有效。 Like I said, I have a modem which is connected to a router which is connected to my computer. 就像我说的,我有一个调制解调器,它连接到与计算机相连的路由器上。 So, can someone please explain to me (in detail, because I'm a noob) what exactly I would have to do to configure both of them, AND the changes I would have to make to my code? 因此,有人可以向我解释一下(因为我是一个菜鸟)(详细地讲,因为我是菜鸟),要配置它们和配置代码所做的更改到底需要做什么?

You'll have to manually port forward, or look at a solution like UPnP or NAT-PMP for automatic port forwarding. 您将必须手动进行端口转发,或者使用诸如UPnP或NAT-PMP之类的解决方案来实现自动端口转发。 Unfortunately, NAT is a pain in the ass to configure and most routers don't properly support it. 不幸的是,NAT在配置方面很麻烦,并且大多数路由器不正确地支持它。 It's also not a simple task, as you have to support a whole range of different implementations and mechanisms. 这也不是一件容易的事,因为您必须支持各种不同的实现和机制。

It shouldn't be too difficult to set up your router to forward one port to your machine, though. 不过,设置路由器将一个端口转发到您的机器应该并不难。 See http://portforward.com/ for an awesome list of how to do it on pretty much any router. 有关如何在几乎所有路由器上执行此操作的出色列表,请参见http://portforward.com/

It sounds like you're asking a number of questions here... I'm no network/socket programming specialist, but here's some ideas. 听起来您在这里问了很多问题...我不是网络/套接字编程专家,但是这里有一些想法。

For distribution, you may wish to look into Java Web Start . 为了进行分发,您可能希望研究Java Web Start It'll make it easy for your clients to obtain the app as well as automating updates. 这将使您的客户轻松获取应用程序以及自动执行更新。

If you're using the Socket constructor like that, the actual implementation will be a system default. 如果使用这样的Socket构造函数,则实际的实现将是系统默认值。 You could override this by calling this method with a suitable SocketImplFactory implementation. 您可以通过使用合适的SocketImplFactory实现调用此方法来覆盖此方法

As for the IP address and port... Using a hard-coded value for the port should be okay. 至于IP地址和端口,则可以为端口使用硬编码值。 You'll need to decide on a port or at least some default anyway for clients to connect to. 无论如何,您都需要决定一个端口或至少一些默认端口,以便客户端连接。 Even so, it might be useful to have the value read from some external configuration file. 即使这样,从某些外部配置文件中读取值可能还是有用的。 This'll make it easier should you ever decide to distribute the server app to let other people run servers. 如果您决定分发服务器应用程序以允许其他人运行服务器,这将使工作更加轻松。 They might want to use a different port. 他们可能想要使用其他端口。

Having the server's IP address (yours) hard-coded in code is definitely a no-no, though. 但是,用代码对服务器的IP地址(您自己)进行硬编码绝对是不行的。 Clients should connect using either an IP address or host name that they need to provide or set in some configuration file. 客户端应使用其需要提供或在某些配置文件中设置的IP地址或主机名进行连接。 A host name would be required if you don't have a static IP address. 如果您没有静态IP地址,则需要一个主机名。

Unless this is something for you and some friends to enjoy, where you can always just initiate a game by providing IP and port in a chat session or something, you'd be better off finding some external hosting solution at a company that takes care of the DNS resolution and network setup for you. 除非这是您和某些朋友喜欢的东西,否则您始终可以通过在聊天会话中提供IP和端口来启动游戏或其他方式,那么最好在一家负责托管的公司找到一些外部托管解决方案DNS解析和网络设置。 These days you'll find stuff like that pretty cheap if you don't have requirements like a Java EE server or database. 如今,如果您没有像Java EE服务器或数据库这样的需求,您会发现类似的东西非常便宜。

EDIT: thought of something else. 编辑:想到了别的东西。 TCP might be okay for your use-case, but if this is a game that requires minimal lag and quick input synchronization (like a shooter or fighting game) then it's not the best choice. TCP可能适合您的用例,但是如果这是一款需要最小的延迟和快速输入同步的游戏(例如射击游戏或格斗游戏),那么它不是最佳选择。 In that case UDP would be better. 在这种情况下,UDP会更好。 It would induce the requirement of adding some sort of detection for desync or a mechanism that makes up for any dropped packets. 这将导致需要添加某种类型的检测以进行不同步或弥补任何丢弃的数据包的机制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM