tcp/ipプロトコルにおけるメッセージ伝送によるフレームメッセージの動作

3130 ワード

インターフェイス:Framer.java:
package com.tcpip;

import java.io.IOException;
import java.io.OutputStream;

/**
 * tcp/ip              
 * @author 
 *
 */
public interface Framer {
	/**
	 *           
	 * @param message    
	 * @param out	   
	 * @throws IOException
	 */
	void frameMsg(byte[] message,OutputStream out) throws IOException;
	
	/**
	 *        ,       
	 * @return
	 * @throws IOException
	 */
	byte[] nextMsg() throws IOException;

}

次の2つのフレーム化方法を示します.
package com.tcpip;

import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 *           
 * @author 
 *
 */
public class DelimFramer implements Framer {
	private InputStream in;
	private static final byte DELIMITER= '
'; public DelimFramer(InputStream in){ this.in = in; } /* * , * @see com.tcpip.Framer#frameMsg(byte[], java.io.OutputStream) */ @Override public void frameMsg(byte[] message, OutputStream out) throws IOException { for(byte b:message){ if(b==DELIMITER){ throw new IOException("Message contains delimiter"); } } out.write(message); out.write(DELIMITER); out.flush(); } /* * * @see com.tcpip.Framer#nextMsg() */ @Override public byte[] nextMsg() throws IOException { ByteArrayOutputStream messageBuffer = new ByteArrayOutputStream(); int nextByte ; while((nextByte=in.read())!=DELIMITER){ if(nextByte == -1){ if(messageBuffer.size()==0){ return null; }else{ throw new EOFException("Non-empty message without delimiter"); } } messageBuffer.write(nextByte); } return messageBuffer.toByteArray(); } }
package com.tcpip;

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 *           
 * @author 
 *
 */
public class LengthFramer implements Framer {
	public static final int MAXMESSAGELENGTH = 65535;
	public static final int BYTEMASK = 0xff;
	public static final int SHORTMASK = 0xffff;
	public static final int BYTESHIFT = 8;
	private DataInputStream in;
	
	public LengthFramer(InputStream in) throws IOException{
		this.in = new DataInputStream(in);
	}

	/*
	 *          ,               ,       
	 * @see com.tcpip.Framer#frameMsg(byte[], java.io.OutputStream)
	 */
	@Override
	public void frameMsg(byte[] message, OutputStream out) throws IOException {
		if(message.length>MAXMESSAGELENGTH){
			throw new IOException("message too long");
		}
		out.write((message.length>>BYTESHIFT)&BYTEMASK);
		out.write(message.length&BYTEMASK);
		out.write(message);
		out.flush();
	}

	/*
	 *        
	 * @see com.tcpip.Framer#nextMsg()
	 */
	@Override
	public byte[] nextMsg() throws IOException {
		int length;
		try{
			//      
			length = in.readUnsignedShort();
		}catch(EOFException e){
			return null;
		}
		
		byte[] msg = new byte[length];
		//     ,              
		in.readFully(msg);
		
		return msg;
	}

}