64 /* to prevent starvation when listening on two sockets, this is |
64 /* to prevent starvation when listening on two sockets, this is |
65 * is used to hold the id of the last socket we accepted on. |
65 * is used to hold the id of the last socket we accepted on. |
66 */ |
66 */ |
67 private int lastfd = -1; |
67 private int lastfd = -1; |
68 |
68 |
|
69 // true if this socket is exclusively bound |
|
70 private final boolean exclusiveBind; |
|
71 |
|
72 // emulates SO_REUSEADDR when exclusiveBind is true |
|
73 private boolean isReuseAddress; |
|
74 |
69 static { |
75 static { |
70 initProto(); |
76 initProto(); |
71 } |
77 } |
72 |
78 |
73 public TwoStacksPlainSocketImpl() {} |
79 public TwoStacksPlainSocketImpl(boolean exclBind) { |
74 |
80 exclusiveBind = exclBind; |
75 public TwoStacksPlainSocketImpl(FileDescriptor fd) { |
81 } |
|
82 |
|
83 public TwoStacksPlainSocketImpl(FileDescriptor fd, boolean exclBind) { |
76 this.fd = fd; |
84 this.fd = fd; |
|
85 exclusiveBind = exclBind; |
77 } |
86 } |
78 |
87 |
79 /** |
88 /** |
80 * Creates a socket with a boolean that specifies whether this |
89 * Creates a socket with a boolean that specifies whether this |
81 * is a stream socket (true) or an unconnected UDP socket (false). |
90 * is a stream socket (true) or an unconnected UDP socket (false). |
114 return anyLocalBoundAddr; |
123 return anyLocalBoundAddr; |
115 } |
124 } |
116 InetAddressContainer in = new InetAddressContainer(); |
125 InetAddressContainer in = new InetAddressContainer(); |
117 socketGetOption(opt, in); |
126 socketGetOption(opt, in); |
118 return in.addr; |
127 return in.addr; |
|
128 } else if (opt == SO_REUSEADDR && exclusiveBind) { |
|
129 // SO_REUSEADDR emulated when using exclusive bind |
|
130 return isReuseAddress; |
119 } else |
131 } else |
120 return super.getOption(opt); |
132 return super.getOption(opt); |
121 } |
133 } |
122 |
134 |
|
135 @Override |
|
136 void socketBind(InetAddress address, int port) throws IOException { |
|
137 socketBind(address, port, exclusiveBind); |
|
138 } |
|
139 |
|
140 @Override |
|
141 void socketSetOption(int opt, boolean on, Object value) |
|
142 throws SocketException |
|
143 { |
|
144 // SO_REUSEADDR emulated when using exclusive bind |
|
145 if (opt == SO_REUSEADDR && exclusiveBind) |
|
146 isReuseAddress = on; |
|
147 else |
|
148 socketNativeSetOption(opt, on, value); |
|
149 } |
|
150 |
123 /** |
151 /** |
124 * Closes the socket. |
152 * Closes the socket. |
125 */ |
153 */ |
|
154 @Override |
126 protected void close() throws IOException { |
155 protected void close() throws IOException { |
127 synchronized(fdLock) { |
156 synchronized(fdLock) { |
128 if (fd != null || fd1 != null) { |
157 if (fd != null || fd1 != null) { |
129 if (!stream) { |
158 if (!stream) { |
130 ResourceManager.afterUdpClose(); |
159 ResourceManager.afterUdpClose(); |
188 native void socketCreate(boolean isServer) throws IOException; |
219 native void socketCreate(boolean isServer) throws IOException; |
189 |
220 |
190 native void socketConnect(InetAddress address, int port, int timeout) |
221 native void socketConnect(InetAddress address, int port, int timeout) |
191 throws IOException; |
222 throws IOException; |
192 |
223 |
193 native void socketBind(InetAddress address, int port) |
224 native void socketBind(InetAddress address, int port, boolean exclBind) |
194 throws IOException; |
225 throws IOException; |
195 |
226 |
196 native void socketListen(int count) throws IOException; |
227 native void socketListen(int count) throws IOException; |
197 |
228 |
198 native void socketAccept(SocketImpl s) throws IOException; |
229 native void socketAccept(SocketImpl s) throws IOException; |
201 |
232 |
202 native void socketClose0(boolean useDeferredClose) throws IOException; |
233 native void socketClose0(boolean useDeferredClose) throws IOException; |
203 |
234 |
204 native void socketShutdown(int howto) throws IOException; |
235 native void socketShutdown(int howto) throws IOException; |
205 |
236 |
206 native void socketSetOption(int cmd, boolean on, Object value) |
237 native void socketNativeSetOption(int cmd, boolean on, Object value) |
207 throws SocketException; |
238 throws SocketException; |
208 |
239 |
209 native int socketGetOption(int opt, Object iaContainerObj) throws SocketException; |
240 native int socketGetOption(int opt, Object iaContainerObj) throws SocketException; |
210 |
241 |
211 native void socketSendUrgentData(int data) throws IOException; |
242 native void socketSendUrgentData(int data) throws IOException; |