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

📄 rdtunitmanager.java

📁 本程序可在局域网内实现聊天、传送文件功能
💻 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 + -