socket接口tcp协议发送16进制码流需求实现

socket接口,数据传输以16进制码流的形式

1.建立连接(鉴权)

2.消息发送

write,flush;write,flush即可

注意:以NULL结束的,因为传输过程中是16进制的码流,而NULL16进制为00,那么直接补00即可,具体方式

byte [] byte = {0};
out.write(byte);//输出流 out = new DataOutputStream(socket.getOutputStream());

1个字节的无符号整数

byte [] byte = {值};
out.write(byte);//输出流 out = new DataOutputStream(socket.getOutputStream());

 

基于tcp的socket消息由head和体构成:

1.tcp发消息传输过程中为16进制的码流,那么需要以字节流的形式发送

public class SocketUtils {
	public static int send(MsgBindHead bind, MsgSendBody send) {
		try {
			Socket socket;
			DataOutputStream out;
			socket = new Socket("ip", port);
			// 客户端读取数据流
			BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
			// 向服务器端发送数据
			out = new DataOutputStream(socket.getOutputStream());
			// 客户端发送数据连接
			System.out.println("bind socket开始发送消息...\t");
			// 头
			System.out.println("绑定头信息:...长度" + bind.getLen());
			byte[] intToByteArray1 = TurnOffUtils.intToByteArray1(bind.getLen());// int转为字节数组
			byte[] intToByteArray2 = TurnOffUtils.intToByteArray1(bind.getId());
			byte[] intToByteArray3 = TurnOffUtils.intToByteArray1(bind.getSeq());
			byte[] k = { 0 };
			byte[] byteMergerAll = TurnOffUtils.byteMergerAll(intToByteArray1, intToByteArray2, intToByteArray3,
					bind.getSys_id().getBytes(), k, TurnOffUtils.getSha1(bind.getPwd()));
			out.write(byteMergerAll);
			out.flush();//发送
			// 客户端读取数据
			byte[] result = new byte[16];
			int read = in.read(result);
			int r = -2;
			System.out.println("bind socket客户端收到的数据...长度=【" + read + "】内容:" + new String(result));
			for (byte b : result) {
				System.out.println(" ");
				System.out.print(b);
			}
			byte[] pro = { 32 };
			byte[] pro1 = { 0 };// 补充0
			/* 更新方式... */
			byte[] b1 = new byte[1];
			if (send.getUpdateType() == 1) {
				b1[0] = 1;// 增加
			}
			if (send.getUpdateType() == 3) {
				b1[0] = 3;// 更新方式
			}
			/* 头 +体 code phone+00 时间 方式 */
			byte[] protect_no = TurnOffUtils.byteMergerAll(TurnOffUtils.intToByteArray1(send.getLen()),
					TurnOffUtils.intToByteArray1(send.getId()), TurnOffUtils.intToByteArray1(send.getNumber()), pro,
					send.getProtect_Num().getBytes(), pro1, send.getTime().getBytes(), b1);
			out.write(protect_no);
			out.flush();
			result = new byte[16];
			read = in.read(result);
			System.out.println("protect socket客户端收到的数据...长度=【" + read + "】内容:" + new String(result));
			for (byte b : result) {
				System.out.println(" ");
				System.out.print(b);
			}

			out.close();
			in.close();
			socket.close();
			return result[13];
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return -1;
	}
/*
	 * byte[]合并
	 */
	public static byte[] byteMergerAll(byte[]... values) {
		int length_byte = 0;
		for (int i = 0; i < values.length; i++) {
			length_byte += values[i].length;
		}
		byte[] all_byte = new byte[length_byte];
		int countLength = 0;
		for (int i = 0; i < values.length; i++) {
			byte[] b = values[i];
			System.arraycopy(b, 0, all_byte, countLength, b.length);
			countLength += b.length;
		}
		return all_byte;
	}

 

2.消息长度计算(消息长度,id,序列数 都是占4个字节,16进制数直接用byte字节发送即可)

消息长度如果为头加体的长度,计算方式为,消息体转为16进制的字符串,然后length/2即为字节数,再加上消息头的长度即为消息长度;(16进制的位数(16进制的string长度)除以2就是字节数,即为消息长度)

/*字符串转为16进制字符串*/
public static String strTo16(String s) {
		String str = "";
		for (int i = 0; i < s.length(); i++) {
			int ch = (int) s.charAt(i);
			String s4 = Integer.toHexString(ch);
			str = str + s4;
		}
		return str;
	}

3.连接中的密码加密为sha-1散列方式加密,但是一般的加密完毕之后都是字符串类型,这里需要的字节类类型,其实在研究底层源码之后稍作修改即可

/*
	 * sha-1散列加密返回字节流byte
	 */
	public static byte[] getSha1(String str) {
		byte[] buf = new byte[16];
		if (null == str || 0 == str.length()) {
			return null;
		}
		byte[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		try {
			MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
			mdTemp.update(str.getBytes("UTF-8"));
			byte[] md = mdTemp.digest();
			return md;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

4.消息接收

byte[] result = new byte[16];// 65535 这里返回的消息长度只有13 那么我暂时用16位来接收
			int read = in.read(result);
			int r = -2;
			System.out.println("bind socket客户端收到的数据...长度=【" + read + "】内容:" + new String(result) );
			for (byte b : result) {
				System.out.print(b);
			}
// 具体的消息内容获取
result[index]

总结:tcp协议中,数据的传输过程中是以16进制的码流实现的,那么消息长度就是16进制码流的字节长度(两位一字节);消息发送均以byte字节流的形式发送;

 

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【1】项目代码完整且功能都验证ok,确保稳定可靠运行后才上传。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通,帮助解答。 【2】项目主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 【3】项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 【4】如果基础还行,或热爱钻研,可基于此项目进行二次开发,DIY其他不同功能,欢迎交流学习。 【注意】 项目下载解压后,项目名字和项目路径不要用中文,否则可能会出现解析不了的错误,建议解压重命名为英文名字后再运行!有问题私信沟通,祝顺利! 基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip 基于联邦学习和深度残差网络实现的网络入侵检测python源码+实验说明.zip
以下是Java中基于TCP协议Socket通讯,发送和接收16进制报文的代码示例: 服务端代码: ```java import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) { try { // 创建服务端Socket并绑定端口号 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务端已启动,等待客户端连接..."); // 等待客户端连接 Socket socket = serverSocket.accept(); System.out.println("客户端已连接"); // 获取输入流 InputStream inputStream = socket.getInputStream(); byte[] buffer = new byte[1024]; int len; // 循环读取数据 while ((len = inputStream.read(buffer)) != -1) { // 将字节数组转换为16进制字符串 String hexString = bytesToHexString(buffer, len); System.out.println("收到客户端消息:" + hexString); } // 关闭流和Socket inputStream.close(); socket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } // 将字节数组转换为16进制字符串 private static String bytesToHexString(byte[] bytes, int len) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < len; i++) { String hex = Integer.toHexString(bytes[i] & 0xff); if (hex.length() == 1) { sb.append("0"); } sb.append(hex.toUpperCase()); } return sb.toString(); } } ``` 客户端代码: ```java import java.io.IOException; import java.io.OutputStream; import java.net.Socket; public class Client { public static void main(String[] args) { try { // 创建客户端Socket并连接服务端 Socket socket = new Socket("127.0.0.1", 8888); // 获取输出流 OutputStream outputStream = socket.getOutputStream(); // 发送16进制报文 String hexString = "AABBCCDD"; byte[] bytes = hexStringToBytes(hexString); outputStream.write(bytes); // 关闭流和Socket outputStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } // 将16进制字符串转换为字节数组 private static byte[] hexStringToBytes(String hexString) { int len = hexString.length() / 2; byte[] bytes = new byte[len]; for (int i = 0; i < len; i++) { bytes[i] = (byte) Integer.parseInt(hexString.substring(i * 2, i * 2 + 2), 16); } return bytes; } } ``` 以上代码示例中,服务端通过创建ServerSocket监听端口8888,等待客户端连接。客户端通过创建Socket连接服务端,并获取输出流发送16进制报文。服务端通过获取输入流读取数据,并将字节数组转换为16进制字符串。客户端和服务端均提供了将16进制字符串转换为字节数组和将字节数组转换为16进制字符串的方法,方便进行数据转换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值