Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

《Java TCP/IP Socket编程》读书笔记(5)

$
0
0

                             
                             
3.1 信息编码

3.1.1 基本整型

TCPUDP套接字使我们能够发送和接收字节序列(数组),及范围在0~255之间的整数。

下面考虑发送一个byte型整数、一个short型整数、一个int型整数和一个long型整数,这四个类型在Java中依次用1248个字节进行标示。



1. 发送顺序,可以由低位到高位发送(little-endian),也可以由高位到低位发送(big-endian)

考虑厂整型123456787654321L,其16禁止标示形式为0x0000704885F926B

1.如果使用little-endian顺序传输这个整数,其字节的十进制数值序列为:


如果使用big-endian顺序传输这个整数,则其字节的十进制数值序列为:


对于任何一个多字节的整数,发送和接收方对于使用哪种传输顺序必须达成一致。

2. 发送者和接收者对于发送的数值是有符号的还是无符号的也要达成共识。Java中的四种基本整数类型都是有符号的。

下面的代码中演示了发送和接收整数。

package com.suifeng.tcpip.chapter3;

/**
 * 基本整型的发送和接收(模拟)
 * 
 * @author Administrator
 * 
 */
public class BruteForceCoding
{
	// 要传输的参数
	private static final byte byteVal = 101;
	private static final short shortVale = 10001;
	private static final int intVal = 100000001;
	private static final long longVal = 1000000000001L;

	// 每种类型所占的位数
	private static final int BSIZE = Byte.SIZE / Byte.SIZE;
	private static final int SSIZE = Short.SIZE / Byte.SIZE;
	private static final int ISIZE = Integer.SIZE / Byte.SIZE;
	private static final int LSIZE = Long.SIZE / Byte.SIZE;

	// 淹没
	private final static int BYTEMASK = 0xff;

	/**
	 * 将要传输的二进制数据打印出来
	 * 
	 * @param bArray
	 *            二进制数组
	 * @return
	 */
	public static String byteArray2DecimalString(byte[] bArray)
	{
		StringBuilder rbtn = new StringBuilder(256);

		for (byte b : bArray)
		{
			rbtn.append(b & BYTEMASK).append(" ");
		}

		return rbtn.toString();
	}

	/**
	 * 将要发送的整数转换成二进制数组
	 * 
	 * @param dst
	 *            目的二进制数组
	 * @param val
	 *            要传输的整数
	 * @param offset
	 *            位移
	 * @param size
	 *            所占字节数
	 * @return
	 */
	public static int encodeIntBigEndian(byte[] dst, long val, int offset,
			int size)
	{
		for (int i = 0; i < size; i++)
		{
			dst[offset++] = (byte) (val >> (size - i - 1) * Byte.SIZE);
		}

		return offset;
	}

	/**
	 * 解析编码后的数据
	 * 
	 * @param val
	 *            加密后的二进制数组
	 * @param offset
	 *            位移
	 * @param size
	 *            大小
	 * @return
	 */
	public static long decodeIntBigEndian(byte[] val, int offset, int size)
	{
		long rbtn = 0;

		for (int i = 0; i < size; i++)
		{
			
			rbtn = (rbtn << Byte.SIZE) | ((long) val[offset + i] & BYTEMASK);
		}

		return rbtn;
	}

	public static void main(String[] args)
	{
		byte[] message = new byte[BSIZE + SSIZE + ISIZE + LSIZE];

		// byte类型
		int offset = encodeIntBigEndian(message, byteVal, 0, BSIZE);
		// short类型
		offset = encodeIntBigEndian(message, shortVale, offset, SSIZE);
		// int类型
		offset = encodeIntBigEndian(message, intVal, offset, ISIZE);
		// long类型
		offset = encodeIntBigEndian(message, longVal, offset, LSIZE);

		System.out
				.println("Encode message:" + byteArray2DecimalString(message));

		// 解析加密后的数据

		offset = 0;
		// 解析byte
		long value = decodeIntBigEndian(message, offset, BSIZE);
		System.out.println("Byte Value=" + value);

		// 解析short
		offset += BSIZE;
		value = decodeIntBigEndian(message, offset, SSIZE);
		System.out.println("Short Value=" + value);

		// 解析int
		offset += SSIZE;
		value = decodeIntBigEndian(message, offset, ISIZE);
		System.out.println("Int value=" + value);

		// 解析long
		offset += ISIZE;
		value = decodeIntBigEndian(message, offset, LSIZE);
		System.out.println("Long value=" + value);
	}

}

执行结果如下



如上图所示,运行过程中产生了一个字节序列


还有一一种方式可以使用Java提供的二进制的读写操作。

package com.suifeng.tcpip.chapter3;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

/**
 * 基本整型的发送和接收(模拟)
 * 
 * @author Administrator
 * 
 */
public class BruteForceCoding2
{
	// 要传输的参数
	private static final byte byteVal = 101;
	private static final short shortVal = 10001;
	private static final int intVal = 100000001;
	private static final long longVal = 1000000000001L;


	public static void main(String[] args)
	{
		byte[] msg = null;
		ByteArrayOutputStream buf = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(buf);
		
		System.out.println("要发送的数据:");
		System.out.println("Byte Value="+byteVal);
		System.out.println("Short Value="+shortVal);
		System.out.println("Int Value="+intVal);
		System.out.println("Long Value="+longVal);
		
		try
		{
			out.writeByte(byteVal);
			out.writeShort(shortVal);
			out.writeInt(intVal);
			out.writeLong(longVal);
			
			out.flush();
			
			msg = buf.toByteArray();
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		finally
		{
			try
			{
				if(buf != null)
				{
					buf.close();
				}
				
				if(out != null)
				{
					buf.close()	;
				}
			}
			catch (IOException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		System.out.println();
		
		ByteArrayInputStream bais = new ByteArrayInputStream(msg);
		DataInputStream dis = new DataInputStream(bais);
		
		try
		{
			System.out.println("接收到的数据:");
			System.out.println("Byte Value="+dis.readByte());
			System.out.println("Short Value="+dis.readShort());
			System.out.println("Int Value="+dis.readInt());
			System.out.println("Long Value="+dis.readLong());
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

执行结果如下



作者:licl19870605 发表于2013-1-27 23:21:32 原文链接
阅读:0 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>