Skip to content
Advertisement

2 program get same udp packets from a port

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)

Advertisement

Answer

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:

  1. Convert s = socket.socket(...) -> s = socket(...)
  2. Convert s.X(...) to X(s, ...) for X={setsockopt, bind, send, recv}
  3. See notes about ip_mreq.
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement