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

📄 datareceive.java

📁 简易聊天工具
💻 JAVA
字号:

import java.io.*; 
import java.awt.*; 
import java.net.*; 
import java.awt.event.*; 
import java.util.Vector; 
import javax.swing.*;
import javax.media.*; 
import javax.media.rtp.*; 
import javax.media.rtp.event.*; 
import javax.media.rtp.rtcp.*; 
import javax.media.protocol.*; 
import javax.media.protocol.DataSource; 
import javax.media.format.AudioFormat; 
import javax.media.format.VideoFormat; 
import javax.media.Format; 
import javax.media.format.FormatChangeEvent; 
import javax.media.control.BufferControl; 
// 接收RTP传输数据的类
public class DataReceive implements ReceiveStreamListener, SessionListener, ControllerListener 
{ 
	String sessions[] = null;                  // RTP会话字符串数组
	RTPManager mgrs[] = null; 					// RTP管理器数组
	Vector playerPanels = null; 				// 管理播放器面板的向量
	PlayerWindow pw = null;
	boolean dataReceived = false; 				// 是否接收到数据的标志
	Object dataSync = new Object();  			// 同步对象
	public DataReceive(String sessions[])        // 构造函数
	{ 
		this.sessions = sessions; 
	} 
	protected String initialize(int xg, int yg) 				// 初始化RTP会话,准备接收数据
	{ 
		try 
		{ 
			pw = new PlayerWindow(xg, yg);
			InetAddress ipAddr; 
			SessionAddress localAddr = new SessionAddress(); 
			SessionAddress destAddr; 
			mgrs = new RTPManager[sessions.length]; // 为每一个RTP会话建立一个管理器
			playerPanels = new Vector(); 
			SessionLabel session; 
			for (int i = 0; i < sessions.length; i++) // 对每一个RTP会话
			{ 
				try 
				{ 
					session = new SessionLabel(sessions[i]); // 解析RTP会话地址
				} catch (IllegalArgumentException e) 
				{ 
					return "Failed to parse the session"; 
				}
		  
				System.err.println("  - Open RTP session for: addr: " + session.addr + " port: " + session.port);

				mgrs[i] = (RTPManager) RTPManager.newInstance(); 	// 为每一个RTP会话产生一个RTP管理器
				mgrs[i].addSessionListener(this); 					// 添加会话监听
				mgrs[i].addReceiveStreamListener(this);	 			// 添加接收到数据的监听
				ipAddr = InetAddress.getByName(session.addr); 
		
				if( ipAddr.isMulticastAddress()) 					// 对于组播,本地和目的地的IP地址相同,均采用组播地址
				{ 
					localAddr= new SessionAddress( ipAddr, session.port); 
					destAddr = new SessionAddress( ipAddr, session.port); 
				} 
				else 
				{ 
					localAddr= new SessionAddress( InetAddress.getLocalHost(), session.port);	// 用本机IP地址和端口号构造源会话地址 
					destAddr = new SessionAddress( ipAddr, session.port); 						// 用目的机(发送端)的IP地址和端口号构造目的会话地址
				}
			
				mgrs[i].initialize( localAddr); 				// 将本机会话地址给RTP管理器
				
				BufferControl bc = (BufferControl)mgrs[i].getControl("javax.media.control.BufferControl"); 
				
				if (bc != null) bc.setBufferLength(350); 		// 设置缓冲区大小
				
				mgrs[i].addTarget(destAddr); 					 // 加入目的会话地址
				
			} 
		} catch (Exception e)
		{ 
			return "Cannot create the RTP Session" + "<<" + e.getMessage() + ">>"; 
		} 
		// 等待数据到达
		long then = System.currentTimeMillis(); 
		long waitingPeriod = 60000; 
		try
		{ 
			synchronized (dataSync) 
			{ 
				while (!dataReceived && System.currentTimeMillis() - then < waitingPeriod)  // 等待上面所设定的时间
				{ 
					dataSync.wait(1000); 				
				} 
			} 
		} catch (Exception e) {} 
		if (!dataReceived) 
		{ 													// 在设定的时间内没有等到数据
			close(); 
			return "No RTP data was received"; 		
		} 
		pw.setVisible(true);
		return "success"; 
	} 
	 // 判断数据是否接收完成
	public boolean isDone() 	
	{ 
		return playerPanels.size() == 0; 
	} 
		// 关闭播放器和会话管理器
	protected void close() 
	{ 
		for (int i = 0; i < playerPanels.size(); i++) 
		{ 
			try 
			{ 
				((PlayerPanel)playerPanels.elementAt(i)).close(); 
			} catch (Exception e) {} 
		} 
		playerPanels.removeAllElements(); 
		pw.dispose();
		// 关闭RTP会话
		for (int i = 0; i < mgrs.length; i++) 
		{ 
			if (mgrs[i] != null) 
			{ 
				mgrs[i].removeTargets( "Closing session from AVReceive2"); 
				mgrs[i].dispose(); 
				mgrs[i] = null; 
			} 
		} 
	} 
	// 通过播放器查找播放面板
	PlayerPanel find(Player p) 
	{ 
		for (int i = 0; i < playerPanels.size(); i++) 
		{ 
			PlayerPanel pp = (PlayerPanel)playerPanels.elementAt(i); 
			if (pp.player == p) return pp; 
		} 
		return null; 
	} 
		// 通过接收数据流查找播放面板
	PlayerPanel find(ReceiveStream strm) 
	{ 
		for (int i = 0; i < playerPanels.size(); i++) 
		{ 
			PlayerPanel pp = (PlayerPanel)playerPanels.elementAt(i); 
			if (pp.stream == strm) return pp; 
		} 
		return null; 
	} 
  /***************************************************************
  * 下面这个函数实现了 ReceiveStreamListener 接口
  ****************************************************************/

