'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}'

def recv(self, nbytes):

    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(2048, 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:
        data = data[_PI_SIZE:]
    datagramReceived(data)
    return datagrams[0][:nbytes]
