我做了一个通讯软件(有点儿像QQ),结果发现在内网中无法工作。因为存在NAT,导致ServerSocket接不到连接,DatagramSocket接不到数据包。在网上查了关于UDP和TCP打洞的资料,却发现需要一个中转服务器。我只有一个在Sourceforge上注册的支持PHP的WEB站点和一个小型的Mysql数据库,怎么解决这个内网问题啊?苦恼ing...
实在不行就放弃了吧
实在不行就放弃了吧
解决方案 »
- 请教一个数据库显示的问题
- public class Dao {static {。。。}},static 是匿名方法吗
- 请问 如何取得789这个数
- Arrays.sort 用的是哪些排序方法
- 金山词霸的API
- 新手求教JAVA的环境变量配置
- 请问如何用java获得图片文件的相关信息(文件大小,图片尺寸,像素等),图片格式为jpg,gif,bmp等
- ——求教
- 纠集一群无聊的人(>=50)用一个月时间一起来翻译jbuilder5的帮助文件,大家有没有兴趣啊~~~~~
- 收藏 不显示删除回复显示所有回复显示星级回复显示得分回复 给大家分享一个好资源《Java经典视频教程及板书下载地址大全》
- 1989年12月29日 怎么转换成 1989.95年 的?????
- java web 菜鸟
lz的软件本身具有服务器功能,解决方法,要么模仿MSN的通信模式,要么,模仿P2P,在安装的时候提醒用户打开防火墙以及更改相应的设定。
(图 7)
与UDP 不同的是,使用UDP协议的每个客户端只需要一个套接字即可完成与服务器S通信,并同时与多个p2p客户端通信的任务,而TCP客户端必须处理多个套接字绑定到同一个本地TCP端口的问题,如图7所示。现在来看更加实际的一种情景,A与B分别位于不同的NAT设备后面,如图5所示,并且假定图中的端口号是 TCP协议的端口号,而不是UDP的端口号。图中向外的连接代表A和B向对方的内网endpoint发起的连接,这些连接或许会失败或者无法连接到对方。如同使用UDP协议进行“打洞”操作遇到的问题一样,TCP的“打洞”操作也会遇到内网的IP与“伪”公网IP重复造成连接失败或者错误连接之类的问题。客户端向彼此公网endpoint发起连接的操作,会使得各自的NAT设备打开新的“洞”允许A与B的TCP数据通过。如果NAT设备支持TCP“打洞” 操作的话,一个在客户端之间的基于TCP协议的流通道就会自动建立起来。如果A向B发送的第一个SYN包发到了B的NAT设备,而B在此前没有向A发送 SYN包,B的NAT设备会丢弃这个包,这会引起A的“连接失败”或“无法连接”问题。而此时,由于A已经向B发送过SYN包,B发往A的SYN包将被看作是由A发往B的包的回应的一部分,所以B发往A的SYN包会顺利地通过A的NAT设备,到达A,从而建立起A与B的p2p连接。4.3 从应用程序的角度来看TCP“打洞”从应用程序的角度来看,在进行TCP“打洞”的时候都发生了什么呢?假定A首先向B发出SYN包,该包发往B的公网 endpoint,并且被B的NAT设备丢弃,但是B发往A的公网endpoint的SYN包则通过A的NAT到达了A,然后,会发生以下的两种结果中的一种,具体是哪一种取决于操作系统对TCP协议的实现:(1)A的TCP实现会发现收到的SYN包就是其发起连接并希望联入的B的SYN包,通俗一点来说就是“说曹操,曹操到”的意思,本来A要去找B,结果B自己找上门来了。A的TCP协议栈因此会把B做为A向B发起连接connect的一部分,并认为连接已经成功。程序A调用的异步connect()函数将成功返回,A的listen()等待从外部联入的函数将没有任何反映。此时,B联入A的操作在A程序的内部被理解为A联入B连接成功,并且A开始使用这个连接与B开始p2p通信。由于收到的SYN包中不包含A需要的ACK数据,因此,A的TCP将用 SYN-ACK包回应B的公网endpoint,并且将使用先前A发向B的SYN包一样的序列号。一旦B的TCP收到由A发来的SYN-ACK包,则把自己的ACK包发给A,然后两端建立起TCP连接。简单的说,第一种,就是即使A发往B的SYN包被B的NAT丢弃了,但是由于B发往A的包到达了A。结果是,A认为自己连接成功了,B也认为自己连接成功了,不管是谁成功了,总之连接是已经建立起来了。(2)另外一种结果是,A的TCP实现没有像(1)中所讲的那么“智能”,它没有发现现在联入的B就是自己希望联入的。就好比在机场接人,明明遇到了自己想要接的人却不认识,误认为是其它的人,安排别人给接走了,后来才知道是自己错过了机会,但是无论如何,人已经接到了任务已经完成了。然后,A通过常规的listen()函数和accept()函数得到与B的连接,而由A发起的向B的公网endpoint的连接会以失败告终。尽管A向B的连接失败,A仍然得到了B发起的向A的连接,等效于A与B之间已经联通,不管中间过程如何,A与B已经连接起来了,结果是A和B的基于TCP协议的p2p连接已经建立起来了。第一种结果适用于基于BSD的操作系统对于TCP的实现,而第二种结果更加普遍一些,多数linux和windows系统都会按照第二种结果来处理。