1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.socket.nio;
17
18 import io.netty.channel.ChannelException;
19 import io.netty.channel.ChannelMetadata;
20 import io.netty.channel.ChannelOutboundBuffer;
21 import io.netty.util.internal.SocketUtils;
22 import io.netty.channel.nio.AbstractNioMessageChannel;
23 import io.netty.channel.socket.DefaultServerSocketChannelConfig;
24 import io.netty.channel.socket.ServerSocketChannelConfig;
25 import io.netty.util.internal.PlatformDependent;
26 import io.netty.util.internal.logging.InternalLogger;
27 import io.netty.util.internal.logging.InternalLoggerFactory;
28
29 import java.io.IOException;
30 import java.net.InetSocketAddress;
31 import java.net.ServerSocket;
32 import java.net.SocketAddress;
33 import java.nio.channels.SelectionKey;
34 import java.nio.channels.ServerSocketChannel;
35 import java.nio.channels.SocketChannel;
36 import java.nio.channels.spi.SelectorProvider;
37 import java.util.List;
38
39
40
41
42
43 public class NioServerSocketChannel extends AbstractNioMessageChannel
44 implements io.netty.channel.socket.ServerSocketChannel {
45
46 private static final ChannelMetadata METADATA = new ChannelMetadata(false);
47 private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();
48
49 private static final InternalLogger logger = InternalLoggerFactory.getInstance(NioServerSocketChannel.class);
50
51 private static ServerSocketChannel newSocket(SelectorProvider provider) {
52 try {
53
54
55
56
57
58
59 return provider.openServerSocketChannel();
60 } catch (IOException e) {
61 throw new ChannelException(
62 "Failed to open a server socket.", e);
63 }
64 }
65
66 private final ServerSocketChannelConfig config;
67
68
69
70
71 public NioServerSocketChannel() {
72 this(newSocket(DEFAULT_SELECTOR_PROVIDER));
73 }
74
75
76
77
78 public NioServerSocketChannel(SelectorProvider provider) {
79 this(newSocket(provider));
80 }
81
82
83
84
85 public NioServerSocketChannel(ServerSocketChannel channel) {
86 super(null, channel, SelectionKey.OP_ACCEPT);
87 config = new NioServerSocketChannelConfig(this, javaChannel().socket());
88 }
89
90 @Override
91 public InetSocketAddress localAddress() {
92 return (InetSocketAddress) super.localAddress();
93 }
94
95 @Override
96 public ChannelMetadata metadata() {
97 return METADATA;
98 }
99
100 @Override
101 public ServerSocketChannelConfig config() {
102 return config;
103 }
104
105 @Override
106 public boolean isActive() {
107 return javaChannel().socket().isBound();
108 }
109
110 @Override
111 public InetSocketAddress remoteAddress() {
112 return null;
113 }
114
115 @Override
116 protected ServerSocketChannel javaChannel() {
117 return (ServerSocketChannel) super.javaChannel();
118 }
119
120 @Override
121 protected SocketAddress localAddress0() {
122 return SocketUtils.localSocketAddress(javaChannel().socket());
123 }
124
125 @Override
126 protected void doBind(SocketAddress localAddress) throws Exception {
127 if (PlatformDependent.javaVersion() >= 7) {
128 javaChannel().bind(localAddress, config.getBacklog());
129 } else {
130 javaChannel().socket().bind(localAddress, config.getBacklog());
131 }
132 }
133
134 @Override
135 protected void doClose() throws Exception {
136 javaChannel().close();
137 }
138
139 @Override
140 protected int doReadMessages(List<Object> buf) throws Exception {
141 SocketChannel ch = SocketUtils.accept(javaChannel());
142
143 try {
144 if (ch != null) {
145 buf.add(new NioSocketChannel(this, ch));
146 return 1;
147 }
148 } catch (Throwable t) {
149 logger.warn("Failed to create a new channel from an accepted socket.", t);
150
151 try {
152 ch.close();
153 } catch (Throwable t2) {
154 logger.warn("Failed to close a socket.", t2);
155 }
156 }
157
158 return 0;
159 }
160
161
162 @Override
163 protected boolean doConnect(
164 SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
165 throw new UnsupportedOperationException();
166 }
167
168 @Override
169 protected void doFinishConnect() throws Exception {
170 throw new UnsupportedOperationException();
171 }
172
173 @Override
174 protected SocketAddress remoteAddress0() {
175 return null;
176 }
177
178 @Override
179 protected void doDisconnect() throws Exception {
180 throw new UnsupportedOperationException();
181 }
182
183 @Override
184 protected boolean doWriteMessage(Object msg, ChannelOutboundBuffer in) throws Exception {
185 throw new UnsupportedOperationException();
186 }
187
188 @Override
189 protected final Object filterOutboundMessage(Object msg) throws Exception {
190 throw new UnsupportedOperationException();
191 }
192
193 private final class NioServerSocketChannelConfig extends DefaultServerSocketChannelConfig {
194 private NioServerSocketChannelConfig(NioServerSocketChannel channel, ServerSocket javaSocket) {
195 super(channel, javaSocket);
196 }
197
198 @Override
199 protected void autoReadCleared() {
200 setReadPending(false);
201 }
202 }
203 }