路由器的端口也会自动复用。在你第一个机器使用完毕某个端口1分钟之后,这个端口就可能给别的机器使用。所以如果你的客户端一旦完成了短连接操作,稍微多等点时间以后,你的所谓“打洞”的流程就不靠谱了。tcp当然可以打洞,不过它首先用一个socket监听,然后用另外一个socket复用此端口,来发送消息,这样第一个socket才能收到对方发来的消息。这才是应该有的流程。其实打洞一般来说都是不可靠的,而且tcp更加容易失败(而且失败了也不会有异常被你检测到)。按照路由器的规则进行可靠地持续通讯,你就使用tcp长连接就行了。原本轻松地双向持续通讯,干嘛弄成“打洞”?

解决方案 »

  1.   


    你的理解好像有问题吧....还是我理解错了?tcp就是长连,但是是你自己关闭的..那没办法了 如果你关闭了 当然收不到server过来的信息了..所以你想要实现随时双通道的交互 就一直连着就好了....为啥要关闭呢?而且 2个电脑一个server一个client  client多开 是不存在端口一样的..只能是i++...我不知道你是如何记录clientList的会发生这样的问题..
      

  2.   


    你的理解好像有问题吧....还是我理解错了?tcp就是长连,但是是你自己关闭的..那没办法了 如果你关闭了 当然收不到server过来的信息了..所以你想要实现随时双通道的交互 就一直连着就好了....为啥要关闭呢?而且 2个电脑一个server一个client  client多开 是不存在端口一样的..只能是i++...我不知道你是如何记录clientList的会发生这样的问题..
    我不保存clientlist ,接收完就关闭该client,只保存端口号和ip地址,需要时,用ip地址和端口号发信息,每1分钟发心跳包来确定用户是否在线,但是,感觉自己思路错了,不保存clientlist是为了节约服务器资源,现在看来,1是无法实现,2根本就没法节约资源,准备改成udp的方式进行实现。
      

  3.   

    确实误入歧途,准备改成udp方式实现,但是,我发现我的路由器,貌似不支持打洞,我家所有机器连接外网服务器,都显示一个i同一个ip和端口号
      

  4.   


    首先 你关闭了client 就算你有ip以及port也没用了,,因为close之后你根本没有保持连接..所以更别谈什么发送数据了.就算你client在关闭之后 1分钟在一次重新连接server但是 这个时候 ip以及port一定跟上一次的不一样..所以你记录这个根本没必要. 所以 个人感觉一直连接 +心跳 就可以了..至于你说的UDP我没做过 所以 我不好有什么言论,,
      

  5.   

    tcp打洞只需要保持心跳就可以了