⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.java

📁 一个小型网络仿真器的实现
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    tcb.srtt=(SimParamDouble)it.next();
    tcb.rto=(SimParamDouble)it.next();
  }

  public Object open(int sourceip,int sourceport,int destip,int destport,
                        boolean passive,TCPUser user) {
    return open(sourceip,sourceport,destip,destport,passive,user,null);
  }

  public Object open(int sourceip,int sourceport,int destip,int destport,
                        boolean passive,TCPUser user,java.util.List paramset) {
    TCBKey k=new TCBKey(sourceip,sourceport,destip,destport);
    TCB tcb=(TCB)tcbs.get(k);

    if(tcb!=null && tcb.status.getValue()==STAT_LISTEN) {
      //allow connection with specified foreign socket to switch from
      //passive to active call.
      //remove the previous tcb and continue with the creation of a new one
      tcbs.remove(k);
      tcb=null;
    }

    if(tcb==null) { //connection does not exist
      tcb=new TCB();
      tcb.key=k;
      tcb.passive=passive;
      tcb.user=user;
      tcb.input_q=new java.util.LinkedList();
      tcb.output_q=new java.util.LinkedList();
      tcb.retrans_timer=new VirtualTimer(MY_RETRANS_TIMEOUT,DEFAULT_RETRANS_TIMEOUT,this,tcb);
      tcb.timewait_timer=new VirtualTimer(MY_TIMEWAIT_TIMEOUT,DEFAULT_TIMEWAIT_TIMEOUT,this,tcb);
      tcb.retrans_q=new java.util.LinkedList();
      tcb.reseq_q=new java.util.LinkedList();

      if(paramset==null) setParamset(tcb,createParamset());
      else setParamset(tcb,paramset);

      tcb.status.setValue(STAT_CLOSED);
      tcb.snd_una.setValue(0);
      tcb.snd_nxt.setValue(0);
      tcb.snd_wnd.setValue(0);
      tcb.snd_wl1.setValue(0);
      tcb.snd_wl2.setValue(0);
      tcb.iss.setValue(0);
      tcb.rcv_nxt.setValue(0);
      tcb.rcv_wnd.setValue(provider.getMaxWindowSize());
      tcb.irs.setValue(0);
      tcb.cwnd.setValue(provider.getMaxSegmentSize());
      tcb.ssthresh.setValue(provider.getMaxWindowSize());
      tcb.rttvar.setValue(-1);
      tcb.srtt.setValue(-1);
      tcb.rto.setValue(DEFAULT_RETRANS_TIMEOUT);

      tcb.snd_una.update(comp.getSim().now());
      tcb.snd_nxt.update(comp.getSim().now());
      tcb.snd_wnd.update(comp.getSim().now());
      tcb.rcv_nxt.update(comp.getSim().now());
      tcb.rcv_wnd.update(comp.getSim().now());
      tcb.cwnd.update(comp.getSim().now());
      tcb.ssthresh.update(comp.getSim().now());
      tcb.rttvar.update(comp.getSim().now());
      tcb.srtt.update(comp.getSim().now());
      tcb.rto.update(comp.getSim().now());

      if(passive) {
        tcb.status.setValue(STAT_LISTEN);
        tcbs.put(k,tcb);

        provider.statusChanged();
        return k;
      }

      //check whether foreign socket is specified
      if(k.dest_ip==0 && k.dest_port==0) return null;

      //issue the SYN segment
      tcb.iss.setValue(init_seq_generator(comp.getSim().now()));
      tcb.snd_una.setValue(tcb.iss.getValue(),comp.getSim().now(),provider.getLogFactor());
      tcb.snd_nxt.setValue(tcb.iss.getValue()+1,comp.getSim().now(),provider.getLogFactor());
      tcb.status.setValue(STAT_SYN_SENT);
      tcbs.put(k,tcb);

      TCPSegment seg=new TCPSegment();
      seg.sourceport=k.source_port;
      seg.destport=k.dest_port;
      seg.seg_seq=tcb.iss.getValue();
      seg.syn=true;
      seg.seg_len=1;
      IPPacket packet=new IPPacket();
      packet.sourceIP=k.source_ip;
      packet.destIP=k.dest_ip;
      packet.protocol=IPPacket.PRO_TCP;
      packet.len=46;
      packet.payload=seg;
      send_ip(packet);

      tcb.rtt_seq=tcb.iss.getValue(); //set the rtt reference seq num
      tcb.rtt_tick=comp.getSim().now();
      tcb.rtt_on=true;

      //retrans q & timer
      TCPBuffer buf=new TCPBuffer();
      buf.syn=true;
      buf.len=1;
      tcb.retrans_q.add(buf);
      tcb.retrans_timer.start();

      provider.statusChanged();

      return k;
    }

    return null; //connection already exists!
  }

  public boolean send(Object k,TCPBuffer buf) {
    TCB tcb=(TCB)tcbs.get(k);
    if(tcb==null) return false; //no connection yet

    switch (tcb.status.getValue()) {
      case STAT_LISTEN:
        //check for specified foreign socket
        if(tcb.key.dest_ip==0 && tcb.key.dest_port==0)
          return false;
  
        //ok, change to active,
        //issue the SYN segment
        tcb.iss.setValue(init_seq_generator(comp.getSim().now()));
        tcb.snd_una.setValue(tcb.iss.getValue(),comp.getSim().now(),provider.getLogFactor());
        tcb.snd_nxt.setValue(tcb.iss.getValue()+1,comp.getSim().now(),provider.getLogFactor());
        tcb.status.setValue(STAT_SYN_SENT);
  
        TCPSegment seg=new TCPSegment();
        seg.sourceport=tcb.key.source_port;
        seg.destport=tcb.key.dest_port;
        seg.seg_seq=tcb.iss.getValue();
        seg.syn=true;
        seg.seg_len=1;
        IPPacket packet=new IPPacket();
        packet.sourceIP=tcb.key.source_ip;
        packet.destIP=tcb.key.dest_port;
        packet.protocol=IPPacket.PRO_TCP;
        packet.len=46;
        packet.payload=seg;
        send_ip(packet);

        tcb.rtt_seq=tcb.iss.getValue(); //set the rtt reference seq num
        tcb.rtt_tick=comp.getSim().now();
        tcb.rtt_on=true;

        //retrans q & timer
        TCPBuffer tempbuf=new TCPBuffer();
        tempbuf.syn=true;
        tempbuf.len=1;
        tcb.retrans_q.add(tempbuf);
        tcb.retrans_timer.start();

        //queue data
        tcb.input_q.add(buf);

        provider.statusChanged();
        return true;

      case STAT_SYN_SENT:
      case STAT_SYN_RCVD:
        tcb.input_q.add(buf);
        return true;

      case STAT_ESTABLISHED:
      case STAT_CLOSE_WAIT:
        tcb.input_q.add(buf);
        send_new_data(tcb);
        if(!tcb.retrans_timer.isRunning()) tcb.retrans_timer.start();
        return true;

      default:
        return false;
    }
  }

  public boolean receive(Object k,int buf_len) {
    TCB tcb=(TCB)tcbs.get(k);
    if(tcb==null) return false; //no connection yet

    int i,len;
    switch (tcb.status.getValue()) {
      case STAT_LISTEN:
      case STAT_SYN_SENT:
      case STAT_SYN_RCVD:
        tcb.userbuf_len=buf_len;
        break;

      case STAT_ESTABLISHED:
      case STAT_FIN_WAIT1:
      case STAT_FIN_WAIT2:
        //calculate buf size in output_q
        boolean push=false;
        len=0;
        for(i=0;i<tcb.output_q.size();i++) {
          TCPBuffer buf=(TCPBuffer)tcb.output_q.get(i);
          len+=buf.len;
          if(buf.push) push=true;
        }
        tcb.userbuf_len=buf_len;
        if(push || (buf_len>0 && len>=buf_len)) { //notify user if enough data
          comp.getSim().enqueue(new SimEvent(MY_RECEIVE_BUF,this,this,comp.getSim().now(),tcb));
        }
        break;

      case STAT_CLOSE_WAIT:
        //calculate buf size in output_q
        len=0;
        for(i=0;i<tcb.output_q.size();i++) {
          TCPBuffer buf=(TCPBuffer)tcb.output_q.get(i);
          len+=buf.len;
        }
        tcb.userbuf_len=buf_len;
        if(len>0) { //notify user if got data
          comp.getSim().enqueue(new SimEvent(MY_RECEIVE_BUF,this,this,comp.getSim().now(),tcb));
        }
        else
          return false;
        break;

      default:
        return false;
    }

    return true;
  }

  public boolean close(Object k) {
    TCB tcb=(TCB)tcbs.get(k);
    if(tcb==null) return false; //no connection yet

    switch(tcb.status.getValue()) {
      case STAT_LISTEN:
        tcb.status.setValue(STAT_CLOSED);
        tcbs.remove(k);
        provider.statusChanged();
        return true;
      case STAT_SYN_SENT:
        tcb.retrans_timer.stop(); //for safety
        tcb.status.setValue(STAT_CLOSED);
        tcbs.remove(k);
        provider.statusChanged();
        return true;
      case STAT_SYN_RCVD:
        if(tcb.input_q.isEmpty()) {
          send_fin(tcb);
          tcb.status.setValue(STAT_FIN_WAIT1);
          provider.statusChanged();
        }
        else {
          tcb.userclosing=true;
        }
        return true;
      case STAT_ESTABLISHED:
        if(tcb.input_q.isEmpty()) {
          send_fin(tcb);
        }
        else {
          tcb.userclosing=true;
        }
        tcb.status.setValue(STAT_FIN_WAIT1);
        provider.statusChanged();
        return true;
      case STAT_CLOSE_WAIT:
        if(tcb.input_q.isEmpty()) {
          send_fin(tcb);
          //the state-change below is now in send_fin()
          //tcb.status.setValue(STAT_CLOSING);
          //provider.statusChanged(); //notify provider
        }
        else {
          tcb.userclosing=true;
        }
        return true;
    }

    return false;
  }

  public boolean abort(Object k) {
    TCB tcb=(TCB)tcbs.get(k);
    if(tcb==null) return false; //no connection yet

    switch(tcb.status.getValue()) {
      case STAT_SYN_RCVD:
      case STAT_ESTABLISHED:
      case STAT_FIN_WAIT1:
      case STAT_FIN_WAIT2:
      case STAT_CLOSE_WAIT:
        TCPSegment seg=new TCPSegment();
        seg.sourceport=tcb.key.source_port;
        seg.destport=tcb.key.dest_port;
        seg.seg_seq=tcb.snd_nxt.getValue();
        seg.rst=true;
        seg.seg_len=0;
        IPPacket packet=new IPPacket();
        packet.sourceIP=tcb.key.source_ip;
        packet.destIP=tcb.key.dest_ip;
        packet.protocol=IPPacket.PRO_TCP;
        packet.len=46;
        packet.payload=seg;
        send_ip(packet);

        tcb.retrans_timer.stop(); //for safety
        tcb.timewait_timer.stop(); //for safety
        tcb.status.setValue(STAT_CLOSED);
        tcbs.remove(k);
        provider.statusChanged();
        return true;

      default:
        tcb.retrans_timer.stop(); //for safety
        tcb.timewait_timer.stop(); //for safety
        tcb.status.setValue(STAT_CLOSED);
        tcbs.remove(k);
        provider.statusChanged();
    }

    return true;
  }

