[英]Sending data consecutively to two different IPs with socket.socket: is it standard behaviour that the NAT keeps the same port?
[英]Is it possible to have a socket listening to two UDP IPs, one that is 127.0.0.1 (same machine) and a different computer at the same time?
我使用的眼动追踪应用程序利用UDP发送数据包。 我在同一台计算机上制作了一个python套接字,以侦听数据并将其转储为.txt文件。 我已经做了很多工作。
另一个用python编写的单独应用程序(眼睛跟踪的对象正在查看的内容)在单独的计算机上运行。 因为眼动追踪应用程序是连续的并且会发送不必要的数据,所以到目前为止,当对象正在查看所需的刺激时,我不得不手动解析出实例。 我是基于手动同步启动刺激和眼动跟踪应用程序,然后再挖掘日志文件来完成此操作的。
我想做的是让第二台计算机充当第二个UDP客户端,每次受试者观察刺激时都会向眼动计算机上的套接字发送一个数据包(之前在.txt文件中插入了标记)提到)。 是否可以让一个套接字同时监听两个IP地址?
这是我的套接字脚本:
#GT Pocket client program
import datetime
import socket
now = datetime.datetime.now()
filename = 'C:\gazelog_' + now.strftime("%Y_%m_%d_%H_%M") + '.txt'
UDP_IP = '127.0.0.1' # The remote host (in this case our local computer)
UDP_PORT = 6666 # The same port as used by the GT server by default
sock = socket.socket(socket.AF_INET, #internet
socket.SOCK_DGRAM) #UDP
sock.bind( (UDP_IP, UDP_PORT) )
while True:
data, addr = sock.recvfrom( 1024) #I assume buffer size is 1024 bytes.
print "Received Message:", data
with open(filename, "a") as myfile:
myfile.write(str(data + "\n"))
sock.close()
myfile.close()
编辑:
@abarnert我能够绑定到以太网接口上的主机地址,并从计算机B向计算机A发送消息,但是计算机A不再能够从其自身接收数据包。 当我指定UDP_IP = '0.0.0.0'
计算机B不再能够通过以太网发送数据。 当我指定UDP_IP = ''
我收到`error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
这与我在计算机B上用于发送数据的脚本有关:
import socket
UDP_IP = "169.254.35.231" # this was the host address I was able to send through.
UDP_PORT = 6666
MESSAGE = "Start"
print ("UDP target IP:"), UDP_IP
print ("UDP target port:"), UDP_PORT
print ("message:"), MESSAGE
sock = socket.socket(socket.AF_INET,
socket.SOCK_DGRAM)
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT) )
我不知道需要在哪里(或者根本不需要)指定INADDR_ANY,所以我没有。 但是我确实尝试过一次在哪里import socket.INADDR_ANY
但出现ImportError: No module named INADDR_ANY
根据您的回复,这似乎是一个简单的问题,所以我不确定我在哪里搞砸。
EDIT2:我只是重新阅读了您的答案,并理解了为什么socket.INADDR_ANY不起作用。 请忽略我先前编辑的那部分
EDIT3:好的,所以我在指定主机IP时未拾取数据的原因是,我仍在计算机A上从中收集数据的应用程序仍指定发送给127.0.0.1。 所以我想通了。 我仍然很好奇为什么0.0.0.0不能正常工作!
否。套接字一次只能绑定到一个地址。*
如果碰巧有一个地址可以同时满足您的所有需求,则可以使用一个套接字来监听它。 在这种情况下, INADDR_ANY
主机( 0.0.0.0
)可能正是您要寻找的主机-它将处理所有接口上的任何(IPv4)连接,包括环回和其他方式。 并且即使没有预先存在的地址可以满足您的要求,您也可以通过ipfilter-type接口进行设置。
但是否则,您必须创建两个套接字。 这意味着您需要与select
类的对象多路复用,或者创建两个线程。
在您的情况下,您想指定一个既可以侦听本地计算机又可以侦听同一以太网网络上另一台计算机的主机。 您可以在以太网接口上获取主机地址并将其绑定。 (您的机器可以在其任何接口上与自己通信。)通常,在“默认接口是任何接口”上获取地址也适用于此操作—您会在某些地方看到绑定到socket.gethostname()
代码,例如Python套接字编程HOWTO 。 但是绑定到INADDR_ANY
要简单得多。 除非您要确保某些接口上的计算机无法连接到您(这通常仅是一个问题,例如,您要构建用于驻留在防火墙的DMZ上的服务器),否则通常需要使用INADDR_ANY
。
最后,您如何绑定到INADDR_ANY
? 简短的答案是:如果您想更明确地使用UDP_IP = ''
或UDP_IP = '0.0.0.0'
。 任何了解套接字的人,即使他们不了解任何Python,也会理解服务器代码中'0.0.0.0'
含义。(您可能想知道为什么Python在socket
模块中对此没有常量,尤其是当像C这样的低级语言。答案是可以的,但实际上并不实用。**)
*请注意,绑定到单个地址并不意味着您只能从单个地址接收数据包。 这意味着您可以从单个地址可以到达的所有网络接收数据包。 例如,如果您的计算机具有LAN连接(地址为10.0.0.100)和WAN连接(地址为8.9.10.11),则如果绑定10.0.0.100,则可以从其他LAN客户端(如10.0)接收数据包。 0.201和10.0.0.202。 但是您不能从WAN客户端(如9.10.11.12,即10.0.0.100)接收数据包。
**在低级套接字API中,点字符串地址(例如'0.0.0.0'
将转换为32位整数(例如0
。 Python有时将这些整数表示为int
,有时还表示为4字节的缓冲区,例如b'\\0\\0\\0\\0'
。 根据您的平台和版本, socket.INADDR_ANY
常数可以为0
或b'\\0\\0\\0\\0'
。 bind
方法不会采用0
,也可能不会采用b'\\0\\0\\0\\0'
。 而且,如果不先检查您具有哪种格式,然后在其上调用正确的函数,就无法转换为'0.0.0.0'
。 这很丑。 这就是为什么只使用'0.0.0.0'
更容易的原因。
我相信您可以将原始套接字绑定到整个接口,但是您似乎正在使用两个不同的接口。
最好将两个套接字与select()一起使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.