在tcp编程底层都有拆包和粘包的机制

  拆包

当发送数据量过大时数据量会分多次发送

以前面helloWord代码为例

package com.liqiang.nettyTest2;

public class nettyMain {
public static void main(String[] args) {
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Server server = new Server(8081);
server.start();
}
}).start();
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Client client1=new Client("127.0.0.1", 8081);
client1.connection();
client1.sendMsg("In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. His book w"
+ "ill give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the process "
+ "of configuring and connecting all of Netty’s components to bring your learned about threading models in ge"
+ "neral and Netty’s threading model in particular, whose performance and consistency advantages we discuss"
+ "ed in detail In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. Hi"
+ "s book will give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the"
+ " process of configuring and connecting all of Netty’s components to bring your learned about threading "
+ "models in general and Netty’s threading model in particular, whose performance and consistency advantag"
+ "es we discussed in detailIn this chapter you general, we recommend Java Concurrency in Practice by Bri"
+ "an Goetz. His book will give We’ve reached an exciting point—in the next chapter;the counter is: 1 2222"
+ "sdsa ddasd asdsadas dsadasdas");
}
}).start();
}
}

打印

可以发现这里拆分成了2次发送

  粘包

当发送数据量过小时会组合成一次发送

package com.liqiang.nettyTest2;

public class nettyMain {
public static void main(String[] args) {
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Server server = new Server(8081);
server.start();
}
}).start();
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Client client1=new Client("127.0.0.1", 8081);
client1.connection();
for(int i=0;i<100;i++) {
client1.sendMsg("d");
} }
}).start();
}
}

可以发现有时多条发送的数据会组合成一条发送

解决方案

netty提供了解码器来解决拆包和粘包的问题

LineBasedFrameDecoder 

通过换行符来区分包

服务器端增加LineBasedFrameDecoder

package com.liqiang.nettyTest2;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.AsciiHeadersEncoder.NewlineType;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder; public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> { private Server server;
public ServerChannelInitializer(Server server) {
this.server=server;
}
@Override
protected void initChannel(SocketChannel channel) throws Exception {
// TODO Auto-generated method stub
channel.pipeline()
.addLast(new LineBasedFrameDecoder(2048))//2048是限制一个包的最大字节数。如果超过将会报异常
.addLast("decoder",new StringDecoder())//接收到数据 自动将将buffer转换为String 避免自己再转
.addLast("encoder",new StringEncoder())//发送数据 可以直接发送String 框架内部转换为buffer传输
.addLast(new ServerHandle(server));
} }

客户端

package com.liqiang.nettyTest2;

public class nettyMain {
public static void main(String[] args) {
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Server server = new Server(8081);
server.start(); }
}).start();
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Client client1=new Client("127.0.0.1", 8081);
client1.connection();
client1.sendMsg("In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. His book w"
+ "ill give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the process "
+ "of configuring and connecting all of Netty’s components to bring your learned about threading models in ge"
+ "neral and Netty’s threading model in particular, whose performance and consistency advantages we discuss"
+ "ed in detail In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. Hi"
+ "s book will give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the"
+ " process of configuring and connecting all of Netty’s components to bring your learned about threading "
+ "models in general and Netty’s threading model in particular, whose performance and consistency advantag"
+ "es we discussed in detailIn this chapter you general, we recommend Java Concurrency in Practice by Bri"
+ "an Goetz. His book will give We’ve reached an exciting point—in the next chapter;the counter is: 1 2222"
+ "sdsa ddasd asdsadas dsadasdas"+System.getProperty("line.separator"));//System.getProperty("line.separator") 兼容linux和windows换行符的区别
}
}).start();
}
}

如果发送数据忘记拼换行符 服务器将不会有任何打印

DelimiterBasedFrameDecoder

通过指定符号区分

服务器端

package com.liqiang.nettyTest2;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.AsciiHeadersEncoder.NewlineType;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder; public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> { private Server server;
public ServerChannelInitializer(Server server) {
this.server=server;
}
@Override
protected void initChannel(SocketChannel channel) throws Exception {
// TODO Auto-generated method stub
channel.pipeline()
.addLast(new DelimiterBasedFrameDecoder(2048,Unpooled.copiedBuffer("$$__".getBytes())))//$__为包的分隔符2048是限制一个包的最大字节数。如果超过将会报异常
.addLast("decoder",new StringDecoder())//接收到数据 自动将将buffer转换为String 避免自己再转
.addLast("encoder",new StringEncoder())//发送数据 可以直接发送String 框架内部转换为buffer传输
.addLast(new ServerHandle(server));
} }

客户端

package com.liqiang.nettyTest2;

public class nettyMain {
public static void main(String[] args) {
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Server server = new Server(8081);
server.start(); }
}).start();
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Client client1=new Client("127.0.0.1", 8081);
client1.connection();
client1.sendMsg("In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. His book w"
+ "ill give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the process "
+ "of configuring and connecting all of Netty’s components to bring your learned about threading models in ge"
+ "neral and Netty’s threading model in $$__particular, whose performance and consistency advantages we discuss"
+ "ed in detail In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. Hi"
+ "s book will give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the"
+ " process of configuring and connecting all $$__of Netty’s components to bring your learned about threading "
+ "models in general and Netty’s threading model in particular, whose performance and consistency advantag"
+ "es we discussed in detailIn this chapter you general, we recommend Java Concurrency in Practice by Bri"
+ "an Goetz. His book will give We’ve reached an exciting point—in the next chapter;the counter is: 1 2222"
+ "sdsa ddasd asdsadas dsadasdas$__");
}
}).start();
}
}

