packet.java

来自「java语言开发的P2P流媒体系统」· Java 代码 · 共 447 行

JAVA
447
字号
/* Stream-2-Stream - Peer to peer television and radio
 * October 13, 2005 - This file has been modified from the original P2P-Radio source
 * Project homepage: http://s2s.sourceforge.net/
 * Copyright (C) 2005-2006 Jason Hooks
 */

/* 
 * P2P-Radio - Peer to peer streaming system
 * Project homepage: http://p2p-radio.sourceforge.net/
 * Copyright (C) 2003-2004 Michael Kaufmann <hallo@michael-kaufmann.ch>
 * 
 * ---------------------------------------------------------------------------
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * ---------------------------------------------------------------------------
 */

package p2pradio.packets;

import p2pradio.Messages;
import java.io.*;

public abstract class Packet
{
	// Beta-Versionen: 0
	// public static final byte[] PACKET_SIGNATURE = {'P', '2', 'P', 'R'};
	
	// Nachrichten-Typen
	
	public static final byte EMPTY = 0; // Nur Empfangen
	
	// Messages
	public static final byte JOIN = 50; // Version 1.x: 1;
	public static final byte OK = 2;
	public static final byte OK_USE_MONITOR = 3; // OK-Paket mit Monitoradresse
	public static final byte REDIRECT = 4;
	public static final byte FREELOADER_REPORT = 5;
	public static final byte PUBLIC_KEY_REQUEST = 6;
	public static final byte PUBLIC_KEY = 7;
	public static final byte MONITOR_NOTIFICATION = 8; // Nachricht an Monitor
	public static final byte MONITOR_COMMAND = 9; // Befehl vom Monitor
	public static final byte TIME = 21;
	public static final byte CONNECT = 23;
	public static final byte ACCEPT = 24;
	public static final byte DENY = 25;
	public static final byte REQUEST = 22;
	public static final byte UDP_UPDATE = 27;
	
	// Stream
	public static final byte IDENTIFICATION = 10; // Zu Beginn eines TCP-Stroms
	public static final byte IDENTIFICATION_SEQNR = 11; // Mit Wiederaufnahme-SeqNr
	public static final byte LEAVE = 12; // F黵 den Zulieferer
	public static final byte LEAVE_AND_REDIRECT = 13; // F黵 die Kinder
	public static final byte FREELOADER_REDIRECT = 14;
	public static final byte STANDBY = 15; // Der eigene Zulieferer hat gewechselt, die Kinder sollen nicht gleich wechseln
	public static final byte DATA = 16;
	public static final byte METADATA = 17;
	public static final byte HEADER = 18;
	public static final byte UDP_STREAM = 26; 
	
	// Stream and Messages
	public static final byte PING = 19;
	public static final byte PONG = 20;
	

	// Beim Lesen: L鋘ge des gelesenen Paketteils
	// Beim Schreiben: L鋘ge des geschriebenen Paketteils
	protected int offset;
	
	// Beim Lesen: Exakte L鋘ge des Inhalts
	// Beim Schreiben: Maximale L鋘ge des Inhalts
	protected int contentLength;
	
	// Sowohl "content" als auch die 黚rigen Felder m黶sen immer
	// korrekt ausgef黮lt sein
	protected byte[] content;
	 
	// "Lokale" Variablen
	private byte packetType;
	
	
	protected Packet(byte packetType, byte content[])
	{	
		// Vorne beginnen
		offset = 0;
		
		this.content = content;
		this.contentLength = content.length;
		
		/*
		checkBytesLeft(4);
		content[offset++] = PACKET_SIGNATURE[0];
		content[offset++] = PACKET_SIGNATURE[1];
		content[offset++] = PACKET_SIGNATURE[2];
		content[offset++] = PACKET_SIGNATURE[3];
		*/
			
		checkBytesLeft(1);  //Check if there is 1 byte left
		
		this.packetType = packetType;
		
		content[offset++] = packetType;
	}
	
	protected Packet(byte content[], int contentLength)
	{
		if (contentLength > content.length)
		{
			throw new IllegalArgumentException(Messages.getString("Packet.WRONG_PACKET_SIZE")); //$NON-NLS-1$
		}
		
		// Vorne beginnen
		offset = 0;
		
		this.content = content;
		this.contentLength = contentLength;
		
		/*
		checkBytesLeft(4);
		if ((content[offset+0] != PACKET_SIGNATURE[0])
		  || (content[offset+1] != PACKET_SIGNATURE[1])
		  || (content[offset+2] != PACKET_SIGNATURE[2])
		  || (content[offset+3] != PACKET_SIGNATURE[3]))
		{
			throw new IllegalArgumentException(Messages.getString("Packet.INVALID_PACKET_HEADER")); //$NON-NLS-1$
		}
		offset += 4;
		*/
		
		checkBytesLeft(1);
		
		packetType = content[offset++]; 
  }
  	
