Пример #1
0
  void cancel(boolean sequenced, int oldtag) {
    // cancel stuff from the pending packet queue
    _pendingPacketQueue.cancel(sequenced, oldtag);

    // cancel stuff from the outstanding packet queue
    TSNRangeHandler rh = new TSNRangeHandler(false, sequenced);
    _outstandingPacketQueue.cancel(sequenced, oldtag, rh);
    ACKInformation ai = new ACKInformation();
    rh.fillACKInformation(ai);

    // send control packet containing cancelled packets chunk
    MessagePacket p = new MessagePacket();
    p.setFlags(MessagePacket.HEADER_FLAG_CONTROL);
    CancelledPacketsChunk cpChk = new CancelledPacketsChunk(ai);
    p.addChunk(cpChk);
    MessagePacketInfo pi =
        new MessagePacketInfo(
            p, TxParams.MAX_PRIORITY, 0, 0, MessageMocket.DEFAULT_RETRANSMISSION_TIMEOUT);
    transmitPacket(pi);
  }
Пример #2
0
  void send(
      boolean reliable,
      boolean sequenced,
      byte[] buf,
      int off,
      int len,
      int tag,
      int priority,
      long enqueue_timeout,
      long retry_timeout)
      throws IOException {
    /* we accept data only if the connection is not closed */
    if (_status.currentState() != MessageStateMachine.ESTABLISHED)
      throw new IOException("Connection closed!");

    /* this is the space we can use for data in each packet
     * (provided we have only a single DATA chunk in each packet) */
    int availSize =
        _mocket.getMTU() - (MessagePacket.HEADER_SIZE + DataChunk.DATA_CHUNK_HEADER_SIZE);

    if (_mocket.isCrossSequencingEnabled())
      availSize -= DeliveryPrerequisites.DELIVERY_PREREQUISITES_SIZE;

    _logger.fine(
        "MessageTransmitter::send "
            + (reliable ? "R " : "")
            + (sequenced ? "S " : "")
            + "len = "
            + len
            + " tag = "
            + tag);

    int toSend = len;
    int sent = 0;
    int fragmentNum = 0;
    boolean fragmentationNeeded = len > availSize;

    if (fragmentationNeeded) _logger.info("fragmentation needed!!!");

    // build and enqueue message packet(s)
    while (toSend > 0) {
      int cc = Math.min(toSend, availSize);

      MessagePacket p = new MessagePacket();
      if (reliable) p.setFlags(MessagePacket.HEADER_FLAG_RELIABLE);
      if (sequenced) p.setFlags(MessagePacket.HEADER_FLAG_SEQUENCED);

      if (fragmentationNeeded) p.allocateSpaceForDeliveryPrerequisites();

      DataChunk chk = new DataChunk(tag, buf, off + sent, cc);

      if (!p.addChunk(chk)) {
        // this should never happen
        throw new IOException("Buffer size too big");
      }

      toSend -= cc;

      if (fragmentationNeeded) {
        assert toSend >= 0;
        if (toSend == 0) {
          p.setFlags(MessagePacket.HEADER_FLAG_LAST_FRAGMENT);
        } else {
          if (fragmentNum == 0) {
            p.setFlags(MessagePacket.HEADER_FLAG_FIRST_FRAGMENT);
          }
          p.setFlags(MessagePacket.HEADER_FLAG_MORE_FRAGMENTS);
        }
      }

      // enqueue message packet
      if (!enqueueMessagePacket(p, priority, enqueue_timeout, retry_timeout)) {
        throw new IOException("Pending packet queue is full.");
      }

      ++fragmentNum;
      sent += cc;
    }

    transmitNextPacket();

    // wake up transmitter thread
    synchronized (this) {
      notifyAll();
    }
  }