		public synchronized void update( ReceiveStreamEvent evt) 
		{ 
			RTPManager mgr = (RTPManager)evt.getSource(); 
			Participant participant = evt.getParticipant(); 
			ReceiveStream stream = evt.getReceiveStream(); 
			if (evt instanceof NewReceiveStreamEvent) 
			{ 
				try 
				{ 
					stream = ((NewReceiveStreamEvent)evt).getReceiveStream(); 
					DataSource ds = stream.getDataSource();  
					Player p = javax.media.Manager.createPlayer(ds); 	// 通过数据源构造一个媒体播放器
					if (p == null) return; 
					p.addControllerListener(this); 
					p.realize(); 
					PlayerPanel pp = new PlayerPanel(p, stream); 
					playerPanels.addElement(pp); 
				// 通知initialize()函数中的等待过程:已经接收到了一个新数据流
					synchronized (dataSync) 
					{ 
						dataReceived = true; 
						dataSync.notifyAll(); 
					} 
				} catch (Exception e) 
				{ 
					return; 
				} 
			} 
			else if (evt instanceof StreamMappedEvent) 
			{ 
				if (stream != null && stream.getDataSource() != null) 
				{ 
					DataSource ds = stream.getDataSource(); 
					RTPControl ctl = (RTPControl)ds.getControl("javax.media.rtp.RTPControl"); 
					System.err.println(" - The previously unidentified stream "); 
					if (ctl != null) System.err.println(" " + ctl.getFormat()); 
					System.err.println(" had now been identified as sent by: " + participant.getCNAME()); 
				} 
			} else if (evt instanceof ByeEvent) 
			{ 
				System.err.println(" - Got \"bye\" from: " + participant.getCNAME()); 
				PlayerPanel pp = find(stream); 
				if (pp != null) 
				{ 
					pp.close(); 
					playerPanels.removeElement(pp); 
				} 
			} 
		} 
 /***************************************************************
  * 下面这个函数实现了 SessionListener 接口
  ****************************************************************/

  		public synchronized void update(SessionEvent evt) 
  		{
    		if (evt instanceof NewParticipantEvent) 
    		{
      			Participant p = ((NewParticipantEvent)evt).getParticipant();
      			System.err.println("  - A new participant had just joined: " + p.getCNAME());
    		}
  		}
  /***************************************************************
  * 下面这个函数实现了 ControllerListener 接口
  ****************************************************************/

