1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.testsuite.transport.socket;
17
18 import io.netty.bootstrap.Bootstrap;
19 import io.netty.buffer.ByteBuf;
20 import io.netty.channel.Channel;
21 import io.netty.channel.ChannelFuture;
22 import io.netty.channel.ChannelHandlerAdapter;
23 import io.netty.channel.ChannelHandlerContext;
24 import io.netty.channel.ChannelInitializer;
25 import io.netty.channel.SimpleChannelInboundHandler;
26 import io.netty.channel.socket.DatagramChannel;
27 import io.netty.channel.socket.DatagramPacket;
28 import org.junit.jupiter.api.Test;
29 import org.junit.jupiter.api.TestInfo;
30
31 import java.net.InetSocketAddress;
32 import java.net.SocketAddress;
33 import java.util.concurrent.CountDownLatch;
34 import java.util.concurrent.atomic.AtomicReference;
35
36 import static org.junit.jupiter.api.Assertions.assertEquals;
37 import static org.junit.jupiter.api.Assertions.assertNotNull;
38
39 public class DatagramUnicastInetTest extends DatagramUnicastTest {
40
41 @Test
42 public void testBindWithPortOnly(TestInfo testInfo) throws Throwable {
43 run(testInfo, new Runner<Bootstrap, Bootstrap>() {
44 @Override
45 public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
46 testBindWithPortOnly(bootstrap2);
47 }
48 });
49 }
50
51 private static void testBindWithPortOnly(Bootstrap cb) throws Throwable {
52 Channel channel = null;
53 try {
54 cb.handler(new ChannelHandlerAdapter() { });
55 channel = cb.bind(0).sync().channel();
56 } finally {
57 closeChannel(channel);
58 }
59 }
60
61 @Override
62 protected boolean isConnected(Channel channel) {
63 return ((DatagramChannel) channel).isConnected();
64 }
65
66 @Override
67 protected Channel setupClientChannel(Bootstrap cb, final byte[] bytes, final CountDownLatch latch,
68 final AtomicReference<Throwable> errorRef) throws Throwable {
69 cb.handler(new SimpleChannelInboundHandler<DatagramPacket>() {
70
71 @Override
72 public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) {
73 try {
74 ByteBuf buf = msg.content();
75 assertEquals(bytes.length, buf.readableBytes());
76 for (int i = 0; i < bytes.length; i++) {
77 assertEquals(bytes[i], buf.getByte(buf.readerIndex() + i));
78 }
79
80 InetSocketAddress localAddress = (InetSocketAddress) ctx.channel().localAddress();
81 if (localAddress.getAddress().isAnyLocalAddress()) {
82 assertEquals(localAddress.getPort(), msg.recipient().getPort());
83 } else {
84
85 assertEquals(localAddress, msg.recipient());
86 }
87 } finally {
88 latch.countDown();
89 }
90 }
91
92 @Override
93 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
94 errorRef.compareAndSet(null, cause);
95 }
96 });
97 return cb.bind(newSocketAddress()).sync().channel();
98 }
99
100 @Override
101 protected Channel setupServerChannel(Bootstrap sb, final byte[] bytes, final SocketAddress sender,
102 final CountDownLatch latch, final AtomicReference<Throwable> errorRef,
103 final boolean echo) throws Throwable {
104 sb.handler(new ChannelInitializer<Channel>() {
105 @Override
106 protected void initChannel(Channel ch) {
107 ch.pipeline().addLast(new SimpleChannelInboundHandler<DatagramPacket>() {
108
109 @Override
110 public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) {
111 try {
112 if (sender == null) {
113 assertNotNull(msg.sender());
114 } else {
115 InetSocketAddress senderAddress = (InetSocketAddress) sender;
116 if (senderAddress.getAddress().isAnyLocalAddress()) {
117 assertEquals(senderAddress.getPort(), msg.sender().getPort());
118 } else {
119 assertEquals(sender, msg.sender());
120 }
121 }
122
123 ByteBuf buf = msg.content();
124 assertEquals(bytes.length, buf.readableBytes());
125 for (int i = 0; i < bytes.length; i++) {
126 assertEquals(bytes[i], buf.getByte(buf.readerIndex() + i));
127 }
128
129
130 assertEquals(ctx.channel().localAddress(), msg.recipient());
131
132 if (echo) {
133 ctx.writeAndFlush(new DatagramPacket(buf.retainedDuplicate(), msg.sender()));
134 }
135 } finally {
136 latch.countDown();
137 }
138 }
139
140 @Override
141 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
142 errorRef.compareAndSet(null, cause);
143 }
144 });
145 }
146 });
147 return sb.bind(newSocketAddress()).sync().channel();
148 }
149
150 @Override
151 protected boolean supportDisconnect() {
152 return true;
153 }
154
155 @Override
156 protected ChannelFuture write(Channel cc, ByteBuf buf, SocketAddress remote, WrapType wrapType) {
157 switch (wrapType) {
158 case DUP:
159 return cc.write(new DatagramPacket(buf.retainedDuplicate(), (InetSocketAddress) remote));
160 case SLICE:
161 return cc.write(new DatagramPacket(buf.retainedSlice(), (InetSocketAddress) remote));
162 case READ_ONLY:
163 return cc.write(new DatagramPacket(buf.retain().asReadOnly(), (InetSocketAddress) remote));
164 case NONE:
165 return cc.write(new DatagramPacket(buf.retain(), (InetSocketAddress) remote));
166 default:
167 throw new Error("unknown wrap type: " + wrapType);
168 }
169 }
170 }