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