code: def send(self):
          
          # Collect all the addresses for which we have not seen responses yet.
          if not self._receive_has_been_called:
              all_addrs = self._dest_addrs
          else:
              all_addrs = [a for (i, a) in list(self._id_to_addr.items())
                           if i in self._remaining_ids]
  
          if self._last_used_id is None:
              # Will attempt to continue at the last request ID we used. But if
              # we never sent anything before then we create a first ID
              # 'randomly' from the current time. ID is only a 16 bit field, so
              # need to trim it down.
              self._last_used_id = int(time.time()) & 0xffff
  
          # Send ICMPecho to all addresses...
          for addr in all_addrs:
              # Make a unique ID, wrapping around at 65535.
              self._last_used_id = (self._last_used_id + 1) & 0xffff
              # Remember the address for each ID so we can produce meaningful
              # result lists later on.
              self._id_to_addr[self._last_used_id] = addr
              # Send an ICMPecho request packet. We specify a payload consisting
              # of the current time stamp. This is returned to us in the
              # response and allows us to calculate the 'ping time'.
              self._send_ping(addr, payload=struct.pack("d", time.time()))
docs: Send pings to multiple addresses, ensuring unique IDs for each request.
  
          This operation is non-blocking. Use 'receive' to get the results.
  
          Send can be called multiple times. If there are any addresses left from
          the previous send, from which results have not been received yet, then
          it will resend pings to those remaining addresses.