根据$__数据被拆分成了三个包

netty 拆包和粘包 (三)的更多相关文章

  1. netty权威指南学习笔记三——TCP粘包/拆包之粘包现象

    TCP是个流协议,流没有一定界限.TCP底层不了解业务,他会根据TCP缓冲区的实际情况进行包划分,在业务上,一个业务完整的包,可能会被TCP底层拆分为多个包进行发送,也可能多个小包组合成一个大的数据包 ...

  2. Netty系列(四)TCP拆包和粘包

    Netty系列(四)TCP拆包和粘包 一.拆包和粘包问题 (1) 一个小的Socket Buffer问题 在基于流的传输里比如 TCP/IP,接收到的数据会先被存储到一个 socket 接收缓冲里.不 ...

  3. Netty处理TCP拆包、粘包

    Netty实践(二):TCP拆包.粘包问题-学海无涯 心境无限-51CTO博客 http://blog.51cto.com/zhangfengzhe/1890577 2017-01-09 21:56: ...

  4. Netty—TCP的粘包和拆包问题

    一.前言 虽然TCP协议是可靠性传输协议,但是对于TCP长连接而言,对于消息发送仍然可能会发生粘贴的情形.主要是因为TCP是一种二进制流的传输协议,它会根据TCP缓冲对包进行划分.有可能将一个大数据包 ...

  5. 深入了解Netty【八】TCP拆包、粘包和解决方案

    1.TCP协议传输过程 TCP协议是面向流的协议,是流式的,没有业务上的分段,只会根据当前套接字缓冲区的情况进行拆包或者粘包: 发送端的字节流都会先传入缓冲区,再通过网络传入到接收端的缓冲区中,最终由 ...

  6. 【Netty】TCP粘包和拆包

    一.前言 前面已经基本上讲解完了Netty的主要内容,现在来学习Netty中的一些可能存在的问题,如TCP粘包和拆包. 二.粘包和拆包 对于TCP协议而言,当底层发送消息和接受消息时,都需要考虑TCP ...

  7. Netty 中的粘包和拆包

    Netty 底层是基于 TCP 协议来处理网络数据传输.我们知道 TCP 协议是面向字节流的协议,数据像流水一样在网络中传输那何来 "包" 的概念呢? TCP是四层协议不负责数据逻 ...

  8. netty 解决TCP粘包与拆包问题(二)

    TCP以流的方式进行数据传输,上层应用协议为了对消息的区分,采用了以下几种方法. 1.消息固定长度 2.第一篇讲的回车换行符形式 3.以特殊字符作为消息结束符的形式 4.通过消息头中定义长度字段来标识 ...

  9. Netty的TCP粘包/拆包(源码二)

    假设客户端分别发送了两个数据包D1和D2给服务器,由于服务器端一次读取到的字节数是不确定的,所以可能发生四种情况: 1.服务端分两次读取到了两个独立的数据包,分别是D1和D2,没有粘包和拆包. 2.服 ...

随机推荐

  1. [ JavaScript ] JavaScript 实现继承.

    对于javascript中的继承,因为js中没有后端语言中的类式继承.所以js中的继承,一般都是原型继承(prototype). function P (name){ this.name = name ...

  2. golang LMDB入门例子——尼玛,LMDB的文档真的是太少了

    使用的是这个库:https://github.com/szferi/gomdb 安装: go get github.com/szferi/gomdb 代码: package main import ( ...

  3. openstack 性能优化极致

  4. JS判断浏览器类型和详细区分IE各版本浏览器

    今天用到JS判断浏览器类型,于是就系统整理了一下,便于后期使用. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ...

  5. php 提交编辑数据没有变,返回0,判断

    php 提交编辑数据没有变,返回0,判断以TP为例子 $edit = D('Brand')->save($data);if($edit == true){ echo "修改成功&quo ...

  6. [NOI2015,LuoguP2146]软件包管理器------树剖

    ***题目链接戳我*** 又是在树上瞎搞滴题目.... 我们如果以安装的软件为1,未安装的软件为0,那么软件改变的数量即树上权值总和的数量,涉及到区间修改,区间查询,考虑树剖 分析完毕,似乎没啥好说的 ...

  7. TCP/IP详解(一)

    SYN中的MSS选项是告诉对端,本端在本地连接的每个TCP分节中愿意接收的最大数据量.发送端TCP使用接收端的MSS值作为发送分节的最大大小. TCP半关闭使用的情况较少,可用于通知对端本端数据已输入 ...

  8. HTML基础练习

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  9. MySQL学习笔记之右连接

    MySQL的右连接 #右连接,以右表为基表 select course.stuid,course.stuname,sex,course,city from class1 right join cour ...

  10. @PathVariable注解的使用和@Requestparam

    一. @PathVariable @PathVariable这是一个路径映射格式的书写方式注解,在类映射路径的后加上/{对应方法参数中属性@PathVariable("code") ...