maven工程
依赖

<dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.39.Final</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.18</version></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>19.0</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>3.11.3</version></dependency></dependencies>

这里写目录标题

  • 一.bytebuffer
    • 1.bytebuffer基本使用
    • 2.bytebuffer-内部结构
    • 3.bytebuffer-方法演示
    • 4.bytebuffer-黏半包解析

一.bytebuffer

1.bytebuffer基本使用

package cn.itcast.netty.c1;import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;public class TestByteBuffer {public static void main(String[] args) {//FileChannel//1.输入输出流try (FileChannel channel = new FileInputStream("data.txt").getChannel()) {//准备缓冲区ByteBuffer byteBuffer=ByteBuffer.allocate(5);//从channel读取数据,向buffer写入while(true){int read = channel.read(byteBuffer);System.out.println("read="+read);if(read==-1){break;}//打印buffer的内容byteBuffer.flip();while(byteBuffer.hasRemaining()){byte b = byteBuffer.get();System.out.println((char)b);}byteBuffer.clear();//切换为写模式}} catch (IOException e) {}}
}
read=5
1
3
5
7
9
read=5
0
q
w
e
r
read=3
t
y
u
read=-1

2.bytebuffer-内部结构



3.bytebuffer-方法演示

工具类ByteBufferUtil

package cn.itcast.netty.c1;import io.netty.util.internal.StringUtil;import java.nio.ByteBuffer;import static io.netty.util.internal.MathUtil.isOutOfBounds;
import static jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType.NEWLINE;public class ByteBufferUtil {private static final char[] BYTE2CHAR = new char[256];private static final char[] HEXDUMP_TABLE = new char[256 * 4];private static final String[] HEXPADDING = new String[16];private static final String[] HEXDUMP_ROWPREFIXES = new String[65536 >>> 4];private static final String[] BYTE2HEX = new String[256];private static final String[] BYTEPADDING = new String[16];static {final char[] DIGITS = "0123456789abcdef".toCharArray();for (int i = 0; i < 256; i++) {HEXDUMP_TABLE[i << 1] = DIGITS[i >>> 4 & 0x0F];HEXDUMP_TABLE[(i << 1) + 1] = DIGITS[i & 0x0F];}int i;// Generate the lookup table for hex dump paddingsfor (i = 0; i < HEXPADDING.length; i++) {int padding = HEXPADDING.length - i;StringBuilder buf = new StringBuilder(padding * 3);for (int j = 0; j < padding; j++) {buf.append("   ");}HEXPADDING[i] = buf.toString();}// Generate the lookup table for the start-offset header in each row (up to 64KiB).for (i = 0; i < HEXDUMP_ROWPREFIXES.length; i++) {StringBuilder buf = new StringBuilder(12);buf.append(NEWLINE);buf.append(Long.toHexString(i << 4 & 0xFFFFFFFFL | 0x100000000L));buf.setCharAt(buf.length() - 9, '|');buf.append('|');HEXDUMP_ROWPREFIXES[i] = buf.toString();}// Generate the lookup table for byte-to-hex-dump conversionfor (i = 0; i < BYTE2HEX.length; i++) {BYTE2HEX[i] = ' ' + StringUtil.byteToHexStringPadded(i);}// Generate the lookup table for byte dump paddingsfor (i = 0; i < BYTEPADDING.length; i++) {int padding = BYTEPADDING.length - i;StringBuilder buf = new StringBuilder(padding);for (int j = 0; j < padding; j++) {buf.append(' ');}BYTEPADDING[i] = buf.toString();}// Generate the lookup table for byte-to-char conversionfor (i = 0; i < BYTE2CHAR.length; i++) {if (i <= 0x1f || i >= 0x7f) {BYTE2CHAR[i] = '.';} else {BYTE2CHAR[i] = (char) i;}}}/*** 打印所有内容* @param buffer*/public static void debugAll(ByteBuffer buffer) {int oldlimit = buffer.limit();buffer.limit(buffer.capacity());StringBuilder origin = new StringBuilder(256);appendPrettyHexDump(origin, buffer, 0, buffer.capacity());System.out.println("+--------+-------------------- all ------------------------+----------------+");System.out.printf("position: [%d], limit: [%d]\n", buffer.position(), oldlimit);System.out.println(origin);buffer.limit(oldlimit);}/*** 打印可读取内容* @param buffer*/public static void debugRead(ByteBuffer buffer) {StringBuilder builder = new StringBuilder(256);appendPrettyHexDump(builder, buffer, buffer.position(), buffer.limit() - buffer.position());System.out.println("+--------+-------------------- read -----------------------+----------------+");System.out.printf("position: [%d], limit: [%d]\n", buffer.position(), buffer.limit());System.out.println(builder);}private static void appendPrettyHexDump(StringBuilder dump, ByteBuffer buf, int offset, int length) {if (isOutOfBounds(offset, length, buf.capacity())) {throw new IndexOutOfBoundsException("expected: " + "0 <= offset(" + offset + ") <= offset + length(" + length+ ") <= " + "buf.capacity(" + buf.capacity() + ')');}if (length == 0) {return;}dump.append("         +-------------------------------------------------+" +NEWLINE + "         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |" +NEWLINE + "+--------+-------------------------------------------------+----------------+");final int startIndex = offset;final int fullRows = length >>> 4;final int remainder = length & 0xF;// Dump the rows which have 16 bytes.for (int row = 0; row < fullRows; row++) {int rowStartIndex = (row << 4) + startIndex;// Per-row prefix.appendHexDumpRowPrefix(dump, row, rowStartIndex);// Hex dumpint rowEndIndex = rowStartIndex + 16;for (int j = rowStartIndex; j < rowEndIndex; j++) {dump.append(BYTE2HEX[getUnsignedByte(buf, j)]);}dump.append(" |");// ASCII dumpfor (int j = rowStartIndex; j < rowEndIndex; j++) {dump.append(BYTE2CHAR[getUnsignedByte(buf, j)]);}dump.append('|');}// Dump the last row which has less than 16 bytes.if (remainder != 0) {int rowStartIndex = (fullRows << 4) + startIndex;appendHexDumpRowPrefix(dump, fullRows, rowStartIndex);// Hex dumpint rowEndIndex = rowStartIndex + remainder;for (int j = rowStartIndex; j < rowEndIndex; j++) {dump.append(BYTE2HEX[getUnsignedByte(buf, j)]);}dump.append(HEXPADDING[remainder]);dump.append(" |");// Ascii dumpfor (int j = rowStartIndex; j < rowEndIndex; j++) {dump.append(BYTE2CHAR[getUnsignedByte(buf, j)]);}dump.append(BYTEPADDING[remainder]);dump.append('|');}dump.append(NEWLINE +"+--------+-------------------------------------------------+----------------+");}private static void appendHexDumpRowPrefix(StringBuilder dump, int row, int rowStartIndex) {if (row < HEXDUMP_ROWPREFIXES.length) {dump.append(HEXDUMP_ROWPREFIXES[row]);} else {dump.append(NEWLINE);dump.append(Long.toHexString(rowStartIndex & 0xFFFFFFFFL | 0x100000000L));dump.setCharAt(dump.length() - 9, '|');dump.append('|');}}public static short getUnsignedByte(ByteBuffer buffer, int index) {return (short) (buffer.get(index) & 0xFF);}
}

测试类

package cn.itcast.netty.c1;import java.nio.ByteBuffer;import static cn.itcast.netty.c1.ByteBufferUtil.debugAll;public class TestByteBufferReadWrite {public static void main(String[] args) {ByteBuffer byteBuffer=ByteBuffer.allocate(10);byteBuffer.put((byte)0x61);debugAll(byteBuffer);byteBuffer.put(new byte[]{0x62,0x63,0x64});debugAll(byteBuffer);//System.out.println(byteBuffer.get());byteBuffer.flip();System.out.println(byteBuffer.get());debugAll(byteBuffer);byteBuffer.compact();debugAll(byteBuffer);byteBuffer.put(new byte[]{0x65,0x66,0x67});debugAll(byteBuffer);}
}
15:35:14.029 [main] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
+--------+-------------------- all ------------------------+----------------+
position: [1], limit: [10]+-------------------------------------------------+0         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |0+--------+-------------------------------------------------+----------------+0|00000000| 61 00 00 00 00 00 00 00 00 00                   |a.........      |0+--------+-------------------------------------------------+----------------+
+--------+-------------------- all ------------------------+----------------+
position: [4], limit: [10]+-------------------------------------------------+0         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |0+--------+-------------------------------------------------+----------------+0|00000000| 61 62 63 64 00 00 00 00 00 00                   |abcd......      |0+--------+-------------------------------------------------+----------------+
97
+--------+-------------------- all ------------------------+----------------+
position: [1], limit: [4]+-------------------------------------------------+0         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |0+--------+-------------------------------------------------+----------------+0|00000000| 61 62 63 64 00 00 00 00 00 00                   |abcd......      |0+--------+-------------------------------------------------+----------------+
+--------+-------------------- all ------------------------+----------------+
position: [3], limit: [10]+-------------------------------------------------+0         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |0+--------+-------------------------------------------------+----------------+0|00000000| 62 63 64 64 00 00 00 00 00 00                   |bcdd......      |0+--------+-------------------------------------------------+----------------+
+--------+-------------------- all ------------------------+----------------+
position: [6], limit: [10]+-------------------------------------------------+0         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |0+--------+-------------------------------------------------+----------------+0|00000000| 62 63 64 65 66 67 00 00 00 00                   |bcdefg....      |0+--------+-------------------------------------------------+----------------+Process finished with exit code 0

测试类

package cn.itcast.netty.c1;import java.nio.ByteBuffer;import static cn.itcast.netty.c1.ByteBufferUtil.debugAll;public class TestByteBufferRead {public static void main(String[] args) {ByteBuffer buffer = ByteBuffer.allocate(10);buffer.put(new byte[]{'a', 'b', 'c','d'});buffer.flip();byte[] bytes = new byte[4];buffer.get(bytes);for(int i=0;i<bytes.length;i++){System.out.println(bytes[i]);}debugAll(buffer);buffer.rewind();//rewind 方法将 position 重新置为 0byte b = buffer.get();System.out.println(b);}
}
97
98
99
100
19:50:47.673 [main] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
+--------+-------------------- all ------------------------+----------------+
position: [4], limit: [4]+-------------------------------------------------+0         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |0+--------+-------------------------------------------------+----------------+0|00000000| 61 62 63 64 00 00 00 00 00 00                   |abcd......      |0+--------+-------------------------------------------------+----------------+
97

测试类

public class TestByteBufferRead {public static void main(String[] args) {ByteBuffer buffer = ByteBuffer.allocate(10);buffer.put(new byte[]{'a', 'b', 'c','d'});buffer.flip();/*byte[] bytes = new byte[4];buffer.get(bytes);for(int i=0;i<bytes.length;i++){System.out.println(bytes[i]);}debugAll(buffer);buffer.rewind();byte b = buffer.get();System.out.println(b);*/System.out.println(buffer.get());System.out.println(buffer.get());buffer.mark();//标记System.out.println(buffer.get());System.out.println(buffer.get());buffer.reset();System.out.println(buffer.get());System.out.println(buffer.get());}
}
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;import static cn.itcast.netty.c1.ByteBufferUtil.debugAll;public class ScatteringReads {public static void main(String[] args) {try (RandomAccessFile file = new RandomAccessFile("parts.txt", "r")) {FileChannel channel = file.getChannel();ByteBuffer a = ByteBuffer.allocate(3);ByteBuffer b = ByteBuffer.allocate(3);ByteBuffer c = ByteBuffer.allocate(5);channel.read(new ByteBuffer[]{a, b, c});a.flip();b.flip();c.flip();debugAll(a);debugAll(b);debugAll(c);} catch (IOException e) {e.printStackTrace();}}}
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;public class GatheringWrites {public static void main(String[] args) {ByteBuffer hello = StandardCharsets.UTF_8.encode("hello");ByteBuffer world = StandardCharsets.UTF_8.encode("world");ByteBuffer nihao = StandardCharsets.UTF_8.encode("你好");try (FileChannel rw = new RandomAccessFile("world.txt", "rw").getChannel()) {rw.write(new ByteBuffer []{hello,world,nihao});//生成world.txt,字符串helloworld你好} catch (IOException e) {}}
}

4.bytebuffer-黏半包解析

import java.nio.ByteBuffer;import static cn.itcast.netty.c1.ByteBufferUtil.debugAll;public class TestByteBufferExam {public static void main(String[] args) {ByteBuffer source = ByteBuffer.allocate(32);//                     11            24source.put("Hello,world\nI'm zhangsan\nHo".getBytes());split(source);source.put("w are you?\n".getBytes());split(source);}private static void split(ByteBuffer source) {source.flip();for(int i=0;i<source.limit();i++){if(source.get(i)=='\n'){int length= i+1-source.position();ByteBuffer allocate = ByteBuffer.allocate(length);for(int j=0;j<length;j++){allocate.put(source.get());}debugAll(allocate);}}source.compact();}}
        +-------------------------------------------------+0         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |0+--------+-------------------------------------------------+----------------+0|00000000| 48 65 6c 6c 6f 2c 77 6f 72 6c 64 0a             |Hello,world.    |0+--------+-------------------------------------------------+----------------+
+--------+-------------------- all ------------------------+----------------+
position: [13], limit: [13]+-------------------------------------------------+0         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |0+--------+-------------------------------------------------+----------------+0|00000000| 49 27 6d 20 7a 68 61 6e 67 73 61 6e 0a          |I'm zhangsan.   |0+--------+-------------------------------------------------+----------------+
+--------+-------------------- all ------------------------+----------------+
position: [13], limit: [13]+-------------------------------------------------+0         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |0+--------+-------------------------------------------------+----------------+0|00000000| 48 6f 77 20 61 72 65 20 79 6f 75 3f 0a          |How are you?.   |0+--------+-------------------------------------------------+----------------+
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
//
public class TestChannel {public static void main(String[] args) {try (FileChannel from = new FileInputStream("data.txt").getChannel();FileChannel to=new FileOutputStream("to.txt").getChannel();){from.transferTo(0,from.size(),to);} catch (IOException e) {e.printStackTrace();}}
}

Server

import lombok.extern.slf4j.Slf4j;import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketOption;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;import static cn.itcast.netty.c1.ByteBufferUtil.debugRead;
@Slf4j
public class Server {public static void main(String[] args) throws IOException {//创建selector,管理多个channel//Selector selector= Selector.open();ByteBuffer buffer = ByteBuffer.allocate(16);//1.创建了服务器ServerSocketChannel ssc = ServerSocketChannel.open();ssc.configureBlocking(false);//非阻塞模式//建立selector和channel的联系////SelectionKey sscKey = ssc.register(selector, 0, null);//2.绑定监听端口ssc.bind(new InetSocketAddress(8080));List<SocketChannel> channel = new ArrayList<>();while (true) {//log.debug("connecting");//3.建立与客户端连接,SocketChannel用来与客户端通信SocketChannel sc = ssc.accept();//阻塞方法,线程停止运行if(sc!=null) {log.debug("connected...{}", sc);sc.configureBlocking(false);channel.add(sc);}for (SocketChannel socketChannel : channel) {//log.debug("before read...{}", channel);int read = socketChannel.read(buffer);//阻塞方法,线程停止运行if(read>0) {buffer.flip();debugRead(buffer);buffer.clear();log.debug("after read...{}", channel);}}}}
}

Client

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;public class Client {public static void main(String[] args) throws IOException {SocketChannel sc=SocketChannel.open();sc.connect(new InetSocketAddress("localhost",8080));System.out.println("waiting");}
}

黑马程序员Netty全套教程,全网最全Netty深入浅出教程,Java网络编程的王者相关推荐

  1. k8s之Pod详解(五)【Kubernetes(K8S) 入门进阶实战完整教程,黑马程序员K8S全套教程(基础+高级)】

    参考于Kubernetes(K8S) 入门进阶实战完整教程,黑马程序员K8S全套教程(基础+高级) Pod Pod的结构 每个Pod中都可以包含一个或者多个容器 这些容器可以分为两类: 用户自定义用的 ...

  2. [学习笔记]黑马程序员Spark全套视频教程,4天spark3.2快速入门到精通,基于Python语言的spark教程

    文章目录 视频资料: 思维导图 一.Spark基础入门(环境搭建.入门概念) 第二章:Spark环境搭建-Local 2.1 课程服务器环境 2.2 Local模式基本原理 2.3 安装包下载 2.4 ...

  3. Java程序员从笨鸟到菜鸟之(十三)java网络通信编程

    首先声明一下,刚开始学习Java网络通信编程就对他有一种畏惧感,因为自己对网络一窍不通,所以...呵呵..你懂得,昨天又仔细的学习了一遍,感觉其实java网络编程也没想象的那么难,不信,咱一起看看.. ...

  4. 【JAVA黑马程序员笔记】四 P314到P384(特殊流、多线程编程、网络编程模块、lambda表达式、接口组成更新、方法引用、函数式接口)

    P314-315 字节/符打印流 PrintStream ps = new PrintStream("test.txt");//使用字节输出流的方法ps.write(97);// ...

  5. 黑马程序员——ios面试学习一:Mac系统使用教程——黑马 ios 技术博客

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 学习Mac从这里开始!!!   谢谢大家热烈支持, 感动! 你们的支持是我更新的动力!大家留言说 ...

  6. 2023年黑马程序员Java学习路线图

    2023年Java学科免费学习资源放送40+套课程,超过600小时的内容! 在过去的一年里,为了帮助更多人线上充电,学会更多技能,黑马程序员举办了 150+ 场免费直播公开课,新增精品视频教程 80+ ...

  7. 黑马程序员——JavaScript基础1(初识 JavaScript)

    文章目录 一.初识 JavaScript 1.1 JavaScript 是什么 1.2 JavaScript 的作用 1.3 HTML/CSS/JS 的关系 1.4 浏览器执行 JS 简介 1.5 J ...

  8. 黑马程序员:Xcode8网盘下载链接及更新简述

    6月14日,苹果公司在WWDC 大会上公布了四大系统watchOS 3,tvOS,macOS Sierra和iOS 10.但既然是开发者大会,就一定会有除系统本身之外,对iOS开发技术上的内容更新.所 ...

  9. 黑马程序员——c语言学习心得——函数传递二维数组

    黑马程序员--c语言学习心得--函数传递二维数组 -------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.定义指针的时候一定要初始化.    变量 ...

  10. 黑马程序员前端培训深圳首期班火爆开班

    黑马程序员在北京开设前端学科以来,其火爆程度远远超出了预期.面对市场的强烈需求,黑马程序员前端学院历时三年研发的大前端课程火爆登陆深圳,受到广大学员的热烈追捧,于2016年8月8日正式在深圳校区开班, ...

最新文章

  1. java.lang.Class
  2. 图神经网络在生物医药领域的12项研究综述
  3. dfs题目这样去接题,秒杀leetcode题目
  4. Google AI 教育项目今起免费开放,支持中文
  5. IAR7.51提示秘钥无效IAR 以及 CCDebug驱动(包含win7 64bit)
  6. POS机移动刷卡机自适应网站源码 dedecms织梦模板
  7. Struts2中Action的属性接收参数
  8. Spring Boot + JPA +MySQL 数据操作及示例环境搭建(手动建表建类)
  9. log4j2日志配置
  10. Pr 入门教程,如何创建标题?
  11. 用一个div模拟textarea的实现【前端每日一题-15】
  12. java 编程思想 阅读笔记(1)
  13. win7 exfat补丁_大神面对 win7系统安装补丁提示安装程序出错的操作方案 -win7系统使用教程...
  14. TortoiseSVN回退版本
  15. Creo曲面基础知识
  16. 桥接模式---汽车导航
  17. Pytorch将数据集划分为训练集、验证集和测试集
  18. 基金定投 | 微笑曲线
  19. HDU 6045 Is Derek lying?
  20. 最通俗易懂的网络安全防护原则之进不来、拿不走、看不懂、改不了、跑不掉。

热门文章

  1. Unbuntu下U盘突然权限只读,无法重命名和复制粘贴文件的问题修复
  2. borlndmm.dll(宝兰妹妹)DELPHI核心DLL之一简单分析
  3. Dropping Balls, UVa679
  4. 史上超级详细:银行外包java面试题目
  5. Delta RPMs disabled because /usr/bin/applydeltarpm not installed
  6. 32位cpu和64位cpu对内存地址和内存单元的差别
  7. 大数据战略能不能打造第二个百度?
  8. 各地2022年上半年软考考试疫情防控要求汇总-2022-05更新
  9. python爬虫入门实战之爬取美国体育网篮球比赛数据(selenium+xpath)
  10. 利用Crimestat(犯罪统计)软件进行空间分析