Reputation: 51
there is a server will send some UDP packets to my localhost, for example: if it send some UDP packets to my localhost and destination port is 5000. and there will have a client program to receive it on port 5000. but, what I want is to create another program, it will try to receive the same packets on port 5000.
if the server send packets p1, p2, p3....pn to my localhost port 5000, I want to both client programs will receive same packets. (client program 1: p1, p2, p3....pn, client program 2: p1, p2, p3...pn)
I tried to use pcap to do this, but seems lost some packets in sometimes.(the server will send some video stream to client)
Upvotes: 2
Views: 207
Reputation: 9412
You need to use multicast if you want to do this with a single send
/ sendto
on the server process. Here are quick examples done in Python 2.7.x for the sake of brevity / reuse of code I had laying around.
It's import for the transmit side to set IP_MULTICAST_LOOP
if you are going to use this method with transmitter & receivers running on the same host.
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
Both programs expect two command line arguments, an IPv4 multicast IP (224.0.0.0 - 239.255.255.255), and a port. For example (./sender.py 239.10.10.10 5000
).
You should be able to run as many instances of receiver.py
as you like in different terminals, and see that a single instance of sender.py
will transmit to all receivers.
To translate this to C
, it's basically:
s = socket.socket(...)
-> s = socket(...)
s.X(...)
to X(s, ...)
for X={setsockopt
, bind
, send
, recv
}ip_mreq
.Upvotes: 3
Reputation: 5557
Once you read/recv on the socket the messages will be gone from the socket, so even if you use SO_REUSEADDR/ SO_REUSEPORT, I don't think you will be able to read the packets with both clients.
I think the easiest option is to have a local service running on port 5000 which then forwards all packets to the other services. Whether you write that as a server pub/sub style or hard-code it is probably something to decide based on how much effort you want to put into this.
Upvotes: 1