📄 tcp.java
字号:
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 + -