接受socket无固定长度的报文,报文体的长度存在http头的Content-Length:中
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
if (in.remaining() < packetLength)
return false;
byte[] headBytes = null;
try{
if(headLength ==0 && bodyLength==0){
headBytes = new byte[in.limit()];
log.debug("in.limit():" + in.limit() + " in.remaining():" + in.remaining());
in.get(headBytes);
in.flip();
}
if(headBytes != null && headBytes.length >=0){
String httpMes = new String( headBytes,"UTF-8");
int startIndex = httpMes.indexOf("Content-Length:") + "Content-Length:".length();
int endIndex = httpMes.indexOf("Connection:");
String length = httpMes.substring(startIndex, endIndex);
length = length.trim();
bodyLength = Integer.parseInt(length);
httpMes = httpMes.substring(0,httpMes.indexOf("keep-alive") + "keep-alive".length()+1);
headLength = httpMes.getBytes().length;
headBytes = null;
log.debug("bodyLength:" + bodyLength +" headLength:" + headLength);
}
}catch(Exception e){
e.printStackTrace();
log.debug("exception e");
headLength =0;
bodyLength = 0;
// throw new Exception("exception e");
}
byte[] bytes = null;
if(headLength >= 0 && bodyLength>=0){
// 先获取上次的处理上下文,其中可能有未处理完的数据
Context ctx = getContext(session);
log.debug("in.limit:" + in.limit());
// 先把当前buffer中的数据追加到Context的buffer当中
ctx.append(in);
// 把position指向0位置,把limit指向原来的position位置
IoBuffer buf = ctx.getBuffer();
buf.flip();
log.debug("buf.remaining()--------" + buf.remaining());
try{
// 然后按数据包的协议进行读取
while (buf.remaining() >= packetLength) {
buf.mark();
// 检查读取是否正常,不正常的话清空buffer
if (bodyLength < 0 || bodyLength > maxPackLength) {
buf.clear();
break;
}
// 读取正常的消息,并写入输出流中,以便IoHandler进行处理
else if (bodyLength >= headLength
&& bodyLength + headLength <= buf.remaining()) {
log.debug("buf.limit():" + buf.limit() + " buf.remaining():" + buf.remaining());
bytes = new byte[buf.remaining()];
buf.get(bytes);
bodyLength=0;
headLength=0;
ctx.reset();
buf.clear();
ICBCMessage icbcMessage = new ICBCMessage();
icbcMessage.setMessageBody(bytes);
log.debug("CCBMessageDecoder bytes.lenght:" + bytes.length);
log.debug("body: " + new String(bytes,"UTF-8"));
ItxMessage itxMessage = convertToItxMessage(icbcMessage);
// 一般为加密报文,故这里只做报文接收,不做格式转换
// AcordLAHUtils.parseMessage(itxMessage, icbcMessage.getMessageBody());
out.write(itxMessage);
break;
} else {
// 如果消息包不完整
// 将指针重新移动消息头的起始位置
log.debug("消息包不完整......");
bytes = new byte[buf.remaining()];
buf.get(bytes);
log.debug(new String(bytes,"UTF-8"));
buf.reset();
break;
}
}
if (buf.hasRemaining()) {
log.debug("###################");
// 将数据移到buffer的最前面
IoBuffer temp = IoBuffer.allocate(maxPackLength)
.setAutoExpand(true);
temp.put(buf);
temp.flip();
// buf.clear();
// buf.put(temp);
String content = buf.getString(ctx.getDecoder());
log.debug("content: " + content);
} else {// 如果数据已经处理完毕,进行清空
log.debug("!!!!!!!!!!!!");
buf.clear();
}
}catch(Exception e){
e.printStackTrace();
log.debug(" exception failed");
bodyLength=0;
headLength=0;
ctx.reset();
buf.clear();
}
}
return true;
}
package com.siebre.itx.ccb.codec;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import org.apache.mina.core.buffer.IoBuffer;
public class Context {
private final CharsetDecoder decoder;
private IoBuffer buf;
private int msgLength = 0;
private int overflowPosition = 0;
private static Charset charset = Charset.defaultCharset();
/**
*
*
*/
public Context() {
decoder = charset.newDecoder();
buf = IoBuffer.allocate(20000).setAutoExpand(true);
}
/**
*
*
* @return CharsetDecoder
*/
public CharsetDecoder getDecoder() {
return decoder;
}
/**
*
*
* @return IoBuffer
*/
public IoBuffer getBuffer() {
return buf;
}
/**
*
*
* @return overflowPosition
*/
public int getOverflowPosition() {
return overflowPosition;
}
/**
*
*
* @return matchCount
*/
public int getMsgLength() {
return msgLength;
}
/**
*
*
* @param matchCount
* 报文长度
*/
public void setMsgLength(int msgLength) {
this.msgLength = msgLength;
}
/**
*
*
*/
public void reset() {
this.buf.clear();
this.overflowPosition = 0;
this.msgLength = 0;
this.decoder.reset();
}
/**
*
* @param in
* 输入流
*/
public void append(IoBuffer in) {
getBuffer().put(in);
}
}
分享到:
相关推荐
文件"MinaSocket"可能包含了实现上述功能的详细代码,包括服务端的Acceptor配置、过滤器设置、事件处理器编写,以及客户端的Socket连接、数据发送和接收等。通过阅读和理解这些代码,你可以更好地掌握Mina与Socket...
同时,客户端也可以使用Mina创建一个Socket连接,发送数据到服务器,并通过接收过滤器解析服务器返回的信息。 总结起来,Socket和Mina都是Java网络编程的重要工具,Socket更适合简单的、低级别的网络通信,而Mina则...
**Android-MinaSocket:基于Mina的高效Socket长连接库** 在移动应用开发中,尤其是Android平台,实时性与稳定性是许多应用场景的核心需求,比如在线游戏、即时通讯、物联网设备等。在这种背景下,使用Socket进行长...
现在我们来详细探讨如何在SpringBoot项目中集成Mina进行Socket通讯,并结合myBatis进行数据交互。 首先,我们需要在SpringBoot项目中引入Mina的相关依赖。在`pom.xml`文件中添加Mina的依赖项,例如: ```xml ...
MINA的灵活性和可扩展性使得它适合于处理各种设备间的通信需求,尤其是在大数据量和高并发的场景下。 深入探讨MINA框架的知识点: 1. **非阻塞I/O**:MINA使用Java NIO(非阻塞I/O)库,这允许在单个线程中处理多...
Socket编程和Apache Mina框架是Java中用于网络通信的重要工具,尤其在开发分布式系统和移动应用时发挥着关键作用。在此,我们将深入探讨这两个概念及其在AndroidPN项目中的应用。 首先,Socket通常被称为套接字,是...
Socket通信和MINA长连接是网络编程中的两个关键概念,主要应用于服务器与客户端之间的数据交互。在移动应用开发,特别是需要实时推送功能时,这两种技术显得尤为重要。 **Socket通信** Socket,也称为套接字,是...
在本篇博文中,我们将深入探讨如何利用Apache MINA库实现基于TLS/SSL的NIO(非阻塞I/O)Socket通信。MINA是一个高度可扩展的网络应用框架,广泛用于构建高性能、高并发的网络应用程序,如服务器端的TCP和UDP服务。...
**Mina Socket 源代码解析** Mina Socket 是 Apache Mina 项目的一部分,它是一个高性能、可扩展的网络通信框架。Mina 提供了一种简单的方式来构建网络应用,如服务器和客户端,支持多种协议,如 TCP/IP 和 UDP。在...
Socket Mina测试框架是一个强大的网络通信应用框架,主要用于简化Java应用程序与远程服务器之间的通信。它提供了高度可扩展和高性能的I/O处理模型,使得开发者能够更专注于业务逻辑,而不是底层的网络实现细节。Mina...
Mina的非阻塞特性使得一个线程可以同时处理多个连接,极大地提高了系统并发性,适合处理大量并发连接的情况。 `ResponseHandler.java`很可能是处理服务器响应的处理器类,它对接收到的数据进行解码、解析和业务逻辑...
Java客户端Socket与Mina服务端通信是网络编程中常见的应用场景,尤其在开发分布式系统或实时数据传输时。这里我们将深入探讨这两个技术,并了解如何通过它们建立保持长连接的通信。 首先,Socket是Java中用于实现...
本文将深入探讨如何使用Mina来实现一个服务器以及对应的Socket客户端,从而进行消息传递。 **Mina 框架介绍** Mina提供了一个高级抽象层,允许开发者用类似处理Java IO的方式处理NIO(非阻塞I/O)。它简化了网络...
Socket通讯和MINA应用是Java网络编程中的两个关键概念,它们在开发分布式系统、网络服务和客户端应用程序中扮演着重要角色。这篇博文将深入探讨这两个主题,并通过一个名为"testMina"的压缩包文件来展示实际应用。 ...
在TCP/IP协议栈中,Socket分为两种类型:流式Socket(TCP)和数据报式Socket(UDP)。Apache Mina主要使用TCP Socket进行可靠的双向通信。 **Apache Mina 2.0.7中的关键组件:** 1. **Transport层**:负责实际的...
MINA框架中的Socket服务端和客户端通过Socket接口实现数据的发送和接收,服务端创建监听Socket,等待客户端的连接请求;客户端则通过Socket连接到服务端,进行数据交互。 3. **服务端实现**:在MINA中,服务端通常...
### HPsocket 封包与mina对接 #### 一、HPsocket概述 HPsocket是一个高性能、跨平台的TCP/UDP/串口通信中间件库,它提供了丰富的API接口和灵活的事件驱动模型,使得用户可以方便地开发自己的网络应用程序。本文将...
mina带心跳长链接,可实现服务间通信。socket长连接实现客户端与服务端的通信。对于通信技术学习是非常好的资料。改造后可实现企业应用
TCP Socket提供可靠的、基于字节流的数据传输,而UDP Socket则是一种无连接的服务,数据以数据报的形式发送,不保证顺序或可靠性,但具有更高的效率。在Java中,我们可以通过`java.net.Socket`和`java.net....
Apache MINA(Multi-purpose Infrastructure for Network Applications)是一个Java框架,用于构建高性能、高可用性的网络应用程序,例如服务器和客户端。MINA提供了高级网络通信抽象,包括异步I/O、事件驱动的架构...