		public synchronized void controllerUpdate(ControllerEvent ce) 
		{ 
			Player p = (Player)ce.getSourceController(); 		// 得到事件源
			if (p == null) return; 
			if (ce instanceof RealizeCompleteEvent) 			// 播放器实现完成
			{ 
				PlayerPanel pp = find(p); 
				if (pp == null) 
				{ 
					System.err.println("Internal error!"); 
				} 
				pp.initialize(); 
				pw.add(pp); 
				p.start(); 
			} 
			if (ce instanceof ControllerErrorEvent) 
			{ 
				p.removeControllerListener(this); 
				PlayerPanel pp = find(p); 
				if (pp != null) 
				{ 
					pp.close(); 
					playerPanels.removeElement(pp); 
				} 
			} 
		} 
		// 解析会话地址的类
  	class SessionLabel 
  	{
    	public String addr = null;
    	public int port;
    	SessionLabel(String session) throws IllegalArgumentException 
    	{
      		int off;
      		String portStr = null;
      		if (session != null && session.length() > 0) 
      		{
        		while (session.length() > 1 && session.charAt(0) == '/') // 去掉字符串前面的“/”
        		{
          			session = session.substring(1);
          		}
        		off = session.indexOf('/');      						// 找到字符串中“/”的位置
        		if (off == -1) 
        		{                 										// 如果字符串中没有找到“/”
          			if (!session.equals(""))       						// 字符串不为空
          			{
            			addr = session;              					// 字符串值作为IP地址
            		}
        		}
        		else 
        		{                           							// 如果字符串中找到了“/”,说明字符串中还存在端口号
          			addr = session.substring(0, off);
          			session = session.substring(off + 1);   			// 得到第一个“/”后面的子串
          			off = session.indexOf('/');    						// 找到子串中“/”的位置
          			if (off == -1) 
          			{               									// 如果子串中没有找到“/”
            			if (!session.equals(""))
            			{
              				portStr = session; 
              			}        										// 字符串值作为端口号
          			}
        		}
      		}
      		if (addr == null)            								// 如果没有给出IP地址,则报错
        	throw new IllegalArgumentException();
      		if (portStr != null) 
      		{       													// 如果给出了端口号,则将其转化为整型数
        		try {
          			Integer integer = Integer.valueOf(portStr);
          			if (integer != null)
            		port = integer.intValue();
        		}
        		catch (Throwable t) 
        		{
          			throw new IllegalArgumentException();
        		}
      		}
      		else                        	// 如果没有给出端口号,则报错
      		{
        		throw new IllegalArgumentException();
        	}
    	}
  	}
  		// 播放窗口类
		class PlayerWindow extends JFrame 
		{ 
			int xGrid;						//横向网格数
			int yGrid;						//竖向网格数
			JPanel panel = null;			//添加播放器组件面板的面板
			public PlayerWindow(int xg, int yg)
			{
				xGrid = xg;
				yGrid = yg;
				setTitle("网络会议");
				Container contentPane = getContentPane();
				panel = new JPanel();
				panel.setLayout(new GridLayout(xGrid, yGrid));
				contentPane.add(panel);	
			}
			public void addPanel(PlayerPanel pp)	//添加播放器组件面板的方法
			{
					panel.add(pp);
					this.add(panel);	
			}
		} 
		// 播放器面板类
		class PlayerPanel extends Panel 
		{ 
			Player player; 			// 播放器对象
			ReceiveStream stream;  	// 接收数据流对象
			Component vc, cc; 
			// 构造函数
			PlayerPanel(Player p, ReceiveStream strm) 
			{ 
				player = p; 
				stream = strm; 
			}
			// 初始化 
			public void initialize() 
			{ 
				setLayout(new BorderLayout()); 
				if ((vc = player.getVisualComponent()) != null) 
				{
					add("Center", vc); 
				}
				if ((cc = player.getControlPanelComponent()) != null) 
				{
					add("South", cc); 
				}
			}
			 // 关闭播放器
			public void close() 
			{ 
				player.close(); 
				setVisible(false); 
				this.close();
			} 
		} 
}
	// end of DataReceive 

⌨️ 快捷键说明

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