Tutorials¶
Jump to a Tutorial
NAT Traversal¶
This is used for peers behind a router, as is the case for most users. There are two methods of external port mapping, and both are covered here. To see usage of “catch-all” port mapping, just reference the example in the API docs.
Note
This example should not be necessary in a few iterations of the library. It’s necessary now because detecting whether or not the peer is behind a router (and thus needs NAT traversal) is not implemented. Eventually, this part will happen automatically.
UPnP¶
Universal Plug and Play is the first method used when
using the generic traversal.PortMapping
object.
The following example tries to map the local port 7777 to external port 8888, increasing the mapped port up to 5 times on failures.
import sys
from cicada.traversal import upnp
LOCAL_PORT = 7777
ATTEMPTS = 5
mapper = upnp.UPnP()
mapper.create()
eport = 8888
for i in xrange(ATTEMPTS):
if mapper.add_port_mapping(LOCAL_PORT, eport, protocol="udp"):
break
if i == ATTEMPTS - 1: continue
print "Failed to map %d <--> %d, trying %d." % (
LOCAL_PORT, eport, eport + 1)
eport += 1
else:
print "Failed to map %d after 5 attempts." % LOCAL_PORT
sys.exit(1)
print "Succeeded in mapping %d <--> %d." % (LOCAL_PORT, eport)
mapper.delete_port_mapping(LOCAL_PORT, protocol="udp")
mapper.cleanup() # removes *all* mappings
Simple 2-Node Echo Server¶
In this sample, we’ll create a 2-peer Cicada swarm and echo messages back and forth between the peers.
""" Establishes a *local* swarm, echoing a message between them.
"""
import sys, time
from cicada import swarmlib
from cicada.traversal import portmapper
local_address = portmapper.PortMapper.get_local_address()
first, second = swarmlib.SwarmPeer(), swarmlib.SwarmPeer()
first.bind(local_address, 5000)
second.bind(local_address, 5001)
second.connect(*first.listener)
first.send(second.listener, "hello!")
src, data, _ = second.recv()
assert data == "hello!"
assert src.chord_addr == first.listener
second.send(first.listener, data[::-1])
src, data, _ = first.recv()
assert data == "!olleh"
assert src.chord_addr == second.listener