我正在尝试连接到客户端计算机,以便使用UDP从服务器计算机发送整数值。问题的出现(我相信)是由于服务器计算机在Python中发送和侦听UDP通信,而客户端从MATLAB脚本接收和发送消息。从理论上讲,这种安排应该没有关系,因为UDP通信根本不应该受到编码语言的影响。
服务器端代码(Python):
import socket
commandVal = 0 #Message to be sent
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(np.uint8(commandVal), (hostIP, portNum)) #hostIP and portNum are defined separately
sock.connect((hostIP, portNum))
while True:
data, addr = sock.recvfrom(1024)
print("received message: %s" % data)
客户端代码(MATLAB):
packetlength = 50
waitdur = 15000
mssgA = judp('receive',port,packetlength,waitdur);
if mssgA(1) == 0
judp('send',port, host,int8('error'))
else
judp('send',port, host,int8('success'))
我知道端口和IP地址定义正确,因为如果我使用基于MATLAB的judp
函数从服务器端进行通信,我就可以发送和接收消息。
当使用Python代码时,消息被发送到客户端,但没有收到“错误”或“成功”消息。这里有什么问题吗?
我尝试过更改防火墙设置,并浏览judp
和socket
的文档。我还没找到解决办法
2条答案
按热度按时间vaqhlq811#
我有点困惑,在你的代码中谁是客户端,谁是服务器。看起来你的“服务器”正在向“客户端”发送命令/请求,这似乎是向后的?
话虽如此,我认为你的主要问题来自这样一个事实,即你从来没有将你的“服务器”套接字绑定到一个特定的地址,这意味着你的“客户端”的消息不被识别为寻址到“服务器”。
此外,您在MATLAB脚本中使用相同的端口进行发送和接收,这可能是一个错字,也可能是故意的,恐怕我不能说没有更多关于您代码其余部分的信息。
server.py
客户端.m
r6hnlfcb2#
TL;DR
在服务器上使用套接字的
bind
方法,以便将其绑定到特定的端口号。通常建议仅绑定到服务器预期通过其进行通信的特定IP地址(或接口),但如果合适,可以使用通配符(所有接口-0.0.0.0)。确保在发出任何传出流量之前绑定套接字,如下所示:
概述
通常在客户端-服务器架构中,客户端发起与服务器的通信(就像有人问问题一样),服务器相应地回复(通常是问题的答案)。这对于UDP和TCP都是正确的(例如DHCP、NTP、DNS等)。一些服务器可以发起与下级机器的通信(例如在配置管理中),但是可以认为这些机器实际上正在运行“服务器”(代理)以回复客户端(CM服务器)的查询。正如@Hoodlum所提到的,让你的“服务器”(Python代码)与“客户端”(MATLAB)联系是相当混乱的,但这是一个不同的主题(如果有的话)。
技术支持
在客户端-服务器架构中,服务器将在特定端口上监听传入的客户端请求(例如,HTTP的端口号为80,HTTPS的端口号为443,SMTP的端口号为25,等等),而客户端通常会分配一个伪随机的源端口号,它们期望接收服务器的应答(通常有些顺序,关键是这些端口号不能被依赖)。这就是问题中的服务器和客户端之间开始出现问题的地方:
在服务器端,
sendto
可以正常工作。如上所述,UDP数据报到达MATLAB客户端。当客户端试图向port
发送响应时,问题就开始了,而服务器并没有监听。由于服务器的套接字没有绑定到特定的端口,因此传出消息被赋予了一个伪随机(顺序的东西)端口号。客户端被配置为将消息发送到Python应用程序(可能)没有监听的特定端口号,并且该数据报将无法到达其期望的目的地。解决方案
[免责声明-我没有MATLAB许可证,所以我尽可能地将客户端代码移植到Python。我建议的一些解决方案需要修改客户端的代码,我不确定MATLAB是否可以做到这一点。
这是作为一个摘要提供的运行示例。代码本身将在下面发布。
1.绑定服务端socket
2.绑定连接客户端
请注意,连接后,应使用
send/recv
而不是sendto/recvfrom
3.让客户端知道服务器的端口(需要修改客户端)
4.实现客户端-服务器,其中服务器不发起通信(需要更改客户端)
这还有一个额外的好处,即在服务器保持运行的同时,可以多次触发客户机
代码
首先,让我们展示问题是否会重现:
下面是一些代码(
example.py
的完整内容):总结(终于...)
喜欢Hoodlum的solution,有一些保留。它很简单,并处理
socket.close()
(通过使用with
上下文)。基本上,这是我的帖子的解决方案#2,只是更短,更可读。尽管如此,我认为这是值得写的,可能会阐明这个问题的原因(或美化UDP,IDK)。