def recv(self, nbytes):
"""
Receive a datagram sent to this port using the L{MemoryIOSystem} which
created this object.
This behaves like L{socket.socket.recv} but the data being I{sent} and
I{received} only passes through various memory buffers managed by this
object and L{MemoryIOSystem}.
@see: L{socket.socket.recv}
"""
data = self._system._openFiles[self._fileno].writeBuffer.popleft()
datagrams = []
receiver = DatagramProtocol()
def capture(datagram, address):
datagrams.append(datagram)
receiver.datagramReceived = capture
udp = RawUDPProtocol()
udp.addProto(12345, receiver)
ip = IPProtocol()
ip.addProto(17, udp)
mode = self._system._openFiles[self._fileno].tunnelMode
if (mode & TunnelFlags.IFF_TAP.value):
ether = EthernetProtocol()
ether.addProto(0x800, ip)
datagramReceived = ether.datagramReceived
else:
datagramReceived = lambda data: ip.datagramReceived(
data, None, None, None, None)
dataHasPI = not (mode & TunnelFlags.IFF_NO_PI.value)
if dataHasPI:
# datagramReceived can't handle the PI, get rid of it.
data = data[_PI_SIZE:]
datagramReceived(data)
return datagrams[0][:nbytes]