def l2_recvfrom (client_socket=None, node=None):
  """
  This function will be used in Layer 3, the Network layer. Nowhere in this Layer 2
  is this function used--rather, this layer purely uses good ol' UDP recvfrom.
  """
  while 1:
    data = ''.encode()
    buffer = ''.encode()
    
    # Read a bunch of bytes up to the MTU or length of data.
    while len(data) <= 4096:
      buffer, external_address = client_socket.recvfrom(4096-len(data))
      if buffer:
        data += buffer
      else:
        #thread.interrupt_main()
        break
        
      # This is our protocol. Stop reading when we see \r\n.
      if '\r\n'.encode() in buffer:
        #thread.interrupt_main()
        break
    
    # Split the headers.
    packet = data.decode().split('@@')
    frame_header = packet[0].split('@')
    datagram_header = packet[1].split('@')    
    
    # Now we should have something like [Frame, Datagram, Segment].
    # Step 1. Build a new Frame.
    frame = Frame(frame_header[2], int(frame_header[3]), frame_header[0], int(frame_header[1]), 
                            int(frame_header[4]), packet[1])
                            
    # Step 2. Build a new Datagram so we can pass it to l3_recvfrom().
    # The order goes 6, 7, then 4, 5 because 6/7 is the destination of this packet, which is 
    # destined for where the source is. It's backwards since we are receiving, not sending.
    datagram = NetworkLayer.Datagram(int(datagram_header[0]), int(datagram_header[1]), int(datagram_header[2]), 
                            int(datagram_header[3]), int(datagram_header[6]), int(datagram_header[7]), 
                            int(datagram_header[4]), int(datagram_header[5]), int(datagram_header[8]), 
                            packet[2])
    
    # l3_recvfrom will return something, but right now, we are not storing that value yet.
    #NetworkLayer.l3_recvfrom(datagram)
    
    return len(buffer), frame, datagram, external_address, \
           NetworkLayer.l3_recvfrom(client_socket, str(packet[1]+'@@'+packet[2]), node)
 def test_communications (self):
   node = Node.Node(1, 'localhost', 5555)
   routing_table = RoutingProtocol.DVRP(node)
   # YOU NEED THE \r\n IN HERE.
   segment = 'This is a payload.\r\n'
   
   node.SetMTU(1500)
   node.AddLink((1, 'localhost', 1))  # A link to itself...
   node.AddLink((2, 'localhost', 1))
   node.AddLink((3, 'localhost', 1))
   client_address, client_socket = LinkLayer.InitializeSocket(node)
   what_was_sent = NetworkLayer.l3_sendto(client_socket, 2, 5555, routing_table, segment, node)
   #print(what_was_sent)
   # Receive it.
   length_of_buffer, received_frame, datagram_to_pass, external_address, received_segment = \
   LinkLayer.l2_recvfrom(client_socket, node)
   
   print(received_segment)
   received_segment.PrintContents()