	// Wieviele Bytes gibt es noch zu lesen bzw. schreiben?
	protected void checkBytesLeft(int bytes)
	{
		if ((bytes < 0) || (contentLength - offset < bytes))
		{
			//System.out.println("bytes:" + bytes);
			throw new IllegalArgumentException(Messages.getString("Packet.PACKET_ERROR_WHILE_READING_OR_WRITING")); //$NON-NLS-1$
		}
		
	}
	
	// Liefert das ganze Paket, nicht nur den lokalen Teil
	public byte[] getContent()
	{
		return content;
	}
	
	public int getContentLength()
	{
		return offset;
	}
	
	public byte getType()
	{
 		return packetType;
 	}
 	
 	protected String getTypeString()
 	{
 		return String.valueOf(getType());
 	}
 	
 	protected static int getMaxLength()
 	{
 		return 1;
 	}
 	
 	public void send(DataOutputStream output) throws IOException
 	{
 		output.writeInt(getContentLength());
 		output.write(getContent(), 0, getContentLength());
 		output.flush();
 	}
 	protected void writeBoolean(boolean value)
 	{
 		checkBytesLeft(1);
 		ByteArrayOutputStream byte_out = new ByteArrayOutputStream (); 
 		DataOutputStream data_out = new DataOutputStream (byte_out); 
 		try {
			data_out.writeBoolean(value);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		byte[] bbool = byte_out.toByteArray();
		System.arraycopy(bbool, 0, content, offset, 1);
		offset += 1;
 	}
 	protected boolean readBoolean()
 	{
 		checkBytesLeft(1);
 		ByteArrayInputStream byte_in = new ByteArrayInputStream (content, offset, 1);
 		DataInputStream data_in = new DataInputStream (byte_in);
 		boolean b = false;
 		try {
			b = data_in.readBoolean();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		offset += 1;
		return b;
 	}
 	protected void writeFloat(float value)
 	{
 		checkBytesLeft(2);
 		
 		ByteArrayOutputStream byte_out = new ByteArrayOutputStream (); 
 		DataOutputStream data_out = new DataOutputStream (byte_out); 
 		try {
			data_out.writeFloat(value);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		byte[] bfloat = byte_out.toByteArray();
		
		System.arraycopy(bfloat, 0, content, offset, 4);

		offset += 4;
 	}
 	protected float readFloat()
 	{
 		checkBytesLeft(4);
 		ByteArrayInputStream byte_in = new ByteArrayInputStream (content, offset, 4);
 		DataInputStream data_in = new DataInputStream (byte_in);
 		float f = 0.0F;
 		try {
			f = data_in.readFloat();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		offset += 4;
		return f;
 	}
 	protected void writeShort(short value)
 	{
 		checkBytesLeft(2);
		
		// Siehe DataOutputStream.java
		content[offset + 0] = (byte)((value >>> 8) & 0xFF);
		content[offset + 1] = (byte)((value >>> 0) & 0xFF);
			
		offset += 2;
 	}
 	protected short readShort()
	{
		checkBytesLeft(2);
		
		// Siehe DataInputStream.java
		int ch1 = (content[offset + 0] & 0xff);
		int ch2 = (content[offset + 1] & 0xff);

		offset += 2;
		
		return (short) ((ch1 << 8) + (ch2 << 0));
	}
 	protected void writeInt(int value)
	{
		checkBytesLeft(4);
		
		// Siehe DataOutputStream.java
		content[offset + 0] = (byte)((value >>> 24) & 0xFF);
		content[offset + 1] = (byte)((value >>> 16) & 0xFF);
		content[offset + 2] = (byte)((value >>>  8) & 0xFF);
		content[offset + 3] = (byte)((value >>>  0) & 0xFF);
			
		offset += 4;
	}
	
	protected int readInt()
	{
		checkBytesLeft(4);
		
		// Siehe DataInputStream.java
		int ch1 = (content[offset + 0] & 0xff);
		int ch2 = (content[offset + 1] & 0xff);
		int ch3 = (content[offset + 2] & 0xff);
		int ch4 = (content[offset + 3] & 0xff);

		offset += 4;
		
		return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
	}

	protected void writeLong(long value)
	{
		checkBytesLeft(8);
	
		// Siehe DataOutputStream.java
		content[offset + 0] = (byte)((value >>> 56) & 0xFF);
		content[offset + 1] = (byte)((value >>> 48) & 0xFF);
		content[offset + 2] = (byte)((value >>> 40) & 0xFF);
		content[offset + 3] = (byte)((value >>> 32) & 0xFF);
		content[offset + 4] = (byte)((value >>> 24) & 0xFF);
		content[offset + 5] = (byte)((value >>> 16) & 0xFF);
		content[offset + 6] = (byte)((value >>>  8) & 0xFF);
		content[offset + 7] = (byte)((value >>>  0) & 0xFF);
		
		offset += 8;
	}

	protected long readLong()
	{
		checkBytesLeft(8);
	
		// Siehe DataInputStream.java
		long part1 = readInt();
		int part2 = readInt();
		
		return (part1 << 32) + (part2 & 0xFFFFFFFFL);	
	}
	
	protected byte[] readByteArray()
	{
		// L鋘ge des Byte-Arrays lesen
		int length = readInt();
		
		checkBytesLeft(length);
		
		// Byte-Array kopieren
		byte[] byteArray = new byte[length];
		System.arraycopy(content, offset, byteArray, 0, length);
		
		offset += length;
		
		return byteArray;
	}
	protected byte[] readBytes(int length)
	{
		checkBytesLeft(length);
		
		// Byte-Array kopieren
		byte[] byteArray = new byte[length];
		System.arraycopy(content, offset, byteArray, 0, length);
		
		offset += length;
		
		return byteArray;
	}
	protected byte readByte()
	{
		return readBytes(1)[0];
	}
	protected void writeByte(byte b)
	{
		byte[] array = {b};
		writeBytes(array);
	}
	
	protected void writeByteArray(byte[] byteArray)
	{
		writeByteArray(byteArray, 0, byteArray.length);
	}
	
	protected void writeByteArray(byte[] byteArray, int arrayOffset, int length)
	{
		// L鋘ge des Byte-Arrays speichern
		writeInt(length);
	
		checkBytesLeft(length);
	
		// Byte-Array kopieren
		System.arraycopy(byteArray, arrayOffset, content, offset, length);
		offset += length;
	}
	protected void writeBytes(byte[] byteArray)
	{
		writeBytes(byteArray, 0, byteArray.length);
	}
	protected void writeBytes(byte[] byteArray, int arrayOffset, int length)
	{
	
		checkBytesLeft(length);
	
		// Byte-Array kopieren
		System.arraycopy(byteArray, arrayOffset, content, offset, length);
		offset += length;
	}
 	
 	public String toString()
 	{
 		
		//int length = getContentLength();
 		int length = content.length;
 		String result = getTypeString() + " [(LENGTH=" + length + ")"; //$NON-NLS-1$
 		
 		for (int i=0; i < length; i++)
 		{
 			String hex = Integer.toHexString(getContent()[i] & 0xff);
 			
 			if (hex.length() == 1)
 			{
 				hex = "0" + hex; //$NON-NLS-1$
 			}
 			
 			result = result + hex;
 			
 			if (i == offset - 1)
 			{
 				result = result + " *"; //$NON-NLS-1$
 			}
 			
			if (i != length - 1)
			{
				result = result + " ";  //$NON-NLS-1$
			} 			
 		}
 			
 		result = result + "]"; //$NON-NLS-1$
 		
 		return result;
 	}
 	
 	/*
 	public static void reportUDPSizes()
 	{
 		// Gr鰏sen aller UDP-Pakete ausgeben
 		// (ohne das PublicKey-Paket)
 		System.out.println(JoinPacket.getMaxLength());
		System.out.println(OKPacket.getMaxLength());
		System.out.println(OKUseMonitorPacket.getMaxLength());
		System.out.println(RedirectPacket.getMaxLength());
		System.out.println(FreeloaderReportPacket.getMaxLength());
		System.out.println(PublicKeyRequestPacket.getMaxLength());
		System.out.println(MonitorNotificationPacket.getMaxLength());
		System.out.println(MonitorCommandPacket.getMaxLength());
 	}
 	*/
}

⌨️ 快捷键说明

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