- 浏览: 25480 次
- 性别:
- 来自: 深圳
-
文章分类
- 全部博客 (18)
- Ajax+DWR (0)
- CallCenter+Asterisk (0)
- EJB+RMI (0)
- Hadoop并行计算 (0)
- HTML+CSS (0)
- J2EE (0)
- Java基础 (2)
- JMS (0)
- JS+jQuery (2)
- JSF (0)
- Linux+Shell+Python (0)
- NoSQL+MongoDB+Cassandra (0)
- Spider+Lucene+solr+nutch (2)
- Spring (0)
- SQL+MySQL (0)
- Web Service+Hessian (0)
- 个人生活 (0)
- 其他 (0)
- 学习心得 (1)
- 工作感悟 (5)
- 服务器+Tomcat+Jetty (0)
- 缓存+Memcached+Redis (1)
- 网络开发+Mina+Netty (3)
- 设计模式 (2)
- 重构 (0)
最新评论
-
xuzhou530:
为什么int length = buffer.readInt( ...
使用Netty实现通用二进制协议的高效数据传输 -
xuzhou530:
我使用你上面的代码启动服务端没有问题,启动客户端出现了下面问题 ...
使用Netty实现通用二进制协议的高效数据传输 -
xuzhou530:
哦哦,谢谢,了
使用Netty实现通用二进制协议的高效数据传输 -
drager:
<div class="quote_title ...
使用Netty实现通用二进制协议的高效数据传输 -
xuzhou530:
XLCharSetFactory这个类没有呀,这个类干嘛的
使用Netty实现通用二进制协议的高效数据传输
Netty是一个高性能的NIO通信框架,提供异步的、事件驱动的网络编程模型。使用Netty可以方便用户开发各种常用协议的网络程序。例如:TCP、UDP、HTTP等等。
Netty的最新版本是3.2.7,官网地址是:http://www.jboss.org/netty
本文的主要目的是基于Netty实现一个通用二进制协议的高效数据传输。协议是通用的二进制协议,高效并且扩展性很好。
一个好的协议有两个标准:
(1)生成的传输数据要少,即数据压缩比要高。这样可以减少网络开销。
(2)传输数据和业务对象之间的转换速度要快。
(友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hankchen)
一、协议的定义
无论是请求还是响应,报文都由一个通用报文头和实际数据组成。报文头在前,数据在后。
(1)报文头:由数据解析类型,数据解析方法,编码,扩展字节,包长度组成,共16个字节:
编码方式(1byte)、加密(1byte)、扩展1(1byte)、扩展2(1byte)、会话ID(4byte)、命令或者结果码(4byte)、数据包长(4byte)
(2)数据:由数据包长指定。请求或回复数据。类型对应为JAVA的Map<String,String>
数据格式定义:
字段1键名长度 字段1键名 字段1值长度 字段1值
字段2键名长度 字段2键名 字段2值长度 字段2值
字段3键名长度 字段3键名 字段3值长度 字段3值
… … … …
长度为整型,占4个字节
代码中用两个Vo对象来表示:XLRequest和XLResponse。

2

3

4

5

6


7

10

11

12

13

14


15

16

17

18


19

20

21

22

23

24

25

26

27

28

29

30

31

32



33

34

35

36

37

38

39

40

41

42

43

44

45



46

47

48

49



50



51

52

53

54

55

56



57

58

59

60



61

62

63

64



65

66

67

68



69

70

71

72



73

74

75

76



77

78

79

80



81

82

83

84



85

86

87

88



89

90

91

92



93

94

95

96



97

98

99

100



101

102

103

104



105

106

107

108



109

110

111

112



113

114

115

116



117

118

119

120



121

122

123

124



125

126

127

128

129



130

131

132

133


2

3

4

5

6


7

8

9

10

11


12

13

14

15


16

17

18

19

20

21

22

23

24

25

26

27

28

29



30

31

32

33

34

35

36

37

38

39

40

41

42



43

44

45

46



47

48

49

50



51

52

53

54



55

56

57

58



59

60

61

62



63

64

65

66



67

68

69

70



71

72

73

74



75

76

77

78



79

80

81

82



83

84

85

86



87

88

89

90



91

92

93

94



95

96

97

98



99

100

101

102



103

104

105

106



107



108

109

110

111

112

113



114

115

116

117



118

119

120

121



122

123

124

125

126



127

128

129

130

131

二、协议的编码和解码
对于自定义二进制协议,编码解码器往往是Netty开发的重点。这里直接给出相关类的代码。

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16


17

18

19

20

21


22

23

24



25

26

27

28



29

30

31


32

33

34

35

36

37

38

39

40

41


42

43

44

45

46

47


48

49

50

51

52

53

54

55

56

57

58

59

60

61


2

3

4

5

6

7

8

9

10

11


12

13

14

15

16


17

18

19



20

21

22



23



24

25

26

27

28

29

30

31

32

33

34



35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54


2

3

4

5

6

7

8

9

10

11

12

13


14

15

16

17



18

19


20

21

22

23

24

25



26

27



28

29

30

31

32



33

34

35

36

37

38

39

40

41

42

43

44



45

46

47

48

49

50

51


52

53

54

55

56

57



58

59



60

61

62



63


64

65

66

67

68

69

70

71


72

73

74

75

76

77

78

79

80

81

82

83

84

85


86

87

88

89

90



91


92

93

94

95

96



97

98

99



100

101

102

103

104



105

106

107

108

109

110

三、服务器端实现
服务器端提供的功能是:
1、接收客户端的请求(非关闭命令),返回XLResponse类型的数据。
2、如果客户端的请求是关闭命令:shutdown,则服务器端关闭自身进程。
为了展示多协议的运用,这里客户端的请求采用的是基于问本行(\n\r)的协议。
具体代码如下:

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21


22

23

24

25

26



27

28

29

30

31

32



33



34

35



36

37

38

39

40



41


42

43

44

45

46

47


48

49

50

51

52

53

54

55

56

57

58


59

60

61

62

63

64

65

66

67



68



69


70

71

72

73

74

75



76

77

78

79



80

81

82

83

84

85


2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17


18

19

20

21

22

23



24

25

26

27



28

29



30

31

32



33

34

35



36

37

38



39

40

41

42

43

44

45



46

47

48

49

50

51

52



53

54

55

56

57

58



59

60

61

62

63

64

65



66

67

68

69

70

71



72

73

74

75

76

77


78

79

80

81

82

83



84

85

86

87

88

89

90

91

92


93

94

95

96

97

98

99

100

四、客户端实现
客户端的功能是连接服务器,发送10次请求,然后发送关闭服务器的命令,最后主动关闭客户端。
关键代码如下:


2

3

4

5

6

7


8

9

10

11

12



13

14

15

16

17

18

19


20

21

22

23



24

25

26

27

28


29

30

31

32

33



34


35

36

37

38

39

40

41


42

43

44

45

46

47

48


49

50

51

52


53

54

55

56



57

58



59

60

61

62

63

64


65

66

67

68

69



70



71


72

73

74

75

76


77

78

79

80

81

82



83

84

85

86



87

88

89

90

91




2

3

4



5

6


7

8

9

10

11


12

13

14

15

16

17

18



2

3

4

5

6

7


8

9

10

11

12



13

14

15

16

17



18

19

20

21


22

23

24

25

26



27

28

29

30

31

32



33

34

35



36

37

38

39

40

41

42



43

44

45

46

47

48

49



50

51

52

53

54

55

全文代码较多,写了很多注释,希望对读者有用,谢谢!
(友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hankchen)
评论
int length = buffer.readInt(); // 数据包长
if (buffer.readableBytes() < length) {
buffer.resetReaderIndex();
return null;
}
一直都会进入这里?
INFO ( XLServer) server is started on port 8080
INFO (XLServerHandler) channelOpen
INFO (XLServerHandler) channelConnected
接受到信息writeRequested:XLResponse [encode=0, encrypt=0, extend=0, extend =0, sessionid=0, result=1, length=0, values={time=1374653003832, age=-182129588, name=hankchen}, ip=null]
ERROR(XLServerHandler) charsetName
java.lang.NullPointerException: charsetName
at com.factory.XLCharSetFactory.getCharset(XLCharSetFactory.java:25)
at com.util.ProtocolUtil.encode(ProtocolUtil.java:33)
at com.codec.XLServerEncoder.writeRequested(XLServerEncoder.java:46)
at org.jboss.netty.channel.Channels.write(Channels.java:611)
at org.jboss.netty.channel.Channels.write(Channels.java:578)
at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:251)
at com.handle.XLServerHandler.sendResponse(XLServerHandler.java:104)
at com.handle.XLServerHandler.channelConnected(XLServerHandler.java:58)
at org.jboss.netty.handler.codec.oneone.OneToOneDecoder.handleUpstream(OneToOneDecoder.java:66)
at org.jboss.netty.channel.Channels.fireChannelConnected(Channels.java:233)
at org.jboss.netty.channel.socket.nio.NioAcceptedSocketChannel.<init>(NioAcceptedSocketChannel.java:53)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink$Boss.registerAcceptedChannel(NioServerSocketPipelineSink.java:285)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink$Boss.run(NioServerSocketPipelineSink.java:249)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
我给你补充一下这个类吧
package org.jboss.netty.example.xlsvr.factory;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
public class XLCharSetFactory {
static String[] charsetArray={"UTF-8","GBK","GB2312","ISO8859-1"};
/**
* :0:UTF-8,1:GBK,2:GB2312,3:ISO8859-1
* @param encode
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
*/
public static Charset getCharset(int encode) {
Charset charset=null;
if (encode == 0)
throw new NullPointerException("charsetName");
try {
switch(encode)
{
case 0:
charset = Charset.forName(charsetArray[0]);
break;
case 1:
charset = Charset.forName(charsetArray[1]);
break;
case 2:
charset = Charset.forName(charsetArray[2]);
break;
case 3:
charset = Charset.forName(charsetArray[3]);
break;
}
} catch (IllegalCharsetNameException e) {
e.printStackTrace();
} catch (UnsupportedCharsetException e) {
e.printStackTrace();
}
return charset;
}
}
相关推荐
它借鉴了多种协议(如FTP、SMTP、HTTP等)的实现经验,融合了二进制和文本协议的处理技巧,形成了一套既高效又易于使用的网络编程框架。 与其他类似框架相比,Netty的独特之处在于其设计哲学的贯彻——始终以用户...
- **广泛的协议支持**: 凭借其灵活的架构,Netty可以轻松支持各种网络协议,包括但不限于HTTP、FTP、SMTP等常见协议,以及各种自定义的二进制或文本协议。 #### 四、Netty实践入门 **1. 开发环境准备** - **Netty...
在面对需要处理大量并发连接和高效数据传输的场景时,传统的通用协议和实现往往无法满足需求。例如,HTTP 服务器可能不适应大规模文件传输或实时消息传递的需求。这时,Netty 提供了一个解决方案,它允许开发者定制...
- **Google Protocol Buffers整合**:讨论了Netty如何与Google Protocol Buffers结合使用,以实现高效的序列化和反序列化。 - **总述**:总结了本章中介绍的主要内容,为读者提供了一个关于Netty架构的全面理解。 ...
RTU模式是MODBUS协议的一种变体,它使用二进制格式传输数据,不包含每个字符的起始和结束标识,因此具有更高的传输效率。在RTU模式下,数据以连续的8位字节流形式发送,每两个字节之间用1.5个停止位隔开,以确保数据...
Netty的出现解决了通用协议库在大规模、高并发场景下的局限性,使得开发者能够快速构建针对特定需求的高度优化的协议实现。 Netty的核心特性在于它的异步事件驱动模型,这一模型基于Java的非阻塞I/O(NIO)API。...
在Dubbo中,传输层扮演着数据传输媒介的角色,确保请求和响应能够在分布式环境中准确无误地传递。在这个实现中,Dubbo选择了Netty作为基础网络库,因为Netty是一个高性能、异步事件驱动的网络应用框架,适用于快速...
- **JSON**:通用的数据交换格式,易于阅读和编写,但相对于二进制序列化协议,效率较低。 - **Hessian**:轻量级的二进制RPC协议,适合内部服务间通信。 - **Msgpack**:另一种高效的二进制序列化协议。 在选择...
Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...
Java 中将对象转化为 byte 数组的方法是指将 Java 对象序列化为二进制数据流,以便在网络上传输或存储。这种方法可以应用于各种领域,如分布式计算、网络通信、数据存储等。 在 Java 中,对象转化为 byte 数组通常...
1. **网络通信**:Hadoop Common包含了一套基于Socket的网络通信组件,如Netty,用于节点间的高效数据传输。这些组件支持TCP/IP协议,确保了Hadoop集群内的节点能够快速、稳定地进行数据交互。 2. **I/O处理**:...
Dubbo默认使用Hessian作为序列化框架,这是一种二进制协议,具有轻量级、快速的特点。此外,还可以选择Duddo、FastJson和Java自带的序列化机制。Hessian通过HTTP POST方式传输数据,将辅助信息封装在HTTP头中,核心...
- **dubbo-common**:这是一个通用模块,包含了Dubbo框架共用的工具类,如IO处理、日志、配置、类处理等,以及线程池、二进制编码、JSON处理、数据存储接口等。这个模块为其他模块提供了基础支持。 - **dubbo-rpc-...
protobuf是Google的一种数据序列化协议,可以将结构化数据转化为二进制格式,便于网络传输。Java开发者可以通过protobuf编译器(protoc)将.proto文件转换为Java代码,其中包含了用于GRPC通信的Stub类。 2. **...
- **网络通信**: Hadoop Common提供了网络通信库,如Socket和Netty,用于节点间的通信,如数据传输、心跳检查和任务调度。 - **安全机制**: 支持Kerberos等认证和授权机制,以确保Hadoop集群的安全性。 - **日志...
Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...
Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...
Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...
Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...