简体   繁体   English

两个Android设备之间的TCP连接(即使使用NAT)

[英]TCP connection between two android devices (even with NAT)

I am doing an android app allowing users to play online. 我正在做一个允许用户在线玩的android应用。

Currently, I use a TCP server: when two persons are connected, the server takes care of forwarding the packets between the two clients. 当前,我使用TCP服务器:当两个人连接时,该服务器负责在两个客户端之间转发数据包。

I would like to replace my server by a java servlet with google app engine. 我想用带有Google App Engine的Java Servlet替换我的服务器。 This new server will just be used to connect the two players. 此新服务器将仅用于连接两个播放器。

It would work in that way: Player A opens a server socket and then post to the server the connection details. 它将以这种方式工作:播放器A打开服务器套接字,然后将连接详细信息发布到服务器。 When a player B wants to play against A, he asks to the server the port number of A and he connects directly to A. 当玩家B想要与A对抗时,他向服务器询问A的端口号,并直接连接到A。

The problem is that I am not sure that it will work if player A is behind a NAT. 问题是,如果播放器A位于NAT之后,我不确定它是否会起作用。 When player A opens a server socket, that opens one port of its 192.168.xy address, but does it ask to the box a port forwarding? 当播放器A打开服务器套接字时,该服务器套接字打开了其192.168.xy地址的一个端口,但是是否向包装盒询问端口转发? I assume it doesn't... 我认为那不是...

So two questions: Is it possible to make a direct connection TCP between two devices even when there is a NAT or a firewall (I don't know how firewalls work on Android...) If it isn't possible, what is the best solution: Is it possible to make a TCP server to ensure the exchange of the messages with app engine? 所以有两个问题:即使有NAT或防火墙,也可以在两个设备之间建立直接连接TCP(我不知道防火墙在Android上是如何工作的...)如果不可能,那怎么办?最佳解决方案:是否可以制造一个TCP服务器以确保与App Engine交换消息?

Thank you by advance. 预先谢谢你。

game 游戏

First, the device itself is probably not going to be the main problem. 首先,设备本身可能不会成为主要问题。 If they are at home and using WiFi, you will probably have to deal with a cable modem/DSL modem, which typically includes a firewall. 如果他们在家中并使用WiFi,则可能必须处理电缆调制解调器/ DSL调制解调器,该调制解调器通常包括防火墙。 Also if they are at work (or a hotel, conference center, etc.), there may be a corporate firewall to deal with. 另外,如果他们在工作(或酒店,会议中心等),则可能需要处理公司防火墙。

I believe most home cable/DSL modems support uPnP (Universal Plug and Play), which includes the Internet Gateway Device Protocol (IGD) designed to let devices determine the external IP address and set up port mappings. 我相信大多数家用电缆/ DSL调制解调器都支持uPnP(通用即插即用),其中包括Internet网关设备协议(IGD),旨在让设备确定外部IP地址并设置端口映射。 In general you can look up NAT traversal for ways to handle connections through a home modem/firewall. 通常,您可以查找NAT遍历,以找到通过家庭调制解调器/防火墙处理连接的方法。 I will note that corporate firewalls are a different matter and many of these techniques won't work. 我将注意到,企业防火墙是另一回事,其中许多技术将无法使用。

So probably I would recommend you be ready for at least the following four scenarios 所以大概我建议您至少准备好以下四种情况

  1. Direct connection with nothing creating problems. 没有任何问题的直接连接。 You can test this by having the server do a test connection when the player first contacts the server. 您可以通过在播放器首次与服务器联系时让服务器建立测试连接来进行测试。 If this works, things are simple. 如果这可行,那么事情就简单了。
  2. Home NAT device that understands uPnP. 了解uPnP的家用NAT设备。 If you have a 10.xxx, 172.16.xx-172.31.xx, or 192.168.xx number (typical home WiFi), then you can try to set up the NAT traversal and if that works you can send the appropriate information to your server. 如果您有10.xxx,172.16.xx-172.31.xx或192.168.xx号(典型的家庭WiFi),则可以尝试设置NAT遍历,如果可以,则可以将适当的信息发送到服务器。 It probably would be worthwhile for the server to do a test connection just to be sure that things work. 为了确保一切正常,服务器进行测试连接可能是值得的。
  3. If you have a firewall that you can't get around, then make a note on the server regarding player A, and when B tries to join A's game, look and see if B will accept connections, and if so then arrange for A to connect to B instead. 如果您有无法绕过的防火墙,请在服务器上记录有关玩家A的信息,然后当B尝试加入A的游戏时,查看B是否会接受连接,如果是,则安排A参加连接到B。
  4. If none of the above work, then have A and B both connect to the server and have the server relay messages between A and B. 如果以上方法均无效,则让A和B都连接到服务器,并使服务器在A和B之间中继消息。

If you don't want to program all those possibilities, then option 4 is the one that is most likely to work, even if it does mean extra traffic going to/from your server. 如果您不希望对所有这些可能性进行编程,那么选项4是最有可能起作用的选项,即使它确实意味着去往/来自服务器的额外流量。 But note that for corporate networks, they may simply have a rule blocking unknown connections, and there may not be much you can do. 但是请注意,对于公司网络,它们可能只是阻止未知连接的规则,因此您可能无能为力。

Edit: I was able to get a simple TCP server working on Android without anything special regarding Android itself, so removed a comment saying I didn't know about that. 编辑:我能够在Android上获得一个简单的TCP服务器,而没有任何关于Android本身的特殊要求,因此删除了一条评论,说我对此一无所知。

Creating direct TCP connection between users under different NAT is mostly possible. 通常可以在不同NAT下的用户之间创建直接TCP连接。 There are 4 types of NAT. NAT有4种类型。 FC, ARC, PRC, Symmetric. FC,ARC,PRC,对称。 If one of player A or B has symmetric NAT then it is impossible to create TCP P2P connection. 如果播放器A或B中的一个具有对称NAT,则无法创建TCP P2P连接。 In this case you will have to use a server in the middle for exchanging data between two players. 在这种情况下,您将必须使用中间的服务器在两个播放器之间交换数据。

For other types of NAT combinations it is very much possible but not guaranteed. 对于其他类型的NAT组合,这很有可能,但不能保证。 The technique that is used to create TCP P2P connection is called TCP hole punching. 用于创建TCP P2P连接的技术称为TCP打孔。 Read this answer to know in details about this technique. 阅读此答案以了解有关此技术的详细信息。

Also creating TCP P2P connection is not related to any platform. 另外,创建TCP P2P连接与任何平台都不相关。

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

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