我目前正在开发一个需要在服务器Amazon Frankfurt之间进行UDP通信的项目和几个主机(Arduino)。我需要能够通过UDP将JSON数据从服务器发送到主机,并且需要实时工作(时间是一个真正的约束)。此外,主机定期与服务器通话以通知服务器其状态。
我面临的问题是虽然我可以ping服务器,但是当我使用端口创建UDP套接字时,我收到此错误(对于任何端口):
errno99:无法分配请求的地址
我也相信,由于主机位于不同的国家,我只能获得路由器的IP。主机将被提供给用户,因此不可能手动改变用户的路由器。我需要使用可以通过代码处理这些内容的东西。
我一直在寻找打孔等技术。我不能在这里决定什么更符合我的情况。很抱歉我缺乏网络信息,任何帮助或指导,因为"阅读或搜索这些技巧"非常感谢。
此代码在服务器上运行:
import socket
import time
#Host's public IP
UDP_IP_ADDRESS = "178.243.98.86"
UDP_PORT_NO = 13000
Destination = (UDP_IP_ADDRESS,UDP_PORT_NO)
Message = "Hello, Server"
senderSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
senderSock.sendto(Message, Destination)
time.sleep(1);
此代码在我的机器上运行:
import socket
#Server's public IP
UDP_IP_ADDRESS = "172.31.46.111"
UDP_PORT_NO = 13000
recieverSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
recieverSock.bind((UDP_IP_ADDRESS, UDP_PORT_NO))
while True:
data, addr = recieverSock.recvfrom(1024)
print "Message: ", data
答案 0 :(得分:0)
# Host's public IP
UDP_IP_ADDRESS = "178.243.98.86"
您不能依赖178.243.98.86
。你的arduinos落后于一个或几个NAT。使用NAT,当数据包离开网络时,您的数据包源和/或目标地址(以及最可能的端口)将被重写。发生此转换时,负责NAT的设备会记住此转换,但仅限于有限的时间段。这段时间通常默认为24小时。
为了克服这个问题,可以由客户端启动与服务器的对话。在协议中引入一种类似hey it's me, client #34
的新消息类型。服务器应该将接收到的消息的源IP和端口与客户端#34关联一段时间,如小时。
在这种情况下,服务器将套接字绑定到地址和端口以及客户端。请注意,通过UDP发送的hey it's me, client #34
未加密,极易受到记录和重放攻击。我认为紧急系统应该加密。
# Server's public IP
UDP_IP_ADDRESS = "172.31.46.111"
172.31.46.111
不能是服务器的公共IP,因为它是来自an IPv4 private space的地址。你可能想说"主持人的私人地址"。绑定到这样的地址是有意义的。您最有可能收到错误,因为您错误地确定了主机的IP地址。
有几种方法可以获得正确的IP。如果您使用DHCP(如果您从未在SOHO中使用过哪些IP,请使用它),请登录离您最近的路由器管理界面并检查 DCHP池。或者,Linux和Windows也有终端命令来执行相同的操作。对于Arduino,您可能已经为其分配了一个静态地址。如果是这样,请绑定它。
答案 1 :(得分:0)
您似乎也在服务器上打开了一个tcp套接字,并通过udp socket从客户端连接到它。这是故意的吗?