PHP,云端用 workerman 做 udp 服务器。硬件设备是单片机。现在的情况是,云端服务器可以接收从内网设备发出的数据,获取动态的 IP 和端口。但是不能根据这个获取到的 IP (公网)和端口号发送数据给设备,只能用内网 IP 和端口发送。用小米路由器的端口映射可以解决,不过不灵活。因为端口号是不固定的。希望有一个好的解决方案
|      1unixeno      2019-05-23 14:55:30 +08:00 via Android  1 可以发啊,你需要维护一个心跳包定时发,不然 nat 就老化了 | 
|  |      2TomVista      2019-05-23 15:16:39 +08:00 不应该啊,云端按照 socket 就能发回来,你这个是不是代码出问题了 | 
|  |      3opengps      2019-05-23 15:18:17 +08:00 via Android 能去就能回的 | 
|  |      4a54552239 OP 我是指不定再某个时候主动推送消息的。不是在当前连接,当前连接的话是可以发的。 | 
|  |      6a54552239 OP 设备大概是每 30 秒会向服务器推送数据 | 
|  |      7TomVista      2019-05-23 15:22:10 +08:00 心跳包保活, | 
|      8whatsmyip      2019-05-23 15:22:11 +08:00 需要心跳保活,之前做 app 推送遇到过,超过 10s 链接就被关掉了,但是感知不到。 | 
|  |      10TomVista      2019-05-23 15:26:28 +08:00 客户端,要不然链接死了,服务器就丢了客户端,或者客户端 ip 动态改变了,服务器就找不到了, | 
|  |      11a54552239 OP 现在有做心跳的,间隔 17 秒 | 
|  |      13TomVista      2019-05-23 15:31:40 +08:00 服务器接收心跳包,然后更新客户端 socket,需要主动推送,就把存的 socket 拿出来,进行推送. 是这个套路不. | 
|  |      15TomVista      2019-05-23 15:34:21 +08:00 那怎么会接不到,, | 
|  |      16opengps      2019-05-23 15:35:49 +08:00 via Android 给你参考下,我做的 GPS 定位器,是等待设备过来时候再下发指令,要么就通过短信这种方式下达指令 | 
|  |      17TomVista      2019-05-23 15:36:31 +08:00 "但是不能根据这个获取到的 IP (公网)和端口号发送数据给设备," 存的是 socket 对象 不是 socket 里面的 ip,对吧? | 
|  |      18a54552239 OP @TomVista 是同一个 ip。不过我是希望某个时候,由服务器端根据这个 ip 和端口再主动和设备监理一个连接。。不懂可行不 | 
|  |      20billzhuang      2019-05-23 15:52:10 +08:00 | 
|  |      21TomVista      2019-05-23 15:53:55 +08:00 List<Socket > socketList = new List<Socket >(); Socket client= sc.Accept(); //服务器接收客户端 socket socketList .Add(client); socketList[0].send();//服务器利用客户端 socket 下发信息 | 
|  |      24a54552239 OP | 
|  |      25a54552239 OP 感谢分享 @billzhuang | 
|      26unixeno      2019-05-23 15:59:04 +08:00 via Android | 
|  |      27mirrorman      2019-05-23 17:10:06 +08:00 via iPhone 推测应该是客户端端口在一段时间之后挂了,你可以用其他服务器向客户端同一个端口发东西测试一下,Linux udp 底层的 socket 发到服务器是会把地址传过去的,正常的话服务器是能发回数据的 | 
|      28smdbh      2019-05-23 18:52:09 +08:00 udp 不是面向连接的,不明白 ls 的大佬的思路 tcp 不好么? | 
|  |      29goofool      2019-05-23 19:20:47 +08:00 有几个单片机,如果只有一个可以用路由器开 DMZ | 
|  |      30dabaibai      2019-05-23 19:43:55 +08:00 不行  运营商不允许这样 | 
|  |      34phithon      2019-05-23 22:02:58 +08:00 看看 unpn 协议吧,动态改端口映射 | 
|  |      35phithon      2019-05-23 22:03:31 +08:00 upnp 写错 | 
|  |      36ihciah      2019-05-24 00:11:16 +08:00 via iPad 不想手动做端口映射,不想配 dmz 主机,不想用 tcp,那只有 upnp 了,前提是路由支持这东西。 | 
|  |      37KasuganoSoras      2019-05-24 03:00:04 +08:00 推测是你的心跳包间隔时间太长,客户端那头的端口关闭了,建议把心跳包间隔时间缩短,比如 10s,或者 5s。 可以参考我这个项目,PHP 写的聊天软件,基于 UDP: https://github.com/kasuganosoras/UChat 理论上服务器只要按原路把数据包发回客户端的 IP 和端口是能够正确传递回去的。 | 
|      39nicevar      2019-05-24 07:20:45 +08:00 有个东西叫 stun,楼主去看一下文档就行了 |