`
MoonMonster
  • 浏览: 36710 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

netty处理tcp粘包/拆包问题

阅读更多

 所谓的粘包/拆包,用一个例子来说明就是:

加入客户端向服务端发送1000条数据,如果不加以处理的话,那么服务端接收的数据可能就是如图所示了:



 数据要么几段粘在了一起,要么一段数据被拆成了几段,这肯定会造成很大的影响。

 

而解决后的所接收的正确数据该如下所示:



 

 

简单讲了一下粘包/拆包是什么样的问题,详细解释可见csdn博客

http://blog.csdn.net/binghuazh/article/details/4222516

 

 

 

客户端代码:

package com.netty.dealpacket;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;

/**
 * @author Chalmers 2016年2月24日 下午2:35:39
 */
public class Client {

	public static void main(String[] args) throws UnknownHostException,
			IOException {
		Socket socket = new Socket("127.0.0.1", 9090);

		String message = "hello";

		byte[] bytes = message.getBytes();

		// 设置空间大小为一个存储了长度的int型数据(长度)加上转换后的byte数组
		ByteBuffer buffer = ByteBuffer.allocate(4 + bytes.length);
		// 将长度存入
		buffer.putInt(bytes.length);
		// 将数据存入
		buffer.put(bytes);

		// 转换成字节数组
		byte[] array = buffer.array();

		// 向服务端发送1000次
		for (int i = 0; i < 1000; i++) {
			socket.getOutputStream().write(array);
		}

		// 关闭
		socket.close();
	}
}

 

 

处理问题代码:

package com.netty.dealpacket;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;

/**
 * @author Chalmers 2016年2月24日 下午2:23:49
 */
public class MyDecoder extends FrameDecoder {

	@Override
	protected Object decode(ChannelHandlerContext chc, Channel channel,
			ChannelBuffer buffer) throws Exception {

		// 如果buffer中的可读字节大于4个(即除了长度以外还有数据,因为长度可能是为0的)
		if (buffer.readableBytes() > 4) {

			// 标记,指向当前指针位置,读取数据时使用
			buffer.markReaderIndex();
			// 取得长度
			int len = buffer.readInt();

			// 如果剩余可读字节小于长度的话,则表明发生了拆包现象,那么不对它进行处理
			if (buffer.readableBytes() < len) {
				// 重置标记
				buffer.resetReaderIndex();

				// 返回null,表示等待
				return null;
			}

			// 对数据进行处理
			byte[] bytes = new byte[len];
			buffer.readBytes(bytes);
			// 将数据返回到ServerHandler中进行处理
			return new String(bytes);
		}

		return null;
	}

}

 

 

package com.netty.dealpacket;

import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;

/**
 * @author Chalmers 2016年2月24日 下午2:22:41
 */
public class ServerHandler extends SimpleChannelHandler {

	int count = 1;

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		// 对从MyDecoder中传递过来的数据进行处理
		System.out.println((String) e.getMessage() + "  " + count);
		count++;
	}
}

 

 

服务端代码:

package com.netty.dealpacket;

import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringEncoder;

/**
 * @author Chalmers 2016年2月24日 下午2:21:33
 */
public class Server {

	public static void main(String[] args) {
		ServerBootstrap serverBootstrap = new ServerBootstrap();

		ExecutorService boss = Executors.newCachedThreadPool();
		ExecutorService worker = Executors.newCachedThreadPool();

		serverBootstrap.setFactory(new NioServerSocketChannelFactory(boss,
				worker));
		serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() {

			@Override
			public ChannelPipeline getPipeline() throws Exception {
				ChannelPipeline pipeline = Channels.pipeline();
				pipeline.addLast("decoder", new MyDecoder());
				pipeline.addLast("encoder", new StringEncoder());
				pipeline.addLast("handler", new ServerHandler());

				return pipeline;
			}
		});

		serverBootstrap.bind(new InetSocketAddress(9090));
		System.out.println("start...");
	}
}

 

 

  • 大小: 17.4 KB
  • 大小: 16.6 KB
1
2
分享到:
评论

相关推荐

    使用Netty解决TCP粘包和拆包问题过程详解

    使用Netty解决TCP粘包和拆包问题过程详解 Netty是一个流行的Java网络编程框架,提供了简洁、灵活的API来处理网络编程的各种问题。其中,解决TCP粘包和拆包问题是Netty的一个重要应用场景。本文将详细介绍使用Netty...

    unity实现Socket通讯(内含tcp粘包/拆包解决)

    Unity中的Socket通信是游戏开发中实现网络交互的重要技术,它基于C#语言,允许服务器和...解决TCP粘包/拆包问题,可以确保数据正确无误地传输。理解并熟练掌握这些知识点,对于开发网络游戏或实时交互应用至关重要。

    Netty精粹之TCP粘包拆包问题

    ### Netty精粹之TCP粘包拆包问题详解 #### 一、引言 在网络通信领域,尤其是在基于TCP协议的应用程序开发中,经常会遇到“粘包”和“拆包”的问题。这些问题虽然属于较为底层的技术细节,但对于保障数据传输的准确...

    Netty粘包-拆包应用案例及解决方案分析.docx

    Netty 作为一个高性能的网络通信框架,提供了多种解决 TCP 粘包/拆包问题的方法。 一、TCP 粘包/拆包的基础知识 TCP 是一个“流”协议,没有界限的一串数据。TCP 底层并不知道上层业务逻辑,它会根据 TCP 缓冲区...

    c++服务器 拆包粘包 过程

    在计算机网络编程中,"拆包"和"粘包"是TCP协议中常见的问题,尤其在C++服务器开发中,理解并处理好这两个概念对于构建高效稳定的网络服务至关重要。TCP是一种面向连接的、可靠的传输层协议,它通过流式传输确保数据...

    Netty中粘包和拆包的解决方案.docx

    在TCP网络编程中,粘包和拆包是常见的问题,...总的来说,Netty通过提供一系列的解码器,使得处理TCP粘包和拆包问题变得更加便捷,开发者可以根据实际业务需求灵活选择或自定义解码策略,保证数据的正确传输和解析。

    粘包和拆包及Netty解决方案.docx

    #### 五、Netty提供的粘包拆包解决方案 Netty是一个高性能的Java网络编程框架,它内置了一些专门用于处理粘包和拆包问题的组件。以下是Netty中几个常用的技术方案: 1. **FixedLengthFrameDecoder**:适用于固定...

    Netty粘包与拆包源码

    在TCP/IP协议中,由于数据的传输是以字节流的方式进行,如果不对数据进行适当的处理,就可能出现“粘包”和“拆包”的问题。本文将深入探讨Netty中如何处理这两个问题,并通过源码分析来理解其内部机制。 “粘包”...

    netty搭建tcp服务,粘拆包解决

    在TCP(传输控制协议)网络编程中,粘包和拆包是常见的问题,尤其在处理连续的数据流时。下面我们将深入探讨Netty如何搭建TCP服务以及它如何解决粘包和拆包的问题。 首先,TCP本身并不区分消息边界,它只是一个字节...

    面试题:聊聊TCP的粘包、拆包以及解决方案.docx

    TCP的粘包和拆包是网络编程中遇到的常见问题,尤其在基于TCP协议的通讯中,如RPC框架和Netty等。TCP是一种面向字节流的协议,它没有明确的数据包边界,这可能导致发送的数据在接收端看起来像是被粘在一起或是被拆...

    Netty粘包拆包问题解决方案

    Netty 粘包拆包问题解决方案 Netty 是一个基于 Java 的网络编程框架,它提供了一个便捷的方式来处理网络数据的读写操作。然而,在使用 Netty 进行网络编程时,经常会遇到粘包和拆包的问题。所谓粘包和拆包,就是指...

    netty拆包粘包解决方案示例

    在分布式系统和网络通信中,Netty是一个非常流行的高性能、异步事件驱动的网络应用程序框架,用于快速开发可...通过阅读和理解这些代码,开发者可以更好地掌握Netty在处理拆包粘包问题以及客户端断线重连方面的技巧。

    netty消息拆包粘包编解码(java代码)

    以上就是关于Netty消息拆包粘包编解码的基本介绍,通过合理的编码和解码策略,我们可以有效地处理TCP通信中的粘包和拆包问题,确保数据的正确传输。在实际应用中,还可以结合其他编码解码器,如`...

    netty解析报文,解决粘包拆包

    注:下载前请查看本人博客文章,看是否...里面包含模拟TCP客户端发送报文工具,硬件厂商提供的协议,服务端(springboot+netty)解析报文源码,源码里整合了redis,不需要可自行删除,如有需要客户端代码,可联系我。

    Netty面试专题1

    本专题主要涵盖了NIO(非阻塞I/O)的基础知识以及与Netty相关的线程模型、TCP粘包/拆包问题和序列化协议。 ### 1. BIO、NIO 和 AIO 的区别 - **BIO (Blocking I/O)**:同步阻塞I/O模型,每个连接都需要一个独立的...

    netty权威指南第2版

    第4章 TCP粘包/拆包问题解析之道 第5章 分隔符和定长解析码器的应用 第6章 编码技术 第7章 MessagePack 编解码 第8章 Google Protobuf编解码 第9章 JBoss Marshalling 编解码 第10章 HTTP协议开发应用 第11章 ...

    Netty粘包拆包解决方案.docx

    Netty 为此提供了多种内置的解码器,方便开发者解决粘包拆包问题: - **LineBasedFrameDecoder**:基于回车换行符`\r\n`或其他指定的行结束符来分割数据。 - **DelimiterBasedFrameDecoder**:基于用户指定的分隔符...

    C# TCP粘包解决

    总结起来,解决C#中的TCP粘包问题需要理解TCP协议的工作原理,合理设计数据包格式,有效管理接收缓冲区,利用同步机制和异步编程技术,以及考虑是否使用第三方库来简化开发。通过深入研究提供的代码示例,可以进一步...

    java Netty作为客户端/服务端处理tcp报文

    报文格式8位长度加内容,代码还对netty的粘包和拆包做了处理

Global site tag (gtag.js) - Google Analytics