1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.core.bio.udp;
21
22 import java.io.IOException;
23 import java.net.InetSocketAddress;
24 import java.nio.ByteBuffer;
25
26 import org.apache.mina.api.IdleStatus;
27 import org.apache.mina.api.IoHandler;
28 import org.apache.mina.api.IoService;
29 import org.apache.mina.api.IoSession;
30 import org.apache.mina.core.BenchmarkServer;
31 import org.apache.mina.core.nio.udp.Mina3UdpBenchmarkServer;
32 import org.apache.mina.session.AttributeKey;
33 import org.apache.mina.transport.bio.BioUdpServer;
34 import org.apache.mina.transport.udp.DefaultUdpSessionConfig;
35 import org.apache.mina.transport.udp.UdpSessionConfig;
36
37
38
39
40
41
42 public class BioUdpBenchmarkServer implements BenchmarkServer {
43 private static enum State {
44 WAIT_FOR_FIRST_BYTE_LENGTH, WAIT_FOR_SECOND_BYTE_LENGTH, WAIT_FOR_THIRD_BYTE_LENGTH, WAIT_FOR_FOURTH_BYTE_LENGTH, READING
45 }
46
47 private static final ByteBuffer ACK = ByteBuffer.allocate(1);
48
49 static {
50 ACK.put((byte) 0);
51 ACK.rewind();
52 }
53
54 private static final AttributeKey<State> STATE_ATTRIBUTE = new AttributeKey<State>(State.class,
55 Mina3UdpBenchmarkServer.class.getName() + ".state");
56
57 private static final AttributeKey<Integer> LENGTH_ATTRIBUTE = new AttributeKey<Integer>(Integer.class,
58 Mina3UdpBenchmarkServer.class.getName() + ".length");
59
60 private BioUdpServer udpServer;
61
62
63
64
65 @Override
66 public void start(int port) throws IOException {
67 UdpSessionConfig config = new DefaultUdpSessionConfig();
68 config.setReadBufferSize(65536);
69 udpServer = new BioUdpServer(config, null);
70 udpServer.setIoHandler(new IoHandler() {
71 @Override
72 public void sessionOpened(IoSession session) {
73 session.setAttribute(STATE_ATTRIBUTE, State.WAIT_FOR_FIRST_BYTE_LENGTH);
74 }
75
76 @Override
77 public void messageReceived(IoSession session, Object message) {
78
79 if (message instanceof ByteBuffer) {
80 ByteBuffer buffer = (ByteBuffer) message;
81
82 State state = session.getAttribute(STATE_ATTRIBUTE);
83 int length = 0;
84
85 if (session.getAttribute(LENGTH_ATTRIBUTE) != null) {
86 length = session.getAttribute(LENGTH_ATTRIBUTE);
87 }
88
89 while (buffer.remaining() > 0) {
90 switch (state) {
91 case WAIT_FOR_FIRST_BYTE_LENGTH:
92 length = (buffer.get() & 255) << 24;
93 state = State.WAIT_FOR_SECOND_BYTE_LENGTH;
94 break;
95 case WAIT_FOR_SECOND_BYTE_LENGTH:
96 length += (buffer.get() & 255) << 16;
97 state = State.WAIT_FOR_THIRD_BYTE_LENGTH;
98 break;
99 case WAIT_FOR_THIRD_BYTE_LENGTH:
100 length += (buffer.get() & 255) << 8;
101 state = State.WAIT_FOR_FOURTH_BYTE_LENGTH;
102 break;
103 case WAIT_FOR_FOURTH_BYTE_LENGTH:
104 length += (buffer.get() & 255);
105 state = State.READING;
106 if ((length == 0) && (buffer.remaining() == 0)) {
107 session.write(ACK.slice());
108 state = State.WAIT_FOR_FIRST_BYTE_LENGTH;
109 }
110 break;
111 case READING:
112 int remaining = buffer.remaining();
113 if (length > remaining) {
114 length -= remaining;
115 buffer.position(buffer.position() + remaining);
116 } else {
117 buffer.position(buffer.position() + length);
118 session.write(ACK.slice());
119 state = State.WAIT_FOR_FIRST_BYTE_LENGTH;
120 length = 0;
121 }
122 }
123 }
124 session.setAttribute(LENGTH_ATTRIBUTE, length);
125 session.setAttribute(STATE_ATTRIBUTE, state);
126 }
127 }
128
129 @Override
130 public void exceptionCaught(IoSession session, Exception cause) {
131 cause.printStackTrace();
132 }
133
134 @Override
135 public void sessionClosed(IoSession session) {
136 }
137
138 @Override
139 public void sessionIdle(IoSession session, IdleStatus status) {
140 }
141
142 @Override
143 public void messageSent(IoSession session, Object message) {
144
145 }
146
147 @Override
148 public void serviceActivated(IoService service) {
149 }
150
151 @Override
152 public void serviceInactivated(IoService service) {
153 }
154 });
155
156 udpServer.bind(new InetSocketAddress(port));
157 }
158
159
160
161
162 @Override
163 public void stop() throws IOException {
164 udpServer.unbind();
165 }
166 }