📄 rdtunitmanager.java
字号:
package org.tuna.net.rdt;
import java.net.*;
import java.util.*;
class RdtUnitManager implements DataSort
{
private RdtServer rdtServer;
private ArrayList<RdtUnit> rdtTeam;
private final int MAX_AMOUNT = 10;
private boolean rdtAccept;
public RdtUnitManager(RdtServer rs)
{
rdtServer = rs;
rdtTeam = new ArrayList<RdtUnit>();
}
/**
* 标识是否对客户端的第一次握手作出响应
* @param b 标识信息
*/
public void acceptable(boolean b)
{
rdtAccept = b;
}
/**
* 处理第一次握手
* @param fst 接收了第一次握手信息的PKT
*/
public void first(DatagramPacket fst)
{
if ( !rdtAccept ) //应用程序并没有调用accept,则对第一次握手不予应答
return;
if ( count() >= MAX_AMOUNT )
return;
if ( isRdtUnitExist(fst.getAddress(), fst.getPort()) ) //如果RDT已存在,则没必要再生成一个
return;
byte[] data = fst.getData();
int cltNum = (int)data[1]; //客户端分组起始序号
int srvNum = (int)(Math.random() * 128); //服务端分组起始序号
RdtUnit newRdt =
new RdtUnit(fst.getAddress(), fst.getPort(), rdtServer.srvskt);
rdtTeam.add(newRdt); //新的RDT单元生成了
//发回第二次握手
byte[] sec = new byte[] {PKT_SH_2, (byte)srvNum};
try
{
DatagramPacket secpkt = new DatagramPacket(sec, sec.length, fst.getAddress(), fst.getPort());
rdtServer.srvskt.send(secpkt);
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* 接收到客户端第三次握手后的操作
* 主要是将accept()唤醒,使之返回
* 生成的RDT单元
* @param thd 第三次握手的PKT
*/
public void third(DatagramPacket thd)
{
if ( !isRdtUnitExist(thd.getAddress(), thd.getPort()) ) //若所求的RDT不存在
return;
rdtServer.newUnit = getCertain(thd.getAddress(), thd.getPort());
synchronized(rdtServer){
try{
rdtServer.notify();
}
catch(Exception e){}
}
}
/**
* 得到当前RDT单元的数量
* @return rdtTeam的长度,即RDT单元的个数
*/
public int count()
{
return rdtTeam.size();
}
/**
* 查看当前是否存在与指定的地址和端口的进程通信的RDT单元
* @param addr 远程地址
* @param port 远程端口
*/
public boolean isRdtUnitExist(InetAddress addr, int port)
{
boolean exist = false;
for(int i = 0; i < count(); i++)
if ( rdtTeam.get(i).getAddress().getHostAddress().equals(addr.getHostAddress()) && rdtTeam.get(i).getPort() == port )
{
exist = true;
break;
}
return exist;
}
/**
* 得到与特定的远程主机进程通信的RDT
* @param addr 远程地址
* @param port 远程端口
*/
private RdtUnit getCertain(InetAddress addr, int port)
{
for(int i = 0; i < count(); i++)
if (rdtTeam.get(i).getAddress().getHostAddress().equals(addr.getHostAddress()) && rdtTeam.get(i).getPort() == port)
return rdtTeam.get(i);
return null;
}
/**
* 移除指定的RDT
* @param addr 远程地址
* @param port 远程端口
*/
private void remove(InetAddress addr, int port)
{
for(int i = 0; i < count(); i++)
if (rdtTeam.get(i).getAddress().getHostAddress().equals(addr.getHostAddress()) && rdtTeam.get(i).getPort() == port)
rdtTeam.remove(i);
}
/**
* 接收到来自客户端的数据并将之分发给指定的RDT单元
* @param data 包含数据的UDP分组
*/
public void newData(DatagramPacket pkt)
{
RdtUnit ru = getCertain(pkt.getAddress(), pkt.getPort());
if (ru == null) return;
byte[] data = pkt.getData();
ru.receiveThread.setRcvByte(data);
synchronized(ru.receiveThread){
try{
ru.receiveThread.notify();
}
catch(Exception e){}
}
if ( data[0] == PKT_SHUT ){
remove(pkt.getAddress(), pkt.getPort());
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -