Java 组拆报文

========================================================================================

如需工程说明文档,请到下面的链接下载

http://download.youkuaiyun.com/detail/ading_25/4857182

========================================================================================

在Java开发过程中经常遇到,组装拆解报文的过程。或用定长或用分隔符。组装拆解报文到java对象很是繁琐,需要分析字符长度/分隔符,轮换的类型,以及代码值的转换/反转换。本工程旨在降低开发人员的组拆报文的工作量,用最小的配置即可完成报文到java对象、java对象到报文的转换过程;同时测试代码提供了对象到报文,再到写报文到FTP目录中;以及根据文件名,解析文件返回java对象;提供Socket服务、客户端的配置和灵活使用。

### 处理TCP报文分的方法 由于TCP是一个面向字节流的协议,它并不关心应用层数据的实际边界。因此,在实际开发中,需要通过特定的方式在接收端解析出完整的消息单元。以下是几种常见的解决方案: #### 方法一:固定长度的消息 一种简单有效的方式来处理TCP报文分问题是定义每条消息具有固定的长度。这种方式适用于消息内容较少变化的应用场景。 ```c++ // C++ 示例代码实现固定长度消息读取 #include <iostream> #include <cstring> void read_fixed_length_message(int socket_fd, size_t message_size) { char buffer[message_size]; ssize_t bytes_received = 0; while (bytes_received < static_cast<ssize_t>(message_size)) { ssize_t result = recv(socket_fd, buffer + bytes_received, message_size - bytes_received, 0); if (result <= 0) { // 错误或连接关闭 break; } bytes_received += result; } std::cout << "Received fixed-length message: " << buffer << std::endl; } ``` 这种方法的优点在于其实现较为直观和容易维护[^1]。然而它的缺点也很明显——无法灵活适应不同大小的消息需求。 #### 方法二:使用特殊定界符 另一种常见做法是在每条消息之间加入特殊的分隔字符作为标志位,比如回车换行符(`\r\n`)或其他不易出现在正常数据中的字符串合。 ```python import socket def receive_delimited_messages(sock): delimiter = b'\r\n' data_buffer = bytearray() messages = [] while True: chunk = sock.recv(4096) if not chunk: break data_buffer.extend(chunk) while True: index = data_buffer.find(delimiter) if index == -1: break msg = data_buffer[:index].decode('utf-8') messages.append(msg) # 移除已处理部分并继续寻找下一个消息 del data_buffer[:len(msg)+len(delimiter)] return messages ``` 此方案允许动态调整消息尺寸,但在某些情况下可能会因为频繁扫描缓冲区而导致性能下降[^2]。 #### 方法三:前缀指定消息长度 最推荐也是最为广泛采用的技术就是在每次发送之前先附加一个表明当前消息体总字节数的信息头(一般为整数)。这样接收方可以根据该数值精确计算所需等待的数据量直至完整获取为止。 ```java public class MessageHandler { public String[] splitMessagesByLengthPrefix(InputStream inputStream) throws IOException { List<String> results = new ArrayList<>(); DataInputStream dis = new DataInputStream(inputStream); try { while(true){ int length = dis.readInt(); // Read the next message's length byte[] messageBytes = new byte[length]; dis.readFully(messageBytes); String messageString = new String(messageBytes,"UTF-8"); results.add(messageString); } } catch (EOFException e){} finally{ dis.close(); } return results.toArray(new String[results.size()]); } } ``` 这种机制不仅能够很好地支持任意规模的数据交换,而且还能显著提升程序运行效率[^3]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值