//check whether a source port is used in any existing connections
  public boolean isSrcportInUse(int srcport) {
    TCB [] tcbarr=(TCB [])tcbs.values().toArray(new TCB[0]);
    for(int i=0;i<tcbarr.length;i++) {
      if(tcbarr[i].key.source_port == srcport) return true;
    }
    return false;
  }

  public int connectionCount() {
    return tcbs.size();
  }
  public int queryTCB_srcip(int index) {
    if(index>=tcbs.size()) return 0;

    TCB [] tcbarr=(TCB [])tcbs.values().toArray(new TCB[0]);
    return tcbarr[index].key.source_ip;
  }
  public int queryTCB_srcport(int index) {
    if(index>=tcbs.size()) return 0;

    TCB [] tcbarr=(TCB [])tcbs.values().toArray(new TCB[0]);
    return tcbarr[index].key.source_port;
  }
  public int queryTCB_destip(int index) {
    if(index>=tcbs.size()) return 0;

    TCB [] tcbarr=(TCB [])tcbs.values().toArray(new TCB[0]);
    return tcbarr[index].key.dest_ip;
  }
  public int queryTCB_destport(int index) {
    if(index>=tcbs.size()) return 0;

    TCB [] tcbarr=(TCB [])tcbs.values().toArray(new TCB[0]);
    return tcbarr[index].key.dest_port;
  }
  public String queryTCBStatus(int index) {
    if(index>=tcbs.size()) return null;

    TCB [] tcbarr=(TCB [])tcbs.values().toArray(new TCB[0]);
    return tcbarr[index].status.getString();
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -