示例#1
0
  /**
   * sends data from buffer.
   *
   * <p>precondition: sendbb is in put mode post condition: sendbb is in put mode
   */
  private void sendFromBuffer() {
    aa(this, isSender(), "nonsender can't write");
    aa(this, isConnected() || isClosurePending(), "needs to be established can't write");

    // switch sendbb to get mode
    sendbb.flip();
    p(this, 3, "Sending from buffer. bb flipped.");
    int payloadLength = Math.min(Transport.MAX_PAYLOAD_SIZE, sendbb.limit());
    p(this, 4, "Max Payload size: " + Transport.MAX_PAYLOAD_SIZE);
    p(this, 4, "payloadlen: " + payloadLength);
    dumpState(4);

    if (roomForPacket(payloadLength) && payloadLength > 0) {
      byte[] payload = new byte[payloadLength];
      sendbb.get(payload);

      Transport t = makeTransport(Transport.DATA, seqNum, payload);
      tcpMan.sendData(this.tsid, t);

      p(this, 3, "Write: converting to packet: " + TCPManager.bytesToString(payload));

      // only increment the seqNum if a packet is sent
      seqNum += payloadLength;
    }

    // switch back to put mode
    sendbb.compact();
    dumpState(4);
    if (isClosurePending() && sendbb.position() == 0) release();
  }
示例#2
0
 /** Release a connection immediately (abortive shutdown) */
 public void release() {
   p(this, 3, "Release()");
   // TODO(syu) send a FIN
   this.state = State.CLOSED;
   tcpMan.sendFIN(tsid);
   if (isReceiver()) tcpMan.remove(tsid);
 }
示例#3
0
  /**
   * Accept a connection on a socket
   *
   * <p>Needs to trigger sending an ACK
   *
   * @return TCPSock The first established connection on the request queue remove from welcomeQueue
   *     adds recvSocket to socketSpace sends Ack
   */
  public TCPSock accept() {
    aa(this, this.sockType == SocketType.WELCOME, "accept() called by non-welcome socket");
    aa(this, this.state == State.LISTEN, "accept() called when not listening");

    if (welcomeQueue.isEmpty()) return null;

    p(this, 3, "accept()");
    TCPSock recvSock = welcomeQueue.remove(0);
    recvSock.state = State.ESTABLISHED;
    p(recvSock, 4, "established");
    tcpMan.add(recvSock.tsid, recvSock);
    tcpMan.sendACK(recvSock.tsid);

    return recvSock;
  }
示例#4
0
  /**
   * Initiate connection to a remote socket
   *
   * @param destAddr int Destination node address
   * @param destPort int Destination port
   * @return int 0 on success, -1 otherwise
   */
  public int connect(int destAddr, int destPort) {
    // if not starting from a closed state, connect should fail.
    if (!isClosed() || !isSender()) {
      pe(this, " connect() called on inappropriated");
      return -1;
    }

    p(this, 3, "Connect() to:  " + destAddr + ":" + destPort);
    this.tsid.remoteAddr = destAddr;
    this.tsid.remotePort = destPort;

    tcpMan.add(this.tsid, this);
    tcpMan.sendSYN(this.tsid);
    this.state = State.SYN_SENT;

    return 0;
  }
示例#5
0
  /**
   * Listen for connections on a socket
   *
   * @param backlog int Maximum number of pending connections
   * @return int 0 on success, -1 otherwise
   */
  public int listen(int backlog) {
    if (sockType != SocketType.WELCOME) {
      die(this, "not a welcome socket");
      return -1;
    }
    this.state = State.LISTEN;
    p(this, 3, "listening. backlog: " + backlog);

    this.backlog = backlog;
    welcomeQueue = new ArrayList<TCPSock>(backlog);
    tcpMan.addWelcomeSocket(this);
    return 0;
  }
示例#6
0
  public void dataReceived(Transport t) {
    aa(this, isReceiver(), "DATA received by non receiver socket");
    aa(this, isConnected(), "DATA received by invalid socket state");

    int inSeqNum = t.getSeqNum();

    p(this, 3, "dataReceived() seqnum: " + inSeqNum);
    transportBuffer.put(inSeqNum, t);
    deliverToBuffer();

    dumpState(4);
    p(this, 3, "ending dataReceived");

    tcpMan.sendACK(this.tsid);
  }
示例#7
0
  public TCPSock(TCPManager tcpMan, SocketType type) {
    this.tcpMan = tcpMan;
    this.tsid = new TCPSockID();
    this.tsid.localAddr = tcpMan.getAddr();
    this.state = State.CLOSED;
    this.sockType = type;

    switch (sockType) {
      case SENDER:
        initSender();
        break;
      case RECEIVER:
        initReceiver();
        break;
      case WELCOME:
        initWelcome();
        break;
    }

    this.seqNum = 0;
  }