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