Пример #1
0
 /**
  * Read data from the input buffer up to len bytes long. Block until there is data available.
  *
  * @param dst
  * @param off
  * @param len
  * @return The number of bytes read
  */
 public synchronized int read(byte[] dst, int off, int len) throws SocketException {
   while ((dataBuffer.getUsed() == 0) && !controlBlock.isReset() && !isEOF()) {
     try {
       wait();
     } catch (InterruptedException ex) {
       // Ignore
     }
   }
   if (controlBlock.isReset()) {
     throw new SocketException("Connection reset");
   } else if (isEOF()) {
     return -1;
   } else {
     return dataBuffer.read(dst, off, len);
   }
 }
Пример #2
0
  /**
   * Process the given segment (that must be the next expected segment). The data will be send to
   * the input data buffer, if there is enough space left in the buffer.
   *
   * @param hdr
   * @param skbuf
   * @return True if the segment has been fully processed, false otherwise.
   * @throws SocketException
   */
  private synchronized boolean processNextSegment(TCPHeader hdr, SocketBuffer skbuf)
      throws SocketException {
    final int seqNr = hdr.getSequenceNr();
    if (seqNr != rcv_next) {
      throw new IllegalArgumentException("hdr.seqNr != rcv_next");
    }

    // This segment is the first expected segment
    // Sent it to the application if there is enough space
    final int dataLength = hdr.getDataLength();
    if (dataLength > dataBuffer.getFreeSize()) {
      // Not enough free space, ignore this segment, it will be retransmitted.
      log.debug("nextSegment dropped due to lack of space");
      return false;
    } else {
      // Enough space, save
      if (dataLength > 0) {
        dataBuffer.add(skbuf, 0, dataLength);
        // Update rcv_next
        rcv_next += dataLength;
      }
      final boolean fin = hdr.isFlagFinishedSet();
      final boolean syn = hdr.isFlagSynchronizeSet();
      if (syn || fin) {
        // SYN & FIN take up 1 seq-nr
        rcv_next++;
      }
      if ((dataLength > 0) || fin) {
        // And ACK it
        controlBlock.sendACK(0, rcv_next);
      }
      // Notify threads blocked in read
      notifyAll();
      // We've processed it fully
      return true;
    }
  }
Пример #3
0
 /**
  * Has the End of the InputChannel been reached?
  *
  * @return True if EOF has been reached, false otherwise
  */
 protected final boolean isEOF() {
   if (!finReceived) {
     // Other site has not closed
     return false;
   }
   if (dataBuffer.getUsed() > 0) {
     // Still data in databuffer
     return false;
   }
   if (!futureSegments.isEmpty()) {
     // Still future segments
     return false;
   }
   // TODO No other requirements here?????
   return true;
 }
Пример #4
0
 public int getBufferSize() {
   return dataBuffer.getLength();
 }
Пример #5
0
 /** Return the number of available bytes in the input buffer. */
 public int available() {
   return dataBuffer.getUsed();
 }