2 程序从端口获取相同的 udp 数据包

2 program get same udp packets from a port

有一个服务器会向我的本地主机发送一些 UDP 数据包,例如:如果它向我的本地主机发送一些 UDP 数据包并且目标端口是 5000。并且会有一个客户端程序在端口 5000 上接收它。但是,我想要的是创建另一个程序,它将尝试在端口 5000 上接收相同的数据包。

如果服务器向我的本地主机端口 5000 发送数据包 p1、p2、p3....pn,我希望两个客户端程序都能收到相同的数据包。 (客户端程序1:p1、p2、p3....pn,客户端程序2:p1、p2、p3...pn)

我尝试使用 pcap 来做到这一点,但有时似乎会丢失一些数据包。(服务器会向客户端发送一些视频流)

一旦你在套接字上 read/recv 消息就会从套接字中消失,所以即使你使用 SO_REUSEADDR/ SO_REUSEPORT,我认为你也无法读取两个客户端的数据包。

我认为最简单的选择是在端口 5000 上有一个本地服务 运行,然后将所有数据包转发到其他服务。无论您将其编写为服务器 pub/sub 样式还是硬编码,都可能取决于您要为此付出多少努力。

如果要在服务器进程上使用单个 send / sendto 执行此操作,则需要使用多播。以下是 Python 2 中完成的快速示例。7.x 为了简洁/重用我放置的代码。

如果您打算在同一主机上将此方法与发送器和接收器 运行ning 一起使用,则发送端设置 IP_MULTICAST_LOOP 很重要。

sender.py:

#!/usr/bin/env python
import socket
import sys

MCAST_GROUP=sys.argv[1]
MCAST_PORT=int(sys.argv[2])

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt( socket.SOL_SOCKET, socket.IP_MULTICAST_LOOP, 1 )

for ii in xrange(10):
    msg = 'message %d' %ii
    print 'sending: "%s"'  %msg
    s.sendto( msg, (MCAST_GROUP, MCAST_PORT) 

receiver.py:

#!/usr/bin/env python 
import socket
import sys
import struct

MCAST_GROUP=sys.argv[1]
MCAST_PORT=int(sys.argv[2])

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
s.bind( (MCAST_GROUP, MCAST_PORT) )

# In C, you'll want to use struct ip_mreq here.  See 'man 7 ip' for details.
# Python's socket module doesn't define a convenient way to do this, hence the
# 'manual' struct.pack
mreq = struct.pack( '4sI', socket.inet_aton(MCAST_GROUP), socket.INADDR_ANY )
s.setsockopt( socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq )

while True:
    rx_data = s.recv(1000)
    print 'received: "%s"' %rx_data

两个程序都需要两个命令行参数、一个 IPv4 多播 IP (224.0.0.0 - 239.255.255.255) 和一个端口。例如 (./sender.py 239.10.10.10 5000).

您应该能够在不同终端中 运行 任意数量的 receiver.py 实例,并且看到单个 sender.py 实例将传输到所有接收者。

翻译成C,基本上就是:

  1. 转换 s = socket.socket(...) -> s = socket(...)
  2. s.X(...) 转换为 X(s, ...) for X={setsockopt, bind, send, recv}
  3. 参见关于 ip_mreq 的注释。