Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
ec347b32
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ec347b32
编写于
8月 31, 2008
作者:
A
alanb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
4640544: New I/O: Complete socket-channel functionality
Reviewed-by: iris, sherman, chegar
上级
70763cd4
变更
61
隐藏空白更改
内联
并排
Showing
61 changed file
with
5728 addition
and
1508 deletion
+5728
-1508
make/java/nio/FILES_java.gmk
make/java/nio/FILES_java.gmk
+13
-6
make/java/nio/Makefile
make/java/nio/Makefile
+32
-13
make/java/nio/mapfile-linux
make/java/nio/mapfile-linux
+37
-4
make/java/nio/mapfile-solaris
make/java/nio/mapfile-solaris
+37
-4
make/mksample/nio/Makefile
make/mksample/nio/Makefile
+1
-1
make/mksample/nio/multicast/Makefile
make/mksample/nio/multicast/Makefile
+24
-11
src/share/classes/java/net/NetworkInterface.java
src/share/classes/java/net/NetworkInterface.java
+0
-1
src/share/classes/java/net/ProtocolFamily.java
src/share/classes/java/net/ProtocolFamily.java
+39
-0
src/share/classes/java/net/SocketOption.java
src/share/classes/java/net/SocketOption.java
+55
-0
src/share/classes/java/net/StandardProtocolFamily.java
src/share/classes/java/net/StandardProtocolFamily.java
+45
-0
src/share/classes/java/net/StandardSocketOption.java
src/share/classes/java/net/StandardSocketOption.java
+352
-0
src/share/classes/java/nio/channels/DatagramChannel.java
src/share/classes/java/nio/channels/DatagramChannel.java
+137
-20
src/share/classes/java/nio/channels/MembershipKey.java
src/share/classes/java/nio/channels/MembershipKey.java
+183
-0
src/share/classes/java/nio/channels/MulticastChannel.java
src/share/classes/java/nio/channels/MulticastChannel.java
+211
-0
src/share/classes/java/nio/channels/NetworkChannel.java
src/share/classes/java/nio/channels/NetworkChannel.java
+158
-0
src/share/classes/java/nio/channels/ServerSocketChannel.java
src/share/classes/java/nio/channels/ServerSocketChannel.java
+111
-16
src/share/classes/java/nio/channels/SocketChannel.java
src/share/classes/java/nio/channels/SocketChannel.java
+126
-24
src/share/classes/java/nio/channels/exceptions
src/share/classes/java/nio/channels/exceptions
+11
-0
src/share/classes/java/nio/channels/package-info.java
src/share/classes/java/nio/channels/package-info.java
+231
-0
src/share/classes/java/nio/channels/package.html
src/share/classes/java/nio/channels/package.html
+0
-222
src/share/classes/java/nio/channels/spi/SelectorProvider.java
...share/classes/java/nio/channels/spi/SelectorProvider.java
+20
-4
src/share/classes/sun/nio/ch/DatagramChannelImpl.java
src/share/classes/sun/nio/ch/DatagramChannelImpl.java
+436
-61
src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
+72
-36
src/share/classes/sun/nio/ch/ExtendedSocketOption.java
src/share/classes/sun/nio/ch/ExtendedSocketOption.java
+44
-0
src/share/classes/sun/nio/ch/MembershipKeyImpl.java
src/share/classes/sun/nio/ch/MembershipKeyImpl.java
+222
-0
src/share/classes/sun/nio/ch/MembershipRegistry.java
src/share/classes/sun/nio/ch/MembershipRegistry.java
+129
-0
src/share/classes/sun/nio/ch/Net.java
src/share/classes/sun/nio/ch/Net.java
+340
-30
src/share/classes/sun/nio/ch/OptionAdaptor.java
src/share/classes/sun/nio/ch/OptionAdaptor.java
+0
-229
src/share/classes/sun/nio/ch/OptionKey.java
src/share/classes/sun/nio/ch/OptionKey.java
+48
-0
src/share/classes/sun/nio/ch/SelectorProviderImpl.java
src/share/classes/sun/nio/ch/SelectorProviderImpl.java
+5
-1
src/share/classes/sun/nio/ch/ServerSocketAdaptor.java
src/share/classes/sun/nio/ch/ServerSocketAdaptor.java
+25
-13
src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
+71
-31
src/share/classes/sun/nio/ch/SocketAdaptor.java
src/share/classes/sun/nio/ch/SocketAdaptor.java
+82
-44
src/share/classes/sun/nio/ch/SocketChannelImpl.java
src/share/classes/sun/nio/ch/SocketChannelImpl.java
+141
-64
src/share/classes/sun/nio/ch/SocketOptsImpl.java
src/share/classes/sun/nio/ch/SocketOptsImpl.java
+0
-318
src/share/native/java/net/net_util.c
src/share/native/java/net/net_util.c
+2
-2
src/share/native/java/net/net_util.h
src/share/native/java/net/net_util.h
+3
-3
src/share/native/sun/nio/ch/genSocketOptionRegistry.c
src/share/native/sun/nio/ch/genSocketOptionRegistry.c
+129
-0
src/share/sample/nio/multicast/MulticastAddress.java
src/share/sample/nio/multicast/MulticastAddress.java
+127
-0
src/share/sample/nio/multicast/Reader.java
src/share/sample/nio/multicast/Reader.java
+142
-0
src/share/sample/nio/multicast/Sender.java
src/share/sample/nio/multicast/Sender.java
+71
-0
src/solaris/native/java/net/net_util_md.c
src/solaris/native/java/net/net_util_md.c
+1
-1
src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
+2
-2
src/solaris/native/sun/nio/ch/FileKey.c
src/solaris/native/sun/nio/ch/FileKey.c
+0
-6
src/solaris/native/sun/nio/ch/Net.c
src/solaris/native/sun/nio/ch/Net.c
+371
-121
src/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c
src/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c
+0
-8
src/solaris/native/sun/nio/ch/SocketChannelImpl.c
src/solaris/native/sun/nio/ch/SocketChannelImpl.c
+0
-13
src/solaris/native/sun/nio/ch/nio_util.h
src/solaris/native/sun/nio/ch/nio_util.h
+7
-0
src/windows/native/java/net/net_util_md.c
src/windows/native/java/net/net_util_md.c
+1
-1
src/windows/native/sun/nio/ch/DatagramChannelImpl.c
src/windows/native/sun/nio/ch/DatagramChannelImpl.c
+43
-105
src/windows/native/sun/nio/ch/Net.c
src/windows/native/sun/nio/ch/Net.c
+330
-64
src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c
src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c
+8
-18
src/windows/native/sun/nio/ch/SocketChannelImpl.c
src/windows/native/sun/nio/ch/SocketChannelImpl.c
+0
-9
test/java/nio/channels/DatagramChannel/BasicMulticastTests.java
...ava/nio/channels/DatagramChannel/BasicMulticastTests.java
+220
-0
test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java
...o/channels/DatagramChannel/MulticastSendReceiveTests.java
+220
-0
test/java/nio/channels/DatagramChannel/NetworkConfiguration.java
...va/nio/channels/DatagramChannel/NetworkConfiguration.java
+97
-0
test/java/nio/channels/DatagramChannel/SocketOptionTests.java
.../java/nio/channels/DatagramChannel/SocketOptionTests.java
+115
-0
test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java
...a/nio/channels/ServerSocketChannel/SocketOptionTests.java
+84
-0
test/java/nio/channels/SocketChannel/SocketOptionTests.java
test/java/nio/channels/SocketChannel/SocketOptionTests.java
+129
-0
test/java/nio/channels/TestUtil.java
test/java/nio/channels/TestUtil.java
+1
-2
test/java/nio/channels/etc/NetworkChannelTests.java
test/java/nio/channels/etc/NetworkChannelTests.java
+187
-0
未找到文件。
make/java/nio/FILES_java.gmk
浏览文件 @
ec347b32
...
@@ -39,6 +39,9 @@ FILES_src = \
...
@@ -39,6 +39,9 @@ FILES_src = \
java/nio/channels/FileLock.java \
java/nio/channels/FileLock.java \
java/nio/channels/GatheringByteChannel.java \
java/nio/channels/GatheringByteChannel.java \
java/nio/channels/InterruptibleChannel.java \
java/nio/channels/InterruptibleChannel.java \
java/nio/channels/MembershipKey.java \
java/nio/channels/MulticastChannel.java \
java/nio/channels/NetworkChannel.java \
java/nio/channels/ReadableByteChannel.java \
java/nio/channels/ReadableByteChannel.java \
java/nio/channels/ScatteringByteChannel.java \
java/nio/channels/ScatteringByteChannel.java \
java/nio/channels/SelectableChannel.java \
java/nio/channels/SelectableChannel.java \
...
@@ -73,6 +76,7 @@ FILES_src = \
...
@@ -73,6 +76,7 @@ FILES_src = \
sun/nio/ch/DatagramSocketAdaptor.java \
sun/nio/ch/DatagramSocketAdaptor.java \
sun/nio/ch/DefaultSelectorProvider.java \
sun/nio/ch/DefaultSelectorProvider.java \
sun/nio/ch/DirectBuffer.java \
sun/nio/ch/DirectBuffer.java \
sun/nio/ch/ExtendedSocketOption.java \
sun/nio/ch/FileChannelImpl.java \
sun/nio/ch/FileChannelImpl.java \
sun/nio/ch/FileDispatcher.java \
sun/nio/ch/FileDispatcher.java \
sun/nio/ch/FileKey.java \
sun/nio/ch/FileKey.java \
...
@@ -80,12 +84,14 @@ FILES_src = \
...
@@ -80,12 +84,14 @@ FILES_src = \
sun/nio/ch/IOUtil.java \
sun/nio/ch/IOUtil.java \
sun/nio/ch/IOStatus.java \
sun/nio/ch/IOStatus.java \
sun/nio/ch/IOVecWrapper.java \
sun/nio/ch/IOVecWrapper.java \
sun/nio/ch/MembershipKeyImpl.java \
sun/nio/ch/MembershipRegistry.java \
sun/nio/ch/NativeDispatcher.java \
sun/nio/ch/NativeDispatcher.java \
sun/nio/ch/NativeObject.java \
sun/nio/ch/NativeObject.java \
sun/nio/ch/NativeThread.java \
sun/nio/ch/NativeThread.java \
sun/nio/ch/NativeThreadSet.java \
sun/nio/ch/NativeThreadSet.java \
sun/nio/ch/Net.java \
sun/nio/ch/Net.java \
sun/nio/ch/Option
Adaptor
.java \
sun/nio/ch/Option
Key
.java \
sun/nio/ch/PipeImpl.java \
sun/nio/ch/PipeImpl.java \
sun/nio/ch/PollArrayWrapper.java \
sun/nio/ch/PollArrayWrapper.java \
sun/nio/ch/Reflect.java \
sun/nio/ch/Reflect.java \
...
@@ -99,8 +105,7 @@ FILES_src = \
...
@@ -99,8 +105,7 @@ FILES_src = \
sun/nio/ch/SocketAdaptor.java \
sun/nio/ch/SocketAdaptor.java \
sun/nio/ch/SocketChannelImpl.java \
sun/nio/ch/SocketChannelImpl.java \
sun/nio/ch/SocketDispatcher.java \
sun/nio/ch/SocketDispatcher.java \
sun/nio/ch/SocketOpts.java \
sun/nio/ch/SocketOptionRegistry.java \
sun/nio/ch/SocketOptsImpl.java \
sun/nio/ch/SourceChannelImpl.java \
sun/nio/ch/SourceChannelImpl.java \
sun/nio/ch/Util.java \
sun/nio/ch/Util.java \
\
\
...
@@ -240,6 +245,7 @@ FILES_gen_ex = \
...
@@ -240,6 +245,7 @@ FILES_gen_ex = \
java/nio/InvalidMarkException.java \
java/nio/InvalidMarkException.java \
java/nio/ReadOnlyBufferException.java \
java/nio/ReadOnlyBufferException.java \
\
\
java/nio/channels/AlreadyBoundException.java \
java/nio/channels/AlreadyConnectedException.java \
java/nio/channels/AlreadyConnectedException.java \
java/nio/channels/AsynchronousCloseException.java \
java/nio/channels/AsynchronousCloseException.java \
java/nio/channels/ClosedByInterruptException.java \
java/nio/channels/ClosedByInterruptException.java \
...
@@ -258,14 +264,15 @@ FILES_gen_ex = \
...
@@ -258,14 +264,15 @@ FILES_gen_ex = \
java/nio/channels/UnresolvedAddressException.java \
java/nio/channels/UnresolvedAddressException.java \
java/nio/channels/UnsupportedAddressTypeException.java \
java/nio/channels/UnsupportedAddressTypeException.java \
\
\
sun/nio/ch/AlreadyBoundException.java \
\
java/nio/charset/CharacterCodingException.java \
java/nio/charset/CharacterCodingException.java \
java/nio/charset/IllegalCharsetNameException.java \
java/nio/charset/IllegalCharsetNameException.java \
java/nio/charset/UnsupportedCharsetException.java
java/nio/charset/UnsupportedCharsetException.java
FILES_gen_csp = sun/nio/cs/StandardCharsets.java
FILES_gen_csp = sun/nio/cs/StandardCharsets.java
FILES_gen = $(FILES_gen_coder) $(FILES_gen_buffer) $(FILES_gen_ex) $(FILES_gen_csp)
FILES_gen_sor = sun/nio/ch/SocketOptionRegistry.java
FILES_gen = $(FILES_gen_coder) $(FILES_gen_buffer) $(FILES_gen_ex) \
$(FILES_gen_csp) $(FILES_gen_sor)
FILES_java = $(FILES_src) $(FILES_gen)
FILES_java = $(FILES_src) $(FILES_gen)
make/java/nio/Makefile
浏览文件 @
ec347b32
...
@@ -56,18 +56,18 @@ FILES_java += \
...
@@ -56,18 +56,18 @@ FILES_java += \
sun/nio/ch/DevPollSelectorProvider.java
\
sun/nio/ch/DevPollSelectorProvider.java
\
sun/nio/ch/InheritedChannel.java
\
sun/nio/ch/InheritedChannel.java
\
sun/nio/ch/PollSelectorProvider.java
\
sun/nio/ch/PollSelectorProvider.java
\
sun/nio/ch/PollSelectorImpl.java
sun/nio/ch/PollSelectorImpl.java
FILES_c
+=
\
FILES_c
+=
\
DevPollArrayWrapper.c
\
DevPollArrayWrapper.c
\
InheritedChannel.c
\
InheritedChannel.c
\
PollArrayWrapper
.c
\
NativeThread
.c
\
NativeThread
.c
PollArrayWrapper
.c
FILES_export
+=
\
FILES_export
+=
\
sun/nio/ch/DevPollArrayWrapper.java
\
sun/nio/ch/DevPollArrayWrapper.java
\
sun/nio/ch/InheritedChannel.java
\
sun/nio/ch/InheritedChannel.java
\
sun/nio/ch/NativeThread.java
sun/nio/ch/NativeThread.java
endif
# PLATFORM = solaris
endif
# PLATFORM = solaris
ifeq
($(PLATFORM), windows)
ifeq
($(PLATFORM), windows)
...
@@ -94,14 +94,14 @@ FILES_java += \
...
@@ -94,14 +94,14 @@ FILES_java += \
FILES_c
+=
\
FILES_c
+=
\
EPollArrayWrapper.c
\
EPollArrayWrapper.c
\
PollArrayWrapper.c
\
InheritedChannel.c
\
InheritedChannel.c
\
NativeThread.c
NativeThread.c
\
PollArrayWrapper.c
FILES_export
+=
\
FILES_export
+=
\
sun/nio/ch/EPollArrayWrapper.java
\
sun/nio/ch/EPollArrayWrapper.java
\
sun/nio/ch/InheritedChannel.java
\
sun/nio/ch/InheritedChannel.java
\
sun/nio/ch/NativeThread.java
sun/nio/ch/NativeThread.java
endif
# PLATFORM = linux
endif
# PLATFORM = linux
# Find platform-specific C source files
# Find platform-specific C source files
...
@@ -618,12 +618,6 @@ $(BUF_GEN)/%Exception.java: genExceptions.sh $(BUF_SRC)/exceptions
...
@@ -618,12 +618,6 @@ $(BUF_GEN)/%Exception.java: genExceptions.sh $(BUF_SRC)/exceptions
@
$(RM)
$@
.temp
@
$(RM)
$@
.temp
$(GEN_EX_CMD)
$(BUF_SRC)
/exceptions
$(BUF_GEN)
$(GEN_EX_CMD)
$(BUF_SRC)
/exceptions
$(BUF_GEN)
$(SCH_GEN)/%Exception.java
:
genExceptions.sh $(SCH_SRC)/exceptions
$
(
prep-target
)
@
$(RM)
$@
.temp
$(GEN_EX_CMD)
$(SCH_SRC)
/exceptions
$(SCH_GEN)
#
#
# Generated charset-provider classes
# Generated charset-provider classes
#
#
...
@@ -638,4 +632,29 @@ $(SCS_GEN)/StandardCharsets.java: genCharsetProvider.sh \
...
@@ -638,4 +632,29 @@ $(SCS_GEN)/StandardCharsets.java: genCharsetProvider.sh \
HASHER
=
"
$(BOOT_JAVA_CMD)
-jar
$(HASHER_JARFILE)
"
\
HASHER
=
"
$(BOOT_JAVA_CMD)
-jar
$(HASHER_JARFILE)
"
\
$(SH)
-e
genCharsetProvider.sh
$(SCS_SRC)
/standard-charsets
$(SCS_GEN)
$(SH)
-e
genCharsetProvider.sh
$(SCS_SRC)
/standard-charsets
$(SCS_GEN)
#
# Generated channel implementation classes.
# C source is compiled in TEMPDIR to avoid turds left by Windows compilers.
#
GENSOR_SRC
=
$(SHARE_SRC)
/native/sun/nio/ch/genSocketOptionRegistry.c
GENSOR_EXE
=
$(TEMPDIR)
/genSocketOptionRegistry
$(EXE_SUFFIX)
SOR_COPYRIGHT_YEARS
=
$(
shell
$(CAT)
$(GENSOR_SRC)
|
\
$(NAWK)
'/^.*Copyright.*Sun/ { print $$3
}
'
)
$(TEMPDIR)/$(GENSOR_SRC)
:
$(GENSOR_SRC)
$
(
install-file
)
$(GENSOR_EXE)
:
$(TEMPDIR)/$(GENSOR_SRC)
$
(
prep-target
)
(
$(CD)
$(TEMPDIR)
;
$(CC)
$(CPPFLAGS)
$(LDDFLAGS)
\
-o
genSocketOptionRegistry
$(EXE_SUFFIX)
$(GENSOR_SRC)
)
$(SCH_GEN)/SocketOptionRegistry.java
:
$(GENSOR_EXE)
$
(
prep-target
)
NAWK
=
"
$(NAWK)
"
SH
=
"
$(SH)
"
$(SH)
-e
addNotices.sh
$(SOR_COPYRIGHT_YEARS)
>
$@
$(GENSOR_EXE)
>>
$@
.PHONY
:
sources
.PHONY
:
sources
make/java/nio/mapfile-linux
浏览文件 @
ec347b32
#
# Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
SUNWprivate_1.1 {
SUNWprivate_1.1 {
global:
global:
...
@@ -61,20 +85,29 @@ SUNWprivate_1.1 {
...
@@ -61,20 +85,29 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_signal;
Java_sun_nio_ch_NativeThread_signal;
Java_sun_nio_ch_Net_socket0;
Java_sun_nio_ch_Net_socket0;
Java_sun_nio_ch_Net_bind;
Java_sun_nio_ch_Net_bind0;
Java_sun_nio_ch_Net_connect;
Java_sun_nio_ch_Net_connect0;
Java_sun_nio_ch_Net_listen;
Java_sun_nio_ch_Net_localPort;
Java_sun_nio_ch_Net_localPort;
Java_sun_nio_ch_Net_localInetAddress;
Java_sun_nio_ch_Net_localInetAddress;
Java_sun_nio_ch_Net_getIntOption0;
Java_sun_nio_ch_Net_getIntOption0;
Java_sun_nio_ch_Net_setIntOption0;
Java_sun_nio_ch_Net_setIntOption0;
Java_sun_nio_ch_Net_initIDs;
Java_sun_nio_ch_Net_initIDs;
Java_sun_nio_ch_Net_isIPv6Available0;
Java_sun_nio_ch_Net_joinOrDrop4;
Java_sun_nio_ch_Net_blockOrUnblock4;
Java_sun_nio_ch_Net_joinOrDrop6;
Java_sun_nio_ch_Net_blockOrUnblock6;
Java_sun_nio_ch_Net_setInterface4;
Java_sun_nio_ch_Net_getInterface4;
Java_sun_nio_ch_Net_setInterface6;
Java_sun_nio_ch_Net_getInterface6;
Java_sun_nio_ch_Net_shutdown;
Java_sun_nio_ch_PollArrayWrapper_interrupt;
Java_sun_nio_ch_PollArrayWrapper_interrupt;
Java_sun_nio_ch_PollArrayWrapper_poll0;
Java_sun_nio_ch_PollArrayWrapper_poll0;
Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs;
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs;
Java_sun_nio_ch_ServerSocketChannelImpl_listen;
Java_sun_nio_ch_SocketChannelImpl_checkConnect;
Java_sun_nio_ch_SocketChannelImpl_checkConnect;
Java_sun_nio_ch_SocketChannelImpl_shutdown;
local:
local:
*;
*;
...
...
make/java/nio/mapfile-solaris
浏览文件 @
ec347b32
#
# Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
SUNWprivate_1.1 {
SUNWprivate_1.1 {
global:
global:
...
@@ -59,20 +83,29 @@ SUNWprivate_1.1 {
...
@@ -59,20 +83,29 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_signal;
Java_sun_nio_ch_NativeThread_signal;
Java_sun_nio_ch_Net_socket0;
Java_sun_nio_ch_Net_socket0;
Java_sun_nio_ch_Net_bind;
Java_sun_nio_ch_Net_bind0;
Java_sun_nio_ch_Net_connect;
Java_sun_nio_ch_Net_connect0;
Java_sun_nio_ch_Net_listen;
Java_sun_nio_ch_Net_localPort;
Java_sun_nio_ch_Net_localPort;
Java_sun_nio_ch_Net_localInetAddress;
Java_sun_nio_ch_Net_localInetAddress;
Java_sun_nio_ch_Net_getIntOption0;
Java_sun_nio_ch_Net_getIntOption0;
Java_sun_nio_ch_Net_setIntOption0;
Java_sun_nio_ch_Net_setIntOption0;
Java_sun_nio_ch_Net_initIDs;
Java_sun_nio_ch_Net_initIDs;
Java_sun_nio_ch_Net_isIPv6Available0;
Java_sun_nio_ch_Net_joinOrDrop4;
Java_sun_nio_ch_Net_blockOrUnblock4;
Java_sun_nio_ch_Net_joinOrDrop6;
Java_sun_nio_ch_Net_blockOrUnblock6;
Java_sun_nio_ch_Net_setInterface4;
Java_sun_nio_ch_Net_getInterface4;
Java_sun_nio_ch_Net_setInterface6;
Java_sun_nio_ch_Net_getInterface6;
Java_sun_nio_ch_Net_shutdown;
Java_sun_nio_ch_PollArrayWrapper_interrupt;
Java_sun_nio_ch_PollArrayWrapper_interrupt;
Java_sun_nio_ch_PollArrayWrapper_poll0;
Java_sun_nio_ch_PollArrayWrapper_poll0;
Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs;
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs;
Java_sun_nio_ch_ServerSocketChannelImpl_listen;
Java_sun_nio_ch_SocketChannelImpl_checkConnect;
Java_sun_nio_ch_SocketChannelImpl_checkConnect;
Java_sun_nio_ch_SocketChannelImpl_shutdown;
local:
local:
*;
*;
...
...
make/mksample/nio/Makefile
浏览文件 @
ec347b32
...
@@ -31,7 +31,7 @@ BUILDDIR = ../..
...
@@ -31,7 +31,7 @@ BUILDDIR = ../..
PRODUCT
=
java
PRODUCT
=
java
include
$(BUILDDIR)/common/Defs.gmk
include
$(BUILDDIR)/common/Defs.gmk
SUBDIRS
=
server
SUBDIRS
=
multicast
server
all build clean clobber
::
all build clean clobber
::
$
(
SUBDIRS-loop
)
$
(
SUBDIRS-loop
)
...
...
src/share/classes/sun/nio/ch/exceptions
→
make/mksample/nio/multicast/Makefile
浏览文件 @
ec347b32
#
#
# Copyright 200
0-200
7 Sun Microsystems, Inc. All Rights Reserved.
# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
#
# This code is free software; you can redistribute it and/or modify it
# This code is free software; you can redistribute it and/or modify it
...
@@ -23,17 +23,30 @@
...
@@ -23,17 +23,30 @@
# have any questions.
# have any questions.
#
#
# Generated exception classes for sun.nio.ch
#
# Makefile for the nio/multicast sample code
#
BUILDDIR
=
../../..
PRODUCT
=
java
include
$(BUILDDIR)/common/Defs.gmk
SAMPLE_SRC_DIR
=
$(SHARE_SRC)
/sample/nio/multicast
SAMPLE_DST_DIR
=
$(SAMPLEDIR)
/nio/multicast
SAMPLE_FILES
=
\
$(SAMPLE_DST_DIR)
/Reader.java
\
$(SAMPLE_DST_DIR)
/Sender.java
\
$(SAMPLE_DST_DIR)
/MulticastAddress.java
SINCE=1.4
all build
:
$(SAMPLE_FILES)
PACKAGE=sun.nio.ch
# This year should only change if the generated source is modified.
COPYRIGHT_YEARS=2000-2007
$(SAMPLE_DST_DIR)/%
:
$(SAMPLE_SRC_DIR)/%
$
(
install-file
)
SUPER=IllegalStateException
clean clobber
:
$(RM)
-r
$(SAMPLE_DST_DIR)
gen AlreadyBoundException "
.PHONY
:
all build clean clobber
* Unchecked exception thrown when an attempt is made to bind a {@link
* SocketChannel} that is already bound." \
9002280723481772026L
src/share/classes/java/net/NetworkInterface.java
浏览文件 @
ec347b32
...
@@ -25,7 +25,6 @@
...
@@ -25,7 +25,6 @@
package
java.net
;
package
java.net
;
import
java.net.SocketException
;
import
java.util.Enumeration
;
import
java.util.Enumeration
;
import
java.util.NoSuchElementException
;
import
java.util.NoSuchElementException
;
import
sun.security.action.*
;
import
sun.security.action.*
;
...
...
src/share/classes/java/net/ProtocolFamily.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
java.net
;
/**
* Represents a family of communication protocols.
*
* @since 1.7
*/
public
interface
ProtocolFamily
{
/**
* Returns the name of the protocol family.
*/
String
name
();
}
src/share/classes/java/net/SocketOption.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
java.net
;
/**
* A socket option associated with a socket.
*
* <p> In the {@link java.nio.channels channels} package, the {@link
* java.nio.channels.NetworkChannel} interface defines the {@link
* java.nio.channels.NetworkChannel#setOption(SocketOption,Object) setOption}
* and {@link java.nio.channels.NetworkChannel#getOption(SocketOption) getOption}
* methods to set and query the channel's socket options.
*
* @param <T> The type of the socket option value.
*
* @since 1.7
*
* @see StandardSocketOption
*/
public
interface
SocketOption
<
T
>
{
/**
* Returns the name of the socket option.
*/
String
name
();
/**
* Returns the type of the socket option value.
*/
Class
<
T
>
type
();
}
src/share/classes/java/net/StandardProtocolFamily.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
java.net
;
/**
* Defines the standard family of communication protocols.
*
* @since 1.7
*/
public
enum
StandardProtocolFamily
implements
ProtocolFamily
{
/**
* Internet Protocol Version 4 (IPv4)
*/
INET
,
/**
* Internet Protocol Version 6 (IPv6)
*/
INET6
}
src/share/classes/java/net/StandardSocketOption.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
java.net
;
/**
* Defines the <em>standard</em> socket options.
*
* <p> The {@link SocketOption#name name} of each socket option defined by this
* class is its field name.
*
* <p> In this release, the socket options defined here are used by {@link
* java.nio.channels.NetworkChannel network} channels in the {@link
* java.nio.channels channels} package.
*
* @since 1.7
*/
public
final
class
StandardSocketOption
{
private
StandardSocketOption
()
{
}
// -- SOL_SOCKET --
/**
* Allow transmission of broadcast datagrams.
*
* <p> The value of this socket option is a {@code Boolean} that represents
* whether the option is enabled or disabled. The option is specific to
* datagram-oriented sockets sending to {@link java.net.Inet4Address IPv4}
* broadcast addresses. When the socket option is enabled then the socket
* can be used to send <em>broadcast datagrams</em>.
*
* <p> The initial value of this socket option is {@code FALSE}. The socket
* option may be enabled or disabled at any time. Some operating systems may
* require that the Java virtual machine be started with implementation
* specific privileges to enable this option or send broadcast datagrams.
*
* @see <a href="http://www.ietf.org/rfc/rfc919.txt">RFC 929:
* Broadcasting Internet Datagrams</a>
*/
public
static
final
SocketOption
<
Boolean
>
SO_BROADCAST
=
new
StdSocketOption
<
Boolean
>(
"SO_BROADCAST"
,
Boolean
.
class
);
/**
* Keep connection alive.
*
* <p> The value of this socket option is a {@code Boolean} that represents
* whether the option is enabled or disabled. When the {@code SO_KEEPALIVE}
* option is enabled the operating system may use a <em>keep-alive</em>
* mechanism to periodically probe the other end of a connection when the
* connection is otherwise idle. The exact semantics of the keep alive
* mechanism is system dependent and therefore unspecified.
*
* <p> The initial value of this socket option is {@code FALSE}. The socket
* option may be enabled or disabled at any time.
*
* @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122
* Requirements for Internet Hosts -- Communication Layers</a>
*/
public
static
final
SocketOption
<
Boolean
>
SO_KEEPALIVE
=
new
StdSocketOption
<
Boolean
>(
"SO_KEEPALIVE"
,
Boolean
.
class
);
/**
* The size of the socket send buffer.
*
* <p> The value of this socket option is an {@code Integer} that is the
* size of the socket send buffer in bytes. The socket send buffer is an
* output buffer used by the networking implementation. It may need to be
* increased for high-volume connections. The value of the socket option is
* a <em>hint</em> to the implementation to size the buffer and the actual
* size may differ. The socket option can be queried to retrieve the actual
* size.
*
* <p> For datagram-oriented sockets, the size of the send buffer may limit
* the size of the datagrams that may be sent by the socket. Whether
* datagrams larger than the buffer size are sent or discarded is system
* dependent.
*
* <p> The initial/default size of the socket send buffer and the range of
* allowable values is system dependent although a negative size is not
* allowed. An attempt to set the socket send buffer to larger than its
* maximum size causes it to be set to its maximum size.
*
* <p> An implementation allows this socket option to be set before the
* socket is bound or connected. Whether an implementation allows the
* socket send buffer to be changed after the socket is bound is system
* dependent.
*/
public
static
final
SocketOption
<
Integer
>
SO_SNDBUF
=
new
StdSocketOption
<
Integer
>(
"SO_SNDBUF"
,
Integer
.
class
);
/**
* The size of the socket receive buffer.
*
* <p> The value of this socket option is an {@code Integer} that is the
* size of the socket receive buffer in bytes. The socket receive buffer is
* an input buffer used by the networking implementation. It may need to be
* increased for high-volume connections or decreased to limit the possible
* backlog of incoming data. The value of the socket option is a
* <em>hint</em> to the implementation to size the buffer and the actual
* size may differ.
*
* <p> For datagram-oriented sockets, the size of the receive buffer may
* limit the size of the datagrams that can be received. Whether datagrams
* larger than the buffer size can be received is system dependent.
* Increasing the socket receive buffer may be important for cases where
* datagrams arrive in bursts faster than they can be processed.
*
* <p> In the case of stream-oriented sockets and the TCP/IP protocol, the
* size of the socket receive buffer may be used when advertising the size
* of the TCP receive window to the remote peer.
*
* <p> The initial/default size of the socket receive buffer and the range
* of allowable values is system dependent although a negative size is not
* allowed. An attempt to set the socket receive buffer to larger than its
* maximum size causes it to be set to its maximum size.
*
* <p> An implementation allows this socket option to be set before the
* socket is bound or connected. Whether an implementation allows the
* socket receive buffer to be changed after the socket is bound is system
* dependent.
*
* @see <a href="http://www.ietf.org/rfc/rfc1323.txt">RFC 1323: TCP
* Extensions for High Performance</a>
*/
public
static
final
SocketOption
<
Integer
>
SO_RCVBUF
=
new
StdSocketOption
<
Integer
>(
"SO_RCVBUF"
,
Integer
.
class
);
/**
* Re-use address.
*
* <p> The value of this socket option is a {@code Boolean} that represents
* whether the option is enabled or disabled. The exact semantics of this
* socket option are socket type and system dependent.
*
* <p> In the case of stream-oriented sockets, this socket option will
* usually determine whether the socket can be bound to a socket address
* when a previous connection involving that socket address is in the
* <em>TIME_WAIT</em> state. On implementations where the semantics differ,
* and the socket option is not required to be enabled in order to bind the
* socket when a previous connection is in this state, then the
* implementation may choose to ignore this option.
*
* <p> For datagram-oriented sockets the socket option is used to allow
* multiple programs bind to the same address. This option should be enabled
* when the socket is to be used for Internet Protocol (IP) multicasting.
*
* <p> An implementation allows this socket option to be set before the
* socket is bound or connected. Changing the value of this socket option
* after the socket is bound has no effect. The default value of this
* socket option is system dependent.
*
* @see <a href="http://www.ietf.org/rfc/rfc793.txt">RFC 793: Transmission
* Control Protocol</a>
*/
public
static
final
SocketOption
<
Boolean
>
SO_REUSEADDR
=
new
StdSocketOption
<
Boolean
>(
"SO_REUSEADDR"
,
Boolean
.
class
);
/**
* Linger on close if data is present.
*
* <p> The value of this socket option is an {@code Integer} that controls
* the action taken when unsent data is queued on the socket and a method
* to close the socket is invoked. If the value of the socket option is zero
* or greater, then it represents a timeout value, in seconds, known as the
* <em>linger interval</em>. The linger interval is the timeout for the
* {@code close} method to block while the operating system attempts to
* transmit the unsent data or it decides that it is unable to transmit the
* data. If the value of the socket option is less than zero then the option
* is disabled. In that case the {@code close} method does not wait until
* unsent data is transmitted; if possible the operating system will transmit
* any unsent data before the connection is closed.
*
* <p> This socket option is intended for use with sockets that are configured
* in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode
* only. The behavior of the {@code close} method when this option is
* enabled on a non-blocking socket is not defined.
*
* <p> The initial value of this socket option is a negative value, meaning
* that the option is disabled. The option may be enabled, or the linger
* interval changed, at any time. The maximum value of the linger interval
* is system dependent. Setting the linger interval to a value that is
* greater than its maximum value causes the linger interval to be set to
* its maximum value.
*/
public
static
final
SocketOption
<
Integer
>
SO_LINGER
=
new
StdSocketOption
<
Integer
>(
"SO_LINGER"
,
Integer
.
class
);
// -- IPPROTO_IP --
/**
* The Type of Service (ToS) octet in the Internet Protocol (IP) header.
*
* <p> The value of this socket option is an {@code Integer}, the least
* significant 8 bits of which represents the value of the ToS octet in IP
* packets sent by sockets to an {@link StandardProtocolFamily#INET IPv4}
* socket. The interpretation of the ToS octet is network specific and
* is not defined by this class. Further information on the ToS octet can be
* found in <a href="http://www.ietf.org/rfc/rfc1349.txt">RFC 1349</a>
* and <a href="http://www.ietf.org/rfc/rfc2474.txt">RFC 2474</a>. The
* value of the socket option is a <em>hint</em>. An implementation may
* ignore the value, or ignore specific values.
*
* <p> The initial/default value of the TOS field in the ToS octet is
* implementation specific but will typically be {@code 0}. For
* datagram-oriented sockets the option may be configured at any time after
* the socket has been bound. The new value of the octet is used when sending
* subsequent datagrams. It is system dependent whether this option can be
* queried or changed prior to binding the socket.
*
* <p> The behavior of this socket option on a stream-oriented socket, or an
* {@link StandardProtocolFamily#INET6 IPv6} socket, is not defined in this
* release.
*/
public
static
final
SocketOption
<
Integer
>
IP_TOS
=
new
StdSocketOption
<
Integer
>(
"IP_TOS"
,
Integer
.
class
);
/**
* The network interface for Internet Protocol (IP) multicast datagrams.
*
* <p> The value of this socket option is a {@link NetworkInterface} that
* represents the outgoing interface for multicast datagrams sent by the
* datagram-oriented socket. For {@link StandardProtocolFamily#INET6 IPv6}
* sockets then it is system dependent whether setting this option also
* sets the outgoing interface for multlicast datagrams sent to IPv4
* addresses.
*
* <p> The initial/default value of this socket option may be {@code null}
* to indicate that outgoing interface will be selected by the operating
* system, typically based on the network routing tables. An implementation
* allows this socket option to be set after the socket is bound. Whether
* the socket option can be queried or changed prior to binding the socket
* is system dependent.
*
* @see java.nio.channels.MulticastChannel
*/
public
static
final
SocketOption
<
NetworkInterface
>
IP_MULTICAST_IF
=
new
StdSocketOption
<
NetworkInterface
>(
"IP_MULTICAST_IF"
,
NetworkInterface
.
class
);
/**
* The <em>time-to-live</em> for Internet Protocol (IP) multicast datagrams.
*
* <p> The value of this socket option is an {@code Integer} in the range
* <tt>0 <= value <= 255</tt>. It is used to control
* the scope of multicast datagrams sent by the datagram-oriented socket.
* In the case of an {@link StandardProtocolFamily#INET IPv4} socket
* the option is the time-to-live (TTL) on multicast datagrams sent by the
* socket. Datagrams with a TTL of zero are not transmitted on the network
* but may be delivered locally. In the case of an {@link
* StandardProtocolFamily#INET6 IPv6} socket the option is the
* <em>hop limit</em> which is number of <em>hops</em> that the datagram can
* pass through before expiring on the network. For IPv6 sockets it is
* system dependent whether the option also sets the <em>time-to-live</em>
* on multicast datagrams sent to IPv4 addresses.
*
* <p> The initial/default value of the time-to-live setting is typically
* {@code 1}. An implementation allows this socket option to be set after
* the socket is bound. Whether the socket option can be queried or changed
* prior to binding the socket is system dependent.
*
* @see java.nio.channels.MulticastChannel
*/
public
static
final
SocketOption
<
Integer
>
IP_MULTICAST_TTL
=
new
StdSocketOption
<
Integer
>(
"IP_MULTICAST_TTL"
,
Integer
.
class
);
/**
* Loopback for Internet Protocol (IP) multicast datagrams.
*
* <p> The value of this socket option is a {@code Boolean} that controls
* the <em>loopback</em> of multicast datagrams. The value of the socket
* option represents if the option is enabled or disabled.
*
* <p> The exact semantics of this socket options are system dependent.
* In particular, it is system dependent whether the loopback applies to
* multicast datagrams sent from the socket or received by the socket.
* For {@link StandardProtocolFamily#INET6 IPv6} sockets then it is
* system dependent whether the option also applies to multicast datagrams
* sent to IPv4 addresses.
*
* <p> The initial/default value of this socket option is {@code TRUE}. An
* implementation allows this socket option to be set after the socket is
* bound. Whether the socket option can be queried or changed prior to
* binding the socket is system dependent.
*
* @see java.nio.channels.MulticastChannel
*/
public
static
final
SocketOption
<
Boolean
>
IP_MULTICAST_LOOP
=
new
StdSocketOption
<
Boolean
>(
"IP_MULTICAST_LOOP"
,
Boolean
.
class
);
// -- IPPROTO_TCP --
/**
* Disable the Nagle algorithm.
*
* <p> The value of this socket option is a {@code Boolean} that represents
* whether the option is enabled or disabled. The socket option is specific to
* stream-oriented sockets using the TCP/IP protocol. TCP/IP uses an algorithm
* known as <em>The Nagle Algorithm</em> to coalesce short segments and
* improve network efficiency.
*
* <p> The default value of this socket option is {@code FALSE}. The
* socket option should only be enabled in cases where it is known that the
* coalescing impacts performance. The socket option may be enabled at any
* time. In other words, the Nagle Algorithm can be disabled. Once the option
* is enabled, it is system dependent whether it can be subsequently
* disabled. In that case, invoking the {@code setOption} method to disable
* the option has no effect.
*
* @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122:
* Requirements for Internet Hosts -- Communication Layers</a>
*/
public
static
final
SocketOption
<
Boolean
>
TCP_NODELAY
=
new
StdSocketOption
<
Boolean
>(
"TCP_NODELAY"
,
Boolean
.
class
);
private
static
class
StdSocketOption
<
T
>
implements
SocketOption
<
T
>
{
private
final
String
name
;
private
final
Class
<
T
>
type
;
StdSocketOption
(
String
name
,
Class
<
T
>
type
)
{
this
.
name
=
name
;
this
.
type
=
type
;
}
@Override
public
String
name
()
{
return
name
;
}
@Override
public
Class
<
T
>
type
()
{
return
type
;
}
@Override
public
String
toString
()
{
return
name
;
}
}
}
src/share/classes/java/nio/channels/DatagramChannel.java
浏览文件 @
ec347b32
...
@@ -26,28 +26,21 @@
...
@@ -26,28 +26,21 @@
package
java.nio.channels
;
package
java.nio.channels
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.net.ProtocolFamily
;
import
java.net.DatagramSocket
;
import
java.net.DatagramSocket
;
import
java.net.SocketOption
;
import
java.net.SocketAddress
;
import
java.net.SocketAddress
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.nio.channels.spi.*
;
import
java.nio.channels.spi.*
;
/**
/**
* A selectable channel for datagram-oriented sockets.
* A selectable channel for datagram-oriented sockets.
*
*
*
* <p> A datagram channel is created by invoking one of the {@link #open open} methods
* <p> Datagram channels are not a complete abstraction of network datagram
* of this class. It is not possible to create a channel for an arbitrary,
* sockets. Binding and the manipulation of socket options must be done
* pre-existing datagram socket. A newly-created datagram channel is open but not
* through an associated {@link java.net.DatagramSocket} object obtained by
* connected. A datagram channel need not be connected in order for the {@link #send
* invoking the {@link #socket() socket} method. It is not possible to create
* send} and {@link #receive receive} methods to be used. A datagram channel may be
* a channel for an arbitrary, pre-existing datagram socket, nor is it possible
* to specify the {@link java.net.DatagramSocketImpl} object to be used by a
* datagram socket associated with a datagram channel.
*
* <p> A datagram channel is created by invoking the {@link #open open} method
* of this class. A newly-created datagram channel is open but not connected.
* A datagram channel need not be connected in order for the {@link #send send}
* and {@link #receive receive} methods to be used. A datagram channel may be
* connected, by invoking its {@link #connect connect} method, in order to
* connected, by invoking its {@link #connect connect} method, in order to
* avoid the overhead of the security checks are otherwise performed as part of
* avoid the overhead of the security checks are otherwise performed as part of
* every send and receive operation. A datagram channel must be connected in
* every send and receive operation. A datagram channel must be connected in
...
@@ -59,11 +52,57 @@ import java.nio.channels.spi.*;
...
@@ -59,11 +52,57 @@ import java.nio.channels.spi.*;
* disconnected or closed. Whether or not a datagram channel is connected may
* disconnected or closed. Whether or not a datagram channel is connected may
* be determined by invoking its {@link #isConnected isConnected} method.
* be determined by invoking its {@link #isConnected isConnected} method.
*
*
* <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
* setOption} method. Datagram channels support the following options:
* <blockquote>
* <table border>
* <tr>
* <th>Option Name</th>
* <th>Description</th>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} </td>
* <td> The size of the socket send buffer </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
* <td> Re-use address </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_BROADCAST SO_BROADCAST} </td>
* <td> Allow transmission of broadcast datagrams </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#IP_TOS IP_TOS} </td>
* <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#IP_MULTICAST_IF IP_MULTICAST_IF} </td>
* <td> The network interface for Internet Protocol (IP) multicast datagrams </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#IP_MULTICAST_TTL
* IP_MULTICAST_TTL} </td>
* <td> The <em>time-to-live</em> for Internet Protocol (IP) multicast
* datagrams </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#IP_MULTICAST_LOOP
* IP_MULTICAST_LOOP} </td>
* <td> Loopback for Internet Protocol (IP) multicast datagrams </td>
* </tr>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported.
*
* <p> Datagram channels are safe for use by multiple concurrent threads. They
* <p> Datagram channels are safe for use by multiple concurrent threads. They
* support concurrent reading and writing, though at most one thread may be
* support concurrent reading and writing, though at most one thread may be
* reading and at most one thread may be writing at any given time. </p>
* reading and at most one thread may be writing at any given time. </p>
*
*
*
* @author Mark Reinhold
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @author JSR-51 Expert Group
* @since 1.4
* @since 1.4
...
@@ -71,7 +110,7 @@ import java.nio.channels.spi.*;
...
@@ -71,7 +110,7 @@ import java.nio.channels.spi.*;
public
abstract
class
DatagramChannel
public
abstract
class
DatagramChannel
extends
AbstractSelectableChannel
extends
AbstractSelectableChannel
implements
ByteChannel
,
ScatteringByteChannel
,
GatheringByteChannel
implements
ByteChannel
,
ScatteringByteChannel
,
GatheringByteChannel
,
MulticastChannel
{
{
/**
/**
...
@@ -88,7 +127,13 @@ public abstract class DatagramChannel
...
@@ -88,7 +127,13 @@ public abstract class DatagramChannel
* java.nio.channels.spi.SelectorProvider#openDatagramChannel()
* java.nio.channels.spi.SelectorProvider#openDatagramChannel()
* openDatagramChannel} method of the system-wide default {@link
* openDatagramChannel} method of the system-wide default {@link
* java.nio.channels.spi.SelectorProvider} object. The channel will not be
* java.nio.channels.spi.SelectorProvider} object. The channel will not be
* connected. </p>
* connected.
*
* <p> The {@link ProtocolFamily ProtocolFamily} of the channel's socket
* is platform (and possibly configuration) dependent and therefore unspecified.
* The {@link #open(ProtocolFamily) open} allows the protocol family to be
* selected when opening a datagram channel, and should be used to open
* datagram channels that are intended for Internet Protocol multicasting.
*
*
* @return A new datagram channel
* @return A new datagram channel
*
*
...
@@ -99,6 +144,39 @@ public abstract class DatagramChannel
...
@@ -99,6 +144,39 @@ public abstract class DatagramChannel
return
SelectorProvider
.
provider
().
openDatagramChannel
();
return
SelectorProvider
.
provider
().
openDatagramChannel
();
}
}
/**
* Opens a datagram channel.
*
* <p> The {@code family} parameter is used to specify the {@link
* ProtocolFamily}. If the datagram channel is to be used for IP multicasing
* then this should correspond to the address type of the multicast groups
* that this channel will join.
*
* <p> The new channel is created by invoking the {@link
* java.nio.channels.spi.SelectorProvider#openDatagramChannel(ProtocolFamily)
* openDatagramChannel} method of the system-wide default {@link
* java.nio.channels.spi.SelectorProvider} object. The channel will not be
* connected.
*
* @param family
* The protocol family
*
* @return A new datagram channel
*
* @throws UnsupportedOperationException
* If the specified protocol family is not supported. For example,
* suppose the parameter is specified as {@link
* java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6}
* but IPv6 is not enabled on the platform.
* @throws IOException
* If an I/O error occurs
*
* @since 1.7
*/
public
static
DatagramChannel
open
(
ProtocolFamily
family
)
throws
IOException
{
return
SelectorProvider
.
provider
().
openDatagramChannel
(
family
);
}
/**
/**
* Returns an operation set identifying this channel's supported
* Returns an operation set identifying this channel's supported
* operations.
* operations.
...
@@ -117,6 +195,32 @@ public abstract class DatagramChannel
...
@@ -117,6 +195,32 @@ public abstract class DatagramChannel
// -- Socket-specific operations --
// -- Socket-specific operations --
/**
* @throws AlreadyBoundException {@inheritDoc}
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its {@link
* SecurityManager#checkListen checkListen} method denies the
* operation
*
* @since 1.7
*/
public
abstract
DatagramChannel
bind
(
SocketAddress
local
)
throws
IOException
;
/**
* @throws IllegalArgumentException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*
* @since 1.7
*/
public
abstract
<
T
>
DatagramChannel
setOption
(
SocketOption
<
T
>
name
,
T
value
)
throws
IOException
;
/**
/**
* Retrieves a datagram socket associated with this channel.
* Retrieves a datagram socket associated with this channel.
*
*
...
@@ -128,10 +232,10 @@ public abstract class DatagramChannel
...
@@ -128,10 +232,10 @@ public abstract class DatagramChannel
public
abstract
DatagramSocket
socket
();
public
abstract
DatagramSocket
socket
();
/**
/**
* Tells whether or not this channel's socket is connected.
</p>
* Tells whether or not this channel's socket is connected.
*
*
* @return
<tt>true</tt>
if, and only if, this channel's socket
* @return
{@code true}
if, and only if, this channel's socket
* is connected
* is
{@link #isOpen open} and
connected
*/
*/
public
abstract
boolean
isConnected
();
public
abstract
boolean
isConnected
();
...
@@ -206,6 +310,19 @@ public abstract class DatagramChannel
...
@@ -206,6 +310,19 @@ public abstract class DatagramChannel
*/
*/
public
abstract
DatagramChannel
disconnect
()
throws
IOException
;
public
abstract
DatagramChannel
disconnect
()
throws
IOException
;
/**
* Returns the remote address to which this channel's socket is connected.
*
* @return The remote address; {@code null} if the channel is not {@link
* #isOpen open} or the channel's socket is not connected
*
* @throws IOException
* If an I/O error occurs
*
* @since 1.7
*/
public
abstract
SocketAddress
getConnectedAddress
()
throws
IOException
;
/**
/**
* Receives a datagram via this channel.
* Receives a datagram via this channel.
*
*
...
...
src/share/classes/java/nio/channels/MembershipKey.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
java.nio.channels
;
import
java.net.InetAddress
;
import
java.net.NetworkInterface
;
import
java.io.IOException
;
import
java.util.List
;
/**
* A token representing the membership of an Internet Protocol (IP) multicast
* group.
*
* <p> A membership key may represent a membership to receive all datagrams sent
* to the group, or it may be <em>source-specific</em>, meaning that it
* represents a membership that receives only datagrams from a specific source
* address. Whether or not a membership key is source-specific may be determined
* by invoking its {@link #getSourceAddress() getSourceAddress} method.
*
* <p> A membership key is valid upon creation and remains valid until the
* membership is dropped by invoking the {@link #drop() drop} method, or
* the channel is closed. The validity of the membership key may be tested
* by invoking its {@link #isValid() isValid} method.
*
* <p> Where a membership key is not source-specific and the underlying operation
* system supports source filtering, then the {@link #block block} and {@link
* #unblock unblock} methods can be used to block or unblock multicast datagrams
* from particular source addresses.
*
* @see MulticastChannel
*
* @since 1.7
*/
public
abstract
class
MembershipKey
{
/**
* Initializes a new instance of this class.
*/
protected
MembershipKey
()
{
}
/**
* Tells whether or not this membership is valid.
*
* <p> A multicast group membership is valid upon creation and remains
* valid until the membership is dropped by invoking the {@link #drop() drop}
* method, or the channel is closed.
*
* @return {@code true} if this membership key is valid, {@code false}
* otherwise
*/
public
abstract
boolean
isValid
();
/**
* Drop membership.
*
* <p> If the membership key represents a membership to receive all datagrams
* then the membership is dropped and the channel will no longer receive any
* datagrams sent to the group. If the membership key is source-specific
* then the channel will no longer receive datagrams sent to the group from
* that source address.
*
* <p> After membership is dropped it may still be possible to receive
* datagrams sent to the group. This can arise when datagrams are waiting to
* be received in the socket's receive buffer. After membership is dropped
* then the channel may {@link MulticastChannel#join join} the group again
* in which case a new membership key is returned.
*
* <p> Upon return, this membership object will be {@link #isValid() invalid}.
* If the multicast group membership is already invalid then invoking this
* method has no effect. Once a multicast group membership is invalid,
* it remains invalid forever.
*
* @throws IOException
* If an I/O error occurs
*/
public
abstract
void
drop
()
throws
IOException
;
/**
* Block multicast datagrams from the given source address.
*
* <p> If this membership key is not source-specific, and the underlying
* operating system supports source filtering, then this method blocks
* multicast datagrams from the given source address. If the given source
* address is already blocked then this method has no effect.
* After a source address is blocked it may still be possible to receive
* datagams from that source. This can arise when datagrams are waiting to
* be received in the socket's receive buffer.
*
* @param source
* The source address to block
*
* @return This membership key
*
* @throws IllegalArgumentException
* If the {@code source} parameter is not a unicast address or
* is not the same address type as the multicast group
* @throws IllegalStateException
* If this membership key is source-specific or is no longer valid
* @throws UnsupportedOperationException
* If the underlying operating system does not support source
* filtering
* @throws IOException
* If an I/O error occurs
*/
public
abstract
MembershipKey
block
(
InetAddress
source
)
throws
IOException
;
/**
* Unblock multicast datagrams from the given source address that was
* previously blocked using the {@link #block(InetAddress) block} method.
*
* @param source
* The source address to unblock
*
* @return This membership key
*
* @throws IllegalStateException
* If the given source address is not currently blocked or the
* membership key is no longer valid
* @throws IOException
* If an I/O error occurs
*/
public
abstract
MembershipKey
unblock
(
InetAddress
source
)
throws
IOException
;
/**
* Returns the channel for which this membership key was created. This
* method will continue to return the channel even after the membership
* becomes {@link #isValid invalid}.
*
* @return the channel
*/
public
abstract
MulticastChannel
getChannel
();
/**
* Returns the multicast group for which this membership key was created.
* This method will continue to return the group even after the membership
* becomes {@link #isValid invalid}.
*
* @return the multicast group
*/
public
abstract
InetAddress
getGroup
();
/**
* Returns the network interface for which this membership key was created.
* This method will continue to return the network interface even after the
* membership becomes {@link #isValid invalid}.
*
* @return the network interface
*/
public
abstract
NetworkInterface
getNetworkInterface
();
/**
* Returns the source address if this membership key is source-specific,
* or {@code null} if this membership is not source-specific.
*
* @return The source address if this membership key is source-specific,
* otherwise {@code null}
*/
public
abstract
InetAddress
getSourceAddress
();
}
src/share/classes/java/nio/channels/MulticastChannel.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
java.nio.channels
;
import
java.net.InetAddress
;
import
java.net.NetworkInterface
;
import
java.io.IOException
;
import
java.net.ProtocolFamily
;
// javadoc
import
java.net.StandardProtocolFamily
;
// javadoc
import
java.net.StandardSocketOption
;
// javadoc
/**
* A network channel that supports Internet Protocol (IP) multicasting.
*
* <p> IP multicasting is the transmission of IP datagrams to members of
* a <em>group</em> that is zero or more hosts identified by a single destination
* address.
*
* <p> In the case of a channel to an {@link StandardProtocolFamily#INET IPv4} socket,
* the underlying operating system supports <a href="http://www.ietf.org/rfc/rfc2236.txt">
* <i>RFC 2236: Internet Group Management Protocol, Version 2 (IGMPv2)</i></a>.
* It may optionally support source filtering as specified by <a
* href="http://www.ietf.org/rfc/rfc3376.txt"> <i>RFC 3376: Internet Group
* Management Protocol, Version 3 (IGMPv3)</i></a>.
* For channels to an {@link StandardProtocolFamily#INET6 IPv6} socket, the equivalent
* standards are <a href="http://www.ietf.org/rfc/rfc2710.txt"> <i>RFC 2710:
* Multicast Listener Discovery (MLD) for IPv6</i></a> and <a
* href="http://www.ietf.org/rfc/rfc3810.txt"> <i>RFC 3810: Multicast Listener
* Discovery Version 2 (MLDv2) for IPv6</i></a>.
*
* <p> The {@link #join(InetAddress,NetworkInterface)} method is used to
* join a group and receive all multicast datagrams sent to the group. A channel
* may join several multicast groups and may join the same group on several
* {@link NetworkInterface interfaces}. Membership is dropped by invoking the {@link
* MembershipKey#drop drop} method on the returned {@link MembershipKey}. If the
* underlying platform supports source filtering then the {@link MembershipKey#block
* block} and {@link MembershipKey#unblock unblock} methods can be used to block or
* unblock multicast datagrams from particular source addresses.
*
* <p> The {@link #join(InetAddress,NetworkInterface,InetAddress)} method
* is used to begin receiving datagrams sent to a group whose source address matches
* a given source address. This method throws {@link UnsupportedOperationException}
* if the underlying platform does not support source filtering. Membership is
* <em>cumulative</em> and this method may be invoked again with the same group
* and interface to allow receiving datagrams from other source addresses. The
* method returns a {@link MembershipKey} that represents membership to receive
* datagrams from the given source address. Invoking the key's {@link
* MembershipKey#drop drop} method drops membership so that datagrams from the
* source address can no longer be received.
*
* <h4>Platform dependencies</h4>
*
* The multicast implementation is intended to map directly to the native
* multicasting facility. Consequently, the following items should be considered
* when developing an application that receives IP multicast datagrams:
*
* <ol>
*
* <li><p> The creation of the channel should specify the {@link ProtocolFamily}
* that corresponds to the address type of the multicast groups that the channel
* will join. There is no guarantee that a channel to a socket in one protocol
* family can join and receive multicast datagrams when the address of the
* multicast group corresponds to another protocol family. For example, it is
* implementation specific if a channel to an {@link StandardProtocolFamily#INET6 IPv6}
* socket can join an {@link StandardProtocolFamily#INET IPv4} multicast group and receive
* multicast datagrams sent to the group. </p></li>
*
* <li><p> The channel's socket should be bound to the {@link
* InetAddress#isAnyLocalAddress wildcard} address. If the socket is bound to
* a specific address, rather than the wildcard address then it is implementation
* specific if multicast datagrams are received by the socket. </p></li>
*
* <li><p> The {@link StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} option should be
* enabled prior to {@link NetworkChannel#bind binding} the socket. This is
* required to allow multiple members of the group to bind to the same
* address. </p></li>
*
* </ol>
*
* <p> <b>Usage Example:</b>
* <pre>
* // join multicast group on this interface, and also use this
* // interface for outgoing multicast datagrams
* NetworkInterface ni = NetworkInterface.getByName("hme0");
*
* DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
* .setOption(StandardSocketOption.SO_REUSEADDR, true)
* .bind(new InetSocketAddress(5000))
* .setOption(StandardSocketOption.IP_MULTICAST_IF, ni);
*
* InetAddress group = InetAddress.getByName("225.4.5.6");
*
* MembershipKey key = dc.join(group, ni);
* </pre>
*
* @since 1.7
*/
public
interface
MulticastChannel
extends
NetworkChannel
{
/**
* Joins a multicast group to begin receiving all datagrams sent to the group,
* returning a membership key.
*
* <p> If this channel is currently a member of the group on the given
* interface to receive all datagrams then the membership key, representing
* that membership, is returned. Otherwise this channel joins the group and
* the resulting new membership key is returned. The resulting membership key
* is not {@link MembershipKey#getSourceAddress source-specific}.
*
* <p> A multicast channel may join several multicast groups, including
* the same group on more than one interface. An implementation may impose a
* limit on the number of groups that may be joined at the same time.
*
* @param group
* The multicast address to join
* @param interf
* The network interface on which to join the group
*
* @return The membership key
*
* @throws IllegalArgumentException
* If the group parameter is not a {@link InetAddress#isMulticastAddress
* multicast} address, or the group parameter is an address type
* that is not supported by this channel
* @throws IllegalStateException
* If the channel already has source-specific membership of the
* group on the interface
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
* If a security manager is set, and its
* {@link SecurityManager#checkMulticast(InetAddress) checkMulticast}
* method denies access to the multiast group
*/
MembershipKey
join
(
InetAddress
group
,
NetworkInterface
interf
)
throws
IOException
;
/**
* Joins a multicast group to begin receiving datagrams sent to the group
* from a given source address.
*
* <p> If this channel is currently a member of the group on the given
* interface to receive datagrams from the given source address then the
* membership key, representing that membership, is returned. Otherwise this
* channel joins the group and the resulting new membership key is returned.
* The resulting membership key is {@link MembershipKey#getSourceAddress
* source-specific}.
*
* <p> Membership is <em>cumulative</em> and this method may be invoked
* again with the same group and interface to allow receiving datagrams sent
* by other source addresses to the group.
*
* @param group
* The multicast address to join
* @param interf
* The network interface on which to join the group
* @param source
* The source address
*
* @return The membership key
*
* @throws IllegalArgumentException
* If the group parameter is not a {@link
* InetAddress#isMulticastAddress multicast} address, the
* source parameter is not a unicast address, the group
* parameter is an address type that is not supported by this channel,
* or the source parameter is not the same address type as the group
* @throws IllegalStateException
* If the channel is currently a member of the group on the given
* interface to receive all datagrams
* @throws UnsupportedOperationException
* If the underlying operation system does not support source filtering
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
* If a security manager is set, and its
* {@link SecurityManager#checkMulticast(InetAddress) checkMulticast}
* method denies access to the multiast group
*/
MembershipKey
join
(
InetAddress
group
,
NetworkInterface
interf
,
InetAddress
source
)
throws
IOException
;
}
src/share/classes/java/nio/channels/NetworkChannel.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
java.nio.channels
;
import
java.net.SocketOption
;
import
java.net.SocketAddress
;
import
java.util.Set
;
import
java.io.IOException
;
/**
* A channel to a network socket.
*
* <p> A channel that implements this interface is a channel to a network
* socket. The {@link #bind(SocketAddress) bind} method is used to bind the
* socket to a local {@link SocketAddress address}, the {@link #getLocalAddress()
* getLocalAddress} method returns the address that the socket is bound to, and
* the {@link #setOption(SocketOption,Object) setOption} and {@link
* #getOption(SocketOption) getOption} methods are used to set and query socket
* options. An implementation of this interface should specify the socket options
* that it supports.
*
* <p> The {@link #bind bind} and {@link #setOption setOption} methods that do
* not otherwise have a value to return are specified to return the network
* channel upon which they are invoked. This allows method invocations to be
* chained. Implementations of this interface should specialize the return type
* so that method invocations on the implementation class can be chained.
*
* @since 1.7
*/
public
interface
NetworkChannel
extends
Channel
{
/**
* Binds the channel's socket to a local address.
*
* <p> This method is used to establish an association between the socket and
* a local address. Once an association is established then the socket remains
* bound until the channel is closed. If the {@code local} parameter has the
* value {@code null} then the socket will be bound to an address that is
* assigned automatically.
*
* @param local
* The address to bind the socket, or {@code null} to bind the socket
* to an automatically assigned socket address
*
* @return This channel
*
* @throws AlreadyBoundException
* If the socket is already bound
* @throws UnsupportedAddressTypeException
* If the type of the given address is not supported
* @throws ClosedChannelException
* If the channel is closed
* @throws IOException
* If some other I/O error occurs
* @throws SecurityException
* If a security manager is installed and it denies an unspecified
* permission. An implementation of this interface should specify
* any required permissions.
*
* @see #getLocalAddress
*/
NetworkChannel
bind
(
SocketAddress
local
)
throws
IOException
;
/**
* Returns the socket address that this channel's socket is bound to, or
* {@code null} if the socket is not bound.
*
* <p> Where the channel is {@link #bind bound} to an Internet Protocol
* socket address then the return value from this method is of type {@link
* java.net.InetSocketAddress}.
*
* @return The socket address that the socket is bound to, or {@code null}
* if the channel is not {@link #isOpen open} or the channel's socket
* is not bound
*
* @throws IOException
* If an I/O error occurs
*/
SocketAddress
getLocalAddress
()
throws
IOException
;
/**
* Sets the value of a socket option.
*
* @param name
* The socket option
* @param value
* The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @return This channel
*
* @throws IllegalArgumentException
* If the socket option is not supported by this channel, or
* the value is not a valid value for this socket option
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If an I/O error occurs
*
* @see java.net.StandardSocketOption
*/
<
T
>
NetworkChannel
setOption
(
SocketOption
<
T
>
name
,
T
value
)
throws
IOException
;
/**
* Returns the value of a socket option.
*
* @param name
* The socket option
*
* @return The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @throws IllegalArgumentException
* If the socket option is not supported by this channel
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If an I/O error occurs
*
* @see java.net.StandardSocketOption
*/
<
T
>
T
getOption
(
SocketOption
<
T
>
name
)
throws
IOException
;
/**
* Returns a set of the socket options supported by this channel.
*
* <p> This method will continue to return the set of options even after the
* channel has been closed.
*
* @return A set of the socket options supported by this channel
*/
Set
<
SocketOption
<?>>
options
();
}
src/share/classes/java/nio/channels/ServerSocketChannel.java
浏览文件 @
ec347b32
...
@@ -27,33 +27,44 @@ package java.nio.channels;
...
@@ -27,33 +27,44 @@ package java.nio.channels;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.net.ServerSocket
;
import
java.net.ServerSocket
;
import
java.net.SocketOption
;
import
java.net.SocketAddress
;
import
java.net.SocketAddress
;
import
java.nio.channels.spi.*
;
import
java.nio.channels.spi.*
;
/**
/**
* A selectable channel for stream-oriented listening sockets.
* A selectable channel for stream-oriented listening sockets.
*
*
* <p> Server-socket channels are not a complete abstraction of listening
* network sockets. Binding and the manipulation of socket options must be
* done through an associated {@link java.net.ServerSocket} object obtained by
* invoking the {@link #socket() socket} method. It is not possible to create
* a channel for an arbitrary, pre-existing server socket, nor is it possible
* to specify the {@link java.net.SocketImpl} object to be used by a server
* socket associated with a server-socket channel.
*
* <p> A server-socket channel is created by invoking the {@link #open() open}
* <p> A server-socket channel is created by invoking the {@link #open() open}
* method of this class. A newly-created server-socket channel is open but not
* method of this class. It is not possible to create a channel for an arbitrary,
* yet bound. An attempt to invoke the {@link #accept() accept} method of an
* pre-existing {@link ServerSocket}. A newly-created server-socket channel is
* unbound server-socket channel will cause a {@link NotYetBoundException} to
* open but not yet bound. An attempt to invoke the {@link #accept() accept}
* be thrown. A server-socket channel can be bound by invoking one of the
* method of an unbound server-socket channel will cause a {@link NotYetBoundException}
* {@link java.net.ServerSocket#bind(java.net.SocketAddress,int) bind} methods
* to be thrown. A server-socket channel can be bound by invoking one of the
* of an associated server socket.
* {@link #bind(java.net.SocketAddress,int) bind} methods defined by this class.
*
* <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
* setOption} method. Server-socket channels support the following options:
* <blockquote>
* <table border>
* <tr>
* <th>Option Name</th>
* <th>Description</th>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
* <td> Re-use address </td>
* </tr>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported.
*
*
* <p> Server-socket channels are safe for use by multiple concurrent threads.
* <p> Server-socket channels are safe for use by multiple concurrent threads.
* </p>
* </p>
*
*
*
* @author Mark Reinhold
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @author JSR-51 Expert Group
* @since 1.4
* @since 1.4
...
@@ -61,6 +72,7 @@ import java.nio.channels.spi.*;
...
@@ -61,6 +72,7 @@ import java.nio.channels.spi.*;
public
abstract
class
ServerSocketChannel
public
abstract
class
ServerSocketChannel
extends
AbstractSelectableChannel
extends
AbstractSelectableChannel
implements
NetworkChannel
{
{
/**
/**
...
@@ -109,6 +121,89 @@ public abstract class ServerSocketChannel
...
@@ -109,6 +121,89 @@ public abstract class ServerSocketChannel
// -- ServerSocket-specific operations --
// -- ServerSocket-specific operations --
/**
* Binds the channel's socket to a local address and configures the socket
* to listen for connections.
*
* <p> An invocation of this method is equivalent to the following:
* <blockquote><pre>
* bind(local, 0);
* </pre></blockquote>
*
* @param local
* The local address to bind the socket, or {@code null} to bind
* to an automatically assigned socket address
*
* @return This channel
*
* @throws AlreadyBoundException {@inheritDoc}
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its {@link
* SecurityManager#checkListen checkListen} method denies the
* operation
*
* @since 1.7
*/
public
final
ServerSocketChannel
bind
(
SocketAddress
local
)
throws
IOException
{
return
bind
(
local
,
0
);
}
/**
* Binds the channel's socket to a local address and configures the socket to
* listen for connections.
*
* <p> This method is used to establish an association between the socket and
* a local address. Once an association is established then the socket remains
* bound until the channel is closed.
*
* <p> The {@code backlog} parameter is the maximum number of pending
* connections on the socket. Its exact semantics are implementation specific.
* In particular, an implementation may impose a maximum length or may choose
* to ignore the parameter altogther. If the {@code backlog} parameter has
* the value {@code 0}, or a negative value, then an implementation specific
* default is used.
*
* @param local
* The address to bind the socket, or {@code null} to bind to an
* automatically assigned socket address
* @param backlog
* The maximum number of pending connections
*
* @return This channel
*
* @throws AlreadyBoundException
* If the socket is already bound
* @throws UnsupportedAddressTypeException
* If the type of the given address is not supported
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
* @throws SecurityException
* If a security manager has been installed and its {@link
* SecurityManager#checkListen checkListen} method denies the
* operation
*
* @since 1.7
*/
public
abstract
ServerSocketChannel
bind
(
SocketAddress
local
,
int
backlog
)
throws
IOException
;
/**
* @throws IllegalArgumentException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*
* @since 1.7
*/
public
abstract
<
T
>
ServerSocketChannel
setOption
(
SocketOption
<
T
>
name
,
T
value
)
throws
IOException
;
/**
/**
* Retrieves a server socket associated with this channel.
* Retrieves a server socket associated with this channel.
*
*
...
...
src/share/classes/java/nio/channels/SocketChannel.java
浏览文件 @
ec347b32
...
@@ -27,24 +27,17 @@ package java.nio.channels;
...
@@ -27,24 +27,17 @@ package java.nio.channels;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.net.Socket
;
import
java.net.Socket
;
import
java.net.SocketOption
;
import
java.net.SocketAddress
;
import
java.net.SocketAddress
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.nio.channels.spi.*
;
import
java.nio.channels.spi.*
;
/**
/**
* A selectable channel for stream-oriented connecting sockets.
* A selectable channel for stream-oriented connecting sockets.
*
*
* <p> Socket channels are not a complete abstraction of connecting network
* sockets. Binding, shutdown, and the manipulation of socket options must be
* done through an associated {@link java.net.Socket} object obtained by
* invoking the {@link #socket() socket} method. It is not possible to create
* a channel for an arbitrary, pre-existing socket, nor is it possible to
* specify the {@link java.net.SocketImpl} object to be used by a socket
* associated with a socket channel.
*
* <p> A socket channel is created by invoking one of the {@link #open open}
* <p> A socket channel is created by invoking one of the {@link #open open}
* methods of this class. A newly-created socket channel is open but not yet
* methods of this class. It is not possible to create a channel for an arbitrary,
* pre-existing socket. A newly-created socket channel is open but not yet
* connected. An attempt to invoke an I/O operation upon an unconnected
* connected. An attempt to invoke an I/O operation upon an unconnected
* channel will cause a {@link NotYetConnectedException} to be thrown. A
* channel will cause a {@link NotYetConnectedException} to be thrown. A
* socket channel can be connected by invoking its {@link #connect connect}
* socket channel can be connected by invoking its {@link #connect connect}
...
@@ -59,16 +52,6 @@ import java.nio.channels.spi.*;
...
@@ -59,16 +52,6 @@ import java.nio.channels.spi.*;
* Whether or not a connection operation is in progress may be determined by
* Whether or not a connection operation is in progress may be determined by
* invoking the {@link #isConnectionPending isConnectionPending} method.
* invoking the {@link #isConnectionPending isConnectionPending} method.
*
*
* <p> The input and output sides of a socket channel may independently be
* <i>shut down</i> without actually closing the channel. Shutting down the
* input side of a channel by invoking the {@link java.net.Socket#shutdownInput
* shutdownInput} method of an associated socket object will cause further
* reads on the channel to return <tt>-1</tt>, the end-of-stream indication.
* Shutting down the output side of the channel by invoking the {@link
* java.net.Socket#shutdownOutput shutdownOutput} method of an associated
* socket object will cause further writes on the channel to throw a {@link
* ClosedChannelException}.
*
* <p> Socket channels support <i>asynchronous shutdown,</i> which is similar
* <p> Socket channels support <i>asynchronous shutdown,</i> which is similar
* to the asynchronous close operation specified in the {@link Channel} class.
* to the asynchronous close operation specified in the {@link Channel} class.
* If the input side of a socket is shut down by one thread while another
* If the input side of a socket is shut down by one thread while another
...
@@ -79,6 +62,43 @@ import java.nio.channels.spi.*;
...
@@ -79,6 +62,43 @@ import java.nio.channels.spi.*;
* channel, then the blocked thread will receive an {@link
* channel, then the blocked thread will receive an {@link
* AsynchronousCloseException}.
* AsynchronousCloseException}.
*
*
* <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
* setOption} method. Socket channels support the following options:
* <blockquote>
* <table border>
* <tr>
* <th>Option Name</th>
* <th>Description</th>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} </td>
* <td> The size of the socket send buffer </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_KEEPALIVE SO_KEEPALIVE} </td>
* <td> Keep connection alive </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
* <td> Re-use address </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#SO_LINGER SO_LINGER} </td>
* <td> Linger on close if data is present (when configured in blocking mode
* only) </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOption#TCP_NODELAY TCP_NODELAY} </td>
* <td> Disable the Nagle algorithm </td>
* </tr>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported.
*
* <p> Socket channels are safe for use by multiple concurrent threads. They
* <p> Socket channels are safe for use by multiple concurrent threads. They
* support concurrent reading and writing, though at most one thread may be
* support concurrent reading and writing, though at most one thread may be
* reading and at most one thread may be writing at any given time. The {@link
* reading and at most one thread may be writing at any given time. The {@link
...
@@ -87,7 +107,6 @@ import java.nio.channels.spi.*;
...
@@ -87,7 +107,6 @@ import java.nio.channels.spi.*;
* or write operation while an invocation of one of these methods is in
* or write operation while an invocation of one of these methods is in
* progress will block until that invocation is complete. </p>
* progress will block until that invocation is complete. </p>
*
*
*
* @author Mark Reinhold
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @author JSR-51 Expert Group
* @since 1.4
* @since 1.4
...
@@ -95,7 +114,7 @@ import java.nio.channels.spi.*;
...
@@ -95,7 +114,7 @@ import java.nio.channels.spi.*;
public
abstract
class
SocketChannel
public
abstract
class
SocketChannel
extends
AbstractSelectableChannel
extends
AbstractSelectableChannel
implements
ByteChannel
,
ScatteringByteChannel
,
GatheringByteChannel
implements
ByteChannel
,
ScatteringByteChannel
,
GatheringByteChannel
,
NetworkChannel
{
{
/**
/**
...
@@ -191,6 +210,73 @@ public abstract class SocketChannel
...
@@ -191,6 +210,73 @@ public abstract class SocketChannel
// -- Socket-specific operations --
// -- Socket-specific operations --
/**
* @throws ConnectionPendingException
* If a non-blocking connection operation is already in progress on
* this channel
* @throws AlreadyBoundException {@inheritDoc}
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*
* @since 1.7
*/
@Override
public
abstract
SocketChannel
bind
(
SocketAddress
local
)
throws
IOException
;
/**
* @throws IllegalArgumentException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*
* @since 1.7
*/
@Override
public
abstract
<
T
>
SocketChannel
setOption
(
SocketOption
<
T
>
name
,
T
value
)
throws
IOException
;
/**
* Shutdown the connection for reading without closing the channel.
*
* <p> Once shutdown for reading then further reads on the channel will
* return {@code -1}, the end-of-stream indication. If the input side of the
* connection is already shutdown then invoking this method has no effect.
*
* @return The channel
*
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*
* @since 1.7
*/
public
abstract
SocketChannel
shutdownInput
()
throws
IOException
;
/**
* Shutdown the connection for writing without closing the channel.
*
* <p> Once shutdown for writing then further attempts to write to the
* channel will throw {@link ClosedChannelException}. If the output side of
* the connection is already shutdown then invoking this method has no
* effect.
*
* @return The channel
*
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*
* @since 1.7
*/
public
abstract
SocketChannel
shutdownOutput
()
throws
IOException
;
/**
/**
* Retrieves a socket associated with this channel.
* Retrieves a socket associated with this channel.
*
*
...
@@ -202,10 +288,10 @@ public abstract class SocketChannel
...
@@ -202,10 +288,10 @@ public abstract class SocketChannel
public
abstract
Socket
socket
();
public
abstract
Socket
socket
();
/**
/**
* Tells whether or not this channel's network socket is connected.
</p>
* Tells whether or not this channel's network socket is connected.
*
*
* @return <tt>true</tt> if, and only if, this channel's network socket
* @return <tt>true</tt> if, and only if, this channel's network socket
* is connected
* is
{@link #isOpen open} and
connected
*/
*/
public
abstract
boolean
isConnected
();
public
abstract
boolean
isConnected
();
...
@@ -339,6 +425,22 @@ public abstract class SocketChannel
...
@@ -339,6 +425,22 @@ public abstract class SocketChannel
*/
*/
public
abstract
boolean
finishConnect
()
throws
IOException
;
public
abstract
boolean
finishConnect
()
throws
IOException
;
/**
* Returns the remote address to which this channel's socket is connected.
*
* <p> Where the channel is bound and connected to an Internet Protocol
* socket address then the return value from this method is of type {@link
* java.net.InetSocketAddress}.
*
* @return The remote address; {@code null} if the channel is not {@link
* #isOpen open} or the channel's socket is not connected
*
* @throws IOException
* If an I/O error occurs
*
* @since 1.7
*/
public
abstract
SocketAddress
getConnectedAddress
()
throws
IOException
;
// -- ByteChannel operations --
// -- ByteChannel operations --
...
...
src/share/classes/java/nio/channels/exceptions
浏览文件 @
ec347b32
...
@@ -146,3 +146,14 @@ gen OverlappingFileLockException "
...
@@ -146,3 +146,14 @@ gen OverlappingFileLockException "
* virtual machine, or when another thread is already waiting to lock an
* virtual machine, or when another thread is already waiting to lock an
* overlapping region of the same file." \
* overlapping region of the same file." \
2047812138163068433L
2047812138163068433L
SINCE=1.7
SUPER=IllegalStateException
gen AlreadyBoundException "
* Unchecked exception thrown when an attempt is made to bind the socket a
* network oriented channel that is already bound." \
6796072983322737592L
src/share/classes/java/nio/channels/package-info.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* Defines channels, which represent connections to entities that are capable of
* performing I/O operations, such as files and sockets; defines selectors, for
* multiplexed, non-blocking I/O operations.
*
* <a name="channels"></a>
*
* <blockquote><table cellspacing=1 cellpadding=0 summary="Lists channels and their descriptions">
* <tr><th><p align="left">Channels</p></th><th><p align="left">Description</p></th></tr>
* <tr><td valign=top><tt><i>{@link java.nio.channels.Channel}</i></tt></td>
* <td>A nexus for I/O operations</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.channels.ReadableByteChannel}</i></tt></td>
* <td>Can read into a buffer</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.channels.ScatteringByteChannel} </i></tt></td>
* <td>Can read into a sequence of buffers</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.channels.WritableByteChannel}</i></tt></td>
* <td>Can write from a buffer</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.channels.GatheringByteChannel}</i></tt></td>
* <td>Can write from a sequence of buffers</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.channels.ByteChannel}</i></tt></td>
* <td>Can read/write to/from a buffer</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.channels.SeekableByteChannel}</i></tt></td>
* <td>A {@code ByteChannel} connected to an entity that contains a variable-length sequence of bytes</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.channels.NetworkChannel}</i></tt></td>
* <td>A channel to a network socket</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.channels.MulticastChannel}</i></tt></td>
* <td>Can join Internet Protocol (IP) multicast groups</td></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.Channels}</tt></td>
* <td>Utility methods for channel/stream interoperation</td></tr>
* </table></blockquote>
*
* <p> A <i>channel</i> represents an open connection to an entity such as a
* hardware device, a file, a network socket, or a program component that is
* capable of performing one or more distinct I/O operations, for example reading
* or writing. As specified in the {@link java.nio.channels.Channel} interface,
* channels are either open or closed, and they are both <i>asynchronously
* closeable</i> and <i>interruptible</i>.
*
* <p> The {@link java.nio.channels.Channel} interface is extended by several
* other interfaces.
*
* <p> The {@link java.nio.channels.ReadableByteChannel} interface specifies a
* {@link java.nio.channels.ReadableByteChannel#read read} method that reads bytes
* from the channel into a buffer; similarly, the {@link
* java.nio.channels.WritableByteChannel} interface specifies a {@link
* java.nio.channels.WritableByteChannel#write write} method that writes bytes
* from a buffer to the channel. The {@link java.nio.channels.ByteChannel}
* interface unifies these two interfaces for the common case of channels that can
* both read and write bytes. The {@link java.nio.channels.SeekableByteChannel}
* interface extends the {@code ByteChannel} interface with methods to {@link
* java.nio.channels.SeekableByteChannel#position() query} and {@link
* java.nio.channels.SeekableByteChannel#position(long) modify} the channel's
* current position, and its {@link java.nio.channels.SeekableByteChannel#size
* size}.
*
* <p> The {@link java.nio.channels.ScatteringByteChannel} and {@link
* java.nio.channels.GatheringByteChannel} interfaces extend the {@link
* java.nio.channels.ReadableByteChannel} and {@link
* java.nio.channels.WritableByteChannel} interfaces, respectively, adding {@link
* java.nio.channels.ScatteringByteChannel#read read} and {@link
* java.nio.channels.GatheringByteChannel#write write} methods that take a
* sequence of buffers rather than a single buffer.
*
* <p> The {@link java.nio.channels.NetworkChannel} interface specifies methods
* to {@link java.nio.channels.NetworkChannel#bind bind} the channel's socket,
* obtain the address to which the socket is bound, and methods to {@link
* java.nio.channels.NetworkChannel#getOption get} and {@link
* java.nio.channels.NetworkChannel#setOption set} socket options. The {@link
* java.nio.channels.MulticastChannel} interface specifies methods to join
* Internet Protocol (IP) multicast groups.
*
* <p> The {@link java.nio.channels.Channels} utility class defines static methods
* that support the interoperation of the stream classes of the <tt>{@link
* java.io}</tt> package with the channel classes of this package. An appropriate
* channel can be constructed from an {@link java.io.InputStream} or an {@link
* java.io.OutputStream}, and conversely an {@link java.io.InputStream} or an
* {@link java.io.OutputStream} can be constructed from a channel. A {@link
* java.io.Reader} can be constructed that uses a given charset to decode bytes
* from a given readable byte channel, and conversely a {@link java.io.Writer} can
* be constructed that uses a given charset to encode characters into bytes and
* write them to a given writable byte channel.
*
* <blockquote><table cellspacing=1 cellpadding=0 summary="Lists file channels and their descriptions">
* <tr><th><p align="left">File channels</p></th><th><p align="left">Description</p></th></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.FileChannel}</tt></td>
* <td>Reads, writes, maps, and manipulates files</td></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.FileLock}</tt></td>
* <td>A lock on a (region of a) file</td></tr>
* <tr><td valign=top><tt>{@link java.nio.MappedByteBuffer}/{@link java.nio.MappedBigByteBuffer} </tt></td>
* <td>A direct byte buffer or big byte buffer mapped to a region of a file</td></tr>
* </table></blockquote>
*
* <p> The {@link java.nio.channels.FileChannel} class supports the usual
* operations of reading bytes from, and writing bytes to, a channel connected to
* a file, as well as those of querying and modifying the current file position
* and truncating the file to a specific size. It defines methods for acquiring
* locks on the whole file or on a specific region of a file; these methods return
* instances of the {@link java.nio.channels.FileLock} class. Finally, it defines
* methods for forcing updates to the file to be written to the storage device that
* contains it, for efficiently transferring bytes between the file and other
* channels, and for mapping a region of the file directly into memory.
*
* <p> A {@code FileChannel} is created by invoking one of its static {@link
* java.nio.channels.FileChannel#open open} methods, or by invoking the {@code
* getChannel} method of a {@link java.io.FileInputStream}, {@link
* java.io.FileOutputStream}, or {@link java.io.RandomAccessFile} to return a
* file channel connected to the same underlying file as the <tt>{@link java.io}</tt>
* class.
*
* <a name="multiplex"></a>
* <blockquote><table cellspacing=1 cellpadding=0 summary="Lists multiplexed, non-blocking channels and their descriptions">
* <tr><th><p align="left">Multiplexed, non-blocking I/O</p></th><th><p align="left">Description</p></th></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.SelectableChannel}</tt></td>
* <td>A channel that can be multiplexed</td></tr>
* <tr><td valign=top><tt> {@link java.nio.channels.DatagramChannel}</tt></td>
* <td>A channel to a datagram-oriented socket</td></tr>
* <tr><td valign=top><tt> {@link java.nio.channels.Pipe.SinkChannel}</tt></td>
* <td>The write end of a pipe</td></tr>
* <tr><td valign=top><tt> {@link java.nio.channels.Pipe.SourceChannel}</tt></td>
* <td>The read end of a pipe</td></tr>
* <tr><td valign=top><tt> {@link java.nio.channels.ServerSocketChannel} </tt></td>
* <td>A channel to a stream-oriented listening socket</td></tr>
* <tr><td valign=top><tt> {@link java.nio.channels.SocketChannel}</tt></td>
* <td>A channel for a stream-oriented connecting socket</td></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.Selector}</tt></td>
* <td>A multiplexor of selectable channels</td></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.SelectionKey}</tt></td>
* <td>A token representing the registration <br> of a channel
* with a selector</td></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.Pipe}</tt></td>
* <td>Two channels that form a unidirectional pipe</td></tr>
* </table></blockquote>
*
* <p> Multiplexed, non-blocking I/O, which is much more scalable than
* thread-oriented, blocking I/O, is provided by <i>selectors</i>, <i>selectable
* channels</i>, and <i>selection keys</i>.
*
* <p> A <a href="Selector.html"><i>selector</i></a> is a multiplexor of <a
* href="SelectableChannel.html"><i>selectable channels</i></a>, which in turn are
* a special type of channel that can be put into <a
* href="SelectableChannel.html#bm"><i>non-blocking mode</i></a>. To perform
* multiplexed I/O operations, one or more selectable channels are first created,
* put into non-blocking mode, and {@link
* java.nio.channels.SelectableChannel#register <i>registered</i>}
* with a selector. Registering a channel specifies the set of I/O operations
* that will be tested for readiness by the selector, and returns a <a
* href="SelectionKey.html"><i>selection key</i></a> that represents the
* registration.
*
* <p> Once some channels have been registered with a selector, a <a
* href="Selector.html#selop"><i>selection operation</i></a> can be performed in
* order to discover which channels, if any, have become ready to perform one or
* more of the operations in which interest was previously declared. If a channel
* is ready then the key returned when it was registered will be added to the
* selector's <i>selected-key set</i>. The key set, and the keys within it, can
* be examined in order to determine the operations for which each channel is
* ready. From each key one can retrieve the corresponding channel in order to
* perform whatever I/O operations are required.
*
* <p> That a selection key indicates that its channel is ready for some operation
* is a hint, but not a guarantee, that such an operation can be performed by a
* thread without causing the thread to block. It is imperative that code that
* performs multiplexed I/O be written so as to ignore these hints when they prove
* to be incorrect.
*
* <p> This package defines selectable-channel classes corresponding to the {@link
* java.net.DatagramSocket}, {@link java.net.ServerSocket}, and {@link
* java.net.Socket} classes defined in the <tt>{@link java.net}</tt> package.
* Minor changes to these classes have been made in order to support sockets that
* are associated with channels. This package also defines a simple class that
* implements unidirectional pipes. In all cases, a new selectable channel is
* created by invoking the static <tt>open</tt> method of the corresponding class.
* If a channel needs an associated socket then a socket will be created as a side
* effect of this operation.
*
* <p> The implementation of selectors, selectable channels, and selection keys
* can be replaced by "plugging in" an alternative definition or instance of the
* {@link java.nio.channels.spi.SelectorProvider} class defined in the <tt>{@link
* java.nio.channels.spi}</tt> package. It is not expected that many developers
* will actually make use of this facility; it is provided primarily so that
* sophisticated users can take advantage of operating-system-specific
* I/O-multiplexing mechanisms when very high performance is required.
*
* <p> Much of the bookkeeping and synchronization required to implement the
* multiplexed-I/O abstractions is performed by the {@link
* java.nio.channels.spi.AbstractInterruptibleChannel}, {@link
* java.nio.channels.spi.AbstractSelectableChannel}, {@link
* java.nio.channels.spi.AbstractSelectionKey}, and {@link
* java.nio.channels.spi.AbstractSelector} classes in the <tt>{@link
* java.nio.channels.spi}</tt> package. When defining a custom selector provider,
* only the {@link java.nio.channels.spi.AbstractSelector} and {@link
* java.nio.channels.spi.AbstractSelectionKey} classes should be subclassed
* directly; custom channel classes should extend the appropriate {@link
* java.nio.channels.SelectableChannel} subclasses defined in this package.
*
* <hr width="80%">
* <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
* or method in any class or interface in this package will cause a {@link
* java.lang.NullPointerException NullPointerException} to be thrown.
*
* @since 1.4
* @author Mark Reinhold
* @author JSR-51 Expert Group
*/
package
java.nio.channels
;
src/share/classes/java/nio/channels/package.html
已删除
100644 → 0
浏览文件 @
70763cd4
<!--
Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation. Sun designates this
particular file as subject to the "Classpath" exception as provided
by Sun in the LICENSE file that accompanied this code.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
CA 95054 USA or visit www.sun.com if you need additional information or
have any questions.
-->
<!doctype html public "-//IETF//DTD HTML//EN">
<html>
<body
bgcolor=
"white"
>
Defines channels, which represent connections to entities that are capable of
performing I/O operations, such as files and sockets; defines selectors, for
multiplexed, non-blocking I/O operations.
<a
name=
"channels"
>
<blockquote><table
cellspacing=
1
cellpadding=
0
summary=
"Lists channels and their descriptions"
>
<tr><th><p
align=
"left"
>
Channels
</p></th><th><p
align=
"left"
>
Description
</p></th></tr>
<tr><td
valign=
top
><tt><i>
{@link java.nio.channels.Channel}
</i></tt></td>
<td>
A nexus for I/O operations
</td></tr>
<tr><td
valign=
top
><tt>
<i>
{@link java.nio.channels.ReadableByteChannel}
</i></tt></td>
<td>
Can read into a buffer
</td></tr>
<tr><td
valign=
top
><tt>
<i>
{@link java.nio.channels.ScatteringByteChannel}
</i></tt></td>
<td>
Can read into a sequence of
buffers
</td></tr>
<tr><td
valign=
top
><tt>
<i>
{@link java.nio.channels.WritableByteChannel}
</i></tt></td>
<td>
Can write from a buffer
</td></tr>
<tr><td
valign=
top
><tt>
<i>
{@link java.nio.channels.GatheringByteChannel}
</i></tt></td>
<td>
Can write from a sequence of
buffers
</td></tr>
<tr><td
valign=
top
><tt>
<i>
{@link java.nio.channels.ByteChannel}
</i></tt></td>
<td>
Can read/write to/from a
buffer
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.Channels}
</tt></td>
<td>
Utility methods for channel/stream interoperation
</td></tr>
</table></blockquote>
<p>
A
<i>
channel
</i>
represents an open connection to an entity such as a
hardware device, a file, a network socket, or a program component that is
capable of performing one or more distinct I/O operations, for example reading
or writing. As specified in the {@link java.nio.channels.Channel} interface,
channels are either open or closed, and they are both
<i>
asynchronously
closeable
</i>
and
<i>
interruptible
</i>
.
<p>
The {@link java.nio.channels.Channel} interface is extended by several
other interfaces, each of which specifies a new I/O operation.
<p>
The {@link java.nio.channels.ReadableByteChannel} interface specifies a
{@link java.nio.channels.ReadableByteChannel#read read} method that reads bytes
from the channel into a buffer; similarly, the {@link
java.nio.channels.WritableByteChannel} interface specifies a {@link
java.nio.channels.WritableByteChannel#write write} method that writes bytes
from a buffer to the channel. The {@link java.nio.channels.ByteChannel}
interface unifies these two interfaces for the common case of channels that can
both read and write bytes.
<p>
The {@link java.nio.channels.ScatteringByteChannel} and {@link
java.nio.channels.GatheringByteChannel} interfaces extend the {@link
java.nio.channels.ReadableByteChannel} and {@link
java.nio.channels.WritableByteChannel} interfaces, respectively, adding {@link
java.nio.channels.ScatteringByteChannel#read read} and {@link
java.nio.channels.GatheringByteChannel#write write} methods that take a
sequence of buffers rather than a single buffer.
<p>
The {@link java.nio.channels.Channels} utility class defines static methods
that support the interoperation of the stream classes of the
<tt>
{@link
java.io}
</tt>
package with the channel classes of this package. An appropriate
channel can be constructed from an {@link java.io.InputStream} or an {@link
java.io.OutputStream}, and conversely an {@link java.io.InputStream} or an
{@link java.io.OutputStream} can be constructed from a channel. A {@link
java.io.Reader} can be constructed that uses a given charset to decode bytes
from a given readable byte channel, and conversely a {@link java.io.Writer} can
be constructed that uses a given charset to encode characters into bytes and
write them to a given writable byte channel.
<blockquote><table
cellspacing=
1
cellpadding=
0
summary=
"Lists file channels and their descriptions"
>
<tr><th><p
align=
"left"
>
File channels
</p></th><th><p
align=
"left"
>
Description
</p></th></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.FileChannel}
</tt></td>
<td>
Reads, writes, maps, and manipulates files
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.FileLock}
</tt></td>
<td>
A lock on a (region of a) file
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.MappedByteBuffer}
</tt></td>
<td>
A direct byte buffer mapped to a region of a
file
</td></tr>
</table></blockquote>
<p>
The {@link java.nio.channels.FileChannel} class supports the usual
operations of reading bytes from, and writing bytes to, a channel connected to
a file, as well as those of querying and modifying the current file position
and truncating the file to a specific size. It defines methods for acquiring
locks on the whole file or on a specific region of a file; these methods return
instances of the {@link java.nio.channels.FileLock} class. Finally, it defines
methods for forcing updates to the file to be written to the storage device that
contains it, for efficiently transferring bytes between the file and other
channels, and for mapping a region of the file directly into memory. This last
operation creates an instance of the {@link java.nio.MappedByteBuffer}
class, which extends the {@link java.nio.ByteBuffer} class with several
file-related operations.
<p>
A
<tt>
getChannel
</tt>
method has been added to each of the {@link
java.io.FileInputStream#getChannel FileInputStream}, {@link
java.io.FileOutputStream#getChannel FileOutputStream}, and {@link
java.io.RandomAccessFile#getChannel RandomAccessFile} classes of the
<tt>
{@link
java.io java.io}
</tt>
package. Invoking this method upon an instance of one of
these classes will return a file channel connected to the underlying file.
<a
name=
"multiplex"
>
<blockquote><table
cellspacing=
1
cellpadding=
0
summary=
"Lists multiplexed, non-blocking channels and their descriptions"
>
<tr><th><p
align=
"left"
>
Multiplexed, non-blocking I/O
</p></th><th><p
align=
"left"
>
Description
</p></th></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.SelectableChannel}
</tt></td>
<td>
A channel that can be multiplexed
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.DatagramChannel}
</tt></td>
<td>
A channel for a {@link java.net.DatagramSocket java.net.DatagramSocket}
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.Pipe.SinkChannel}
</tt></td>
<td>
The write end of a pipe
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.Pipe.SourceChannel}
</tt></td>
<td>
The read end of a pipe
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.ServerSocketChannel}
</tt></td>
<td>
A channel for a {@link java.net.ServerSocket java.net.ServerSocket}
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.SocketChannel}
</tt></td>
<td>
A channel for a {@link java.net.Socket java.net.Socket}
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.Selector}
</tt></td>
<td>
A multiplexor of selectable channels
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.SelectionKey}
</tt></td>
<td>
A token representing the registration
<br>
of a channel
with
a
selector
</td></tr>
<tr><td
valign=
top
><tt>
{@link java.nio.channels.Pipe}
</tt></td>
<td>
Two channels that form a unidirectional
pipe
</td></tr>
</table></blockquote>
<p>
Multiplexed, non-blocking I/O, which is much more scalable than
thread-oriented, blocking I/O, is provided by
<i>
selectors
</i>
,
<i>
selectable
channels
</i>
, and
<i>
selection keys
</i>
.
<p>
A
<a
href=
"Selector.html"
><i>
selector
</i></a>
is a multiplexor of
<a
href=
"SelectableChannel.html"
><i>
selectable channels
</i></a>
, which in turn are
a special type of channel that can be put into
<a
href=
"SelectableChannel.html#bm"
><i>
non-blocking mode
</i></a>
. To perform
multiplexed I/O operations, one or more selectable channels are first created,
put into non-blocking mode, and {@link
java.nio.channels.SelectableChannel#register
</code><i>
registered
</i><code>
}
with a selector. Registering a channel specifies the set of I/O operations
that will be tested for readiness by the selector, and returns a
<a
href=
"SelectionKey.html"
><i>
selection key
</i></a>
that represents the
registration.
<p>
Once some channels have been registered with a selector, a
<a
href=
"Selector.html#selop"
><i>
selection operation
</i></a>
can be performed in
order to discover which channels, if any, have become ready to perform one or
more of the operations in which interest was previously declared. If a channel
is ready then the key returned when it was registered will be added to the
selector's
<i>
selected-key set
</i>
. The key set, and the keys within it, can
be examined in order to determine the operations for which each channel is
ready. From each key one can retrieve the corresponding channel in order to
perform whatever I/O operations are required.
<p>
That a selection key indicates that its channel is ready for some operation
is a hint, but not a guarantee, that such an operation can be performed by a
thread without causing the thread to block. It is imperative that code that
performs multiplexed I/O be written so as to ignore these hints when they prove
to be incorrect.
<p>
This package defines selectable-channel classes corresponding to the {@link
java.net.DatagramSocket}, {@link java.net.ServerSocket}, and {@link
java.net.Socket} classes defined in the
<tt>
{@link java.net}
</tt>
package.
Minor changes to these classes have been made in order to support sockets that
are associated with channels. This package also defines a simple class that
implements unidirectional pipes. In all cases, a new selectable channel is
created by invoking the static
<tt>
open
</tt>
method of the corresponding class.
If a channel needs an associated socket then a socket will be created as a side
effect of this operation.
<p>
The implementation of selectors, selectable channels, and selection keys
can be replaced by "plugging in" an alternative definition or instance of the
{@link java.nio.channels.spi.SelectorProvider} class defined in the
<tt>
{@link
java.nio.channels.spi}
</tt>
package. It is not expected that many developers
will actually make use of this facility; it is provided primarily so that
sophisticated users can take advantage of operating-system-specific
I/O-multiplexing mechanisms when very high performance is required.
<p>
Much of the bookkeeping and synchronization required to implement the
multiplexed-I/O abstractions is performed by the {@link
java.nio.channels.spi.AbstractInterruptibleChannel}, {@link
java.nio.channels.spi.AbstractSelectableChannel}, {@link
java.nio.channels.spi.AbstractSelectionKey}, and {@link
java.nio.channels.spi.AbstractSelector} classes in the
<tt>
{@link
java.nio.channels.spi}
</tt>
package. When defining a custom selector provider,
only the {@link java.nio.channels.spi.AbstractSelector} and {@link
java.nio.channels.spi.AbstractSelectionKey} classes should be subclassed
directly; custom channel classes should extend the appropriate {@link
java.nio.channels.SelectableChannel} subclasses defined in this package.
<p>
Unless otherwise noted, passing a
<tt>
null
</tt>
argument to a constructor
or method in any class or interface in this package will cause a {@link
java.lang.NullPointerException NullPointerException} to be thrown.
@since 1.4
@author Mark Reinhold
@author JSR-51 Expert Group
</body>
</html>
src/share/classes/java/nio/channels/spi/SelectorProvider.java
浏览文件 @
ec347b32
...
@@ -25,10 +25,8 @@
...
@@ -25,10 +25,8 @@
package
java.nio.channels.spi
;
package
java.nio.channels.spi
;
import
java.io.FileDescriptor
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.net.ServerSocket
;
import
java.net.ProtocolFamily
;
import
java.net.Socket
;
import
java.nio.channels.*
;
import
java.nio.channels.*
;
import
java.security.AccessController
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
import
java.security.PrivilegedAction
;
...
@@ -190,7 +188,25 @@ public abstract class SelectorProvider {
...
@@ -190,7 +188,25 @@ public abstract class SelectorProvider {
throws
IOException
;
throws
IOException
;
/**
/**
* Opens a pipe. </p>
* Opens a datagram channel.
*
* @param family
* The protocol family
*
* @return A new datagram channel
*
* @throws UnsupportedOperationException
* If the specified protocol family is not supported
* @throws IOException
* If an I/O error occurs
*
* @since 1.7
*/
public
abstract
DatagramChannel
openDatagramChannel
(
ProtocolFamily
family
)
throws
IOException
;
/**
* Opens a pipe. </p>
*
*
* @return The new pipe
* @return The new pipe
*/
*/
...
...
src/share/classes/sun/nio/ch/DatagramChannelImpl.java
浏览文件 @
ec347b32
...
@@ -31,7 +31,7 @@ import java.net.*;
...
@@ -31,7 +31,7 @@ import java.net.*;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.nio.channels.*
;
import
java.nio.channels.*
;
import
java.nio.channels.spi.*
;
import
java.nio.channels.spi.*
;
import
java.
lang.ref.SoftReference
;
import
java.
util.*
;
/**
/**
...
@@ -47,11 +47,14 @@ class DatagramChannelImpl
...
@@ -47,11 +47,14 @@ class DatagramChannelImpl
private
static
NativeDispatcher
nd
=
new
DatagramDispatcher
();
private
static
NativeDispatcher
nd
=
new
DatagramDispatcher
();
// Our file descriptor
// Our file descriptor
FileDescriptor
fd
=
null
;
private
final
FileDescriptor
fd
;
// fd value needed for dev/poll. This value will remain valid
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
// even after the value in the file descriptor object has been set to -1
int
fdVal
;
private
final
int
fdVal
;
// The protocol family of the socket
private
final
ProtocolFamily
family
;
// IDs of native threads doing reads and writes, for signalling
// IDs of native threads doing reads and writes, for signalling
private
volatile
long
readerThread
=
0
;
private
volatile
long
readerThread
=
0
;
...
@@ -59,8 +62,8 @@ class DatagramChannelImpl
...
@@ -59,8 +62,8 @@ class DatagramChannelImpl
// Cached InetAddress and port for unconnected DatagramChannels
// Cached InetAddress and port for unconnected DatagramChannels
// used by receive0
// used by receive0
private
InetAddress
cachedSenderInetAddress
=
null
;
private
InetAddress
cachedSenderInetAddress
;
private
int
cachedSenderPort
=
0
;
private
int
cachedSenderPort
;
// Lock held by current reading or connecting thread
// Lock held by current reading or connecting thread
private
final
Object
readLock
=
new
Object
();
private
final
Object
readLock
=
new
Object
();
...
@@ -76,20 +79,20 @@ class DatagramChannelImpl
...
@@ -76,20 +79,20 @@ class DatagramChannelImpl
// State (does not necessarily increase monotonically)
// State (does not necessarily increase monotonically)
private
static
final
int
ST_UNINITIALIZED
=
-
1
;
private
static
final
int
ST_UNINITIALIZED
=
-
1
;
private
static
int
ST_UNCONNECTED
=
0
;
private
static
final
int
ST_UNCONNECTED
=
0
;
private
static
int
ST_CONNECTED
=
1
;
private
static
final
int
ST_CONNECTED
=
1
;
private
static
final
int
ST_KILLED
=
2
;
private
static
final
int
ST_KILLED
=
2
;
private
int
state
=
ST_UNINITIALIZED
;
private
int
state
=
ST_UNINITIALIZED
;
// Binding
// Binding
private
SocketAddress
localAddress
=
null
;
private
SocketAddress
localAddress
;
SocketAddress
remoteAddress
=
null
;
private
SocketAddress
remoteAddress
;
// Options
private
SocketOpts
.
IP
options
=
null
;
// Our socket adaptor, if any
// Our socket adaptor, if any
private
DatagramSocket
socket
=
null
;
private
DatagramSocket
socket
;
// Multicast support
private
MembershipRegistry
registry
;
// -- End of fields protected by stateLock
// -- End of fields protected by stateLock
...
@@ -98,7 +101,26 @@ class DatagramChannelImpl
...
@@ -98,7 +101,26 @@ class DatagramChannelImpl
throws
IOException
throws
IOException
{
{
super
(
sp
);
super
(
sp
);
this
.
fd
=
Net
.
socket
(
false
);
this
.
family
=
Net
.
isIPv6Available
()
?
StandardProtocolFamily
.
INET6
:
StandardProtocolFamily
.
INET
;
this
.
fd
=
Net
.
socket
(
family
,
false
);
this
.
fdVal
=
IOUtil
.
fdVal
(
fd
);
this
.
state
=
ST_UNCONNECTED
;
}
public
DatagramChannelImpl
(
SelectorProvider
sp
,
ProtocolFamily
family
)
{
super
(
sp
);
if
((
family
!=
StandardProtocolFamily
.
INET
)
&&
(
family
!=
StandardProtocolFamily
.
INET6
))
{
throw
new
UnsupportedOperationException
(
"Protocol family not supported"
);
}
if
(
family
==
StandardProtocolFamily
.
INET6
)
{
if
(!
Net
.
isIPv6Available
())
{
throw
new
UnsupportedOperationException
(
"IPv6 not available"
);
}
}
this
.
family
=
family
;
this
.
fd
=
Net
.
socket
(
family
,
false
);
this
.
fdVal
=
IOUtil
.
fdVal
(
fd
);
this
.
fdVal
=
IOUtil
.
fdVal
(
fd
);
this
.
state
=
ST_UNCONNECTED
;
this
.
state
=
ST_UNCONNECTED
;
}
}
...
@@ -107,9 +129,12 @@ class DatagramChannelImpl
...
@@ -107,9 +129,12 @@ class DatagramChannelImpl
throws
IOException
throws
IOException
{
{
super
(
sp
);
super
(
sp
);
this
.
family
=
Net
.
isIPv6Available
()
?
StandardProtocolFamily
.
INET6
:
StandardProtocolFamily
.
INET
;
this
.
fd
=
fd
;
this
.
fd
=
fd
;
this
.
fdVal
=
IOUtil
.
fdVal
(
fd
);
this
.
fdVal
=
IOUtil
.
fdVal
(
fd
);
this
.
state
=
ST_UNCONNECTED
;
this
.
state
=
ST_UNCONNECTED
;
this
.
localAddress
=
Net
.
localAddress
(
fd
);
}
}
public
DatagramSocket
socket
()
{
public
DatagramSocket
socket
()
{
...
@@ -120,6 +145,156 @@ class DatagramChannelImpl
...
@@ -120,6 +145,156 @@ class DatagramChannelImpl
}
}
}
}
@Override
public
SocketAddress
getLocalAddress
()
throws
IOException
{
synchronized
(
stateLock
)
{
if
(!
isOpen
())
return
null
;
return
localAddress
;
}
}
@Override
public
SocketAddress
getConnectedAddress
()
throws
IOException
{
synchronized
(
stateLock
)
{
if
(!
isOpen
())
return
null
;
return
remoteAddress
;
}
}
@Override
public
DatagramChannel
setOption
(
SocketOption
name
,
Object
value
)
throws
IOException
{
if
(
name
==
null
)
throw
new
NullPointerException
();
if
(!
options
().
contains
(
name
))
throw
new
IllegalArgumentException
(
"Invalid option name"
);
synchronized
(
stateLock
)
{
ensureOpen
();
if
(
name
==
StandardSocketOption
.
IP_TOS
)
{
// IPv4 only; no-op for IPv6
if
(
family
==
StandardProtocolFamily
.
INET
)
{
Net
.
setSocketOption
(
fd
,
family
,
name
,
value
);
}
return
this
;
}
if
(
name
==
StandardSocketOption
.
IP_MULTICAST_TTL
||
name
==
StandardSocketOption
.
IP_MULTICAST_LOOP
)
{
// options are protocol dependent
Net
.
setSocketOption
(
fd
,
family
,
name
,
value
);
return
this
;
}
if
(
name
==
StandardSocketOption
.
IP_MULTICAST_IF
)
{
if
(
value
==
null
)
throw
new
IllegalArgumentException
(
"Cannot set IP_MULTICAST_IF to 'null'"
);
NetworkInterface
interf
=
(
NetworkInterface
)
value
;
if
(
family
==
StandardProtocolFamily
.
INET6
)
{
int
index
=
interf
.
getIndex
();
if
(
index
==
-
1
)
throw
new
IOException
(
"Network interface cannot be identified"
);
Net
.
setInterface6
(
fd
,
index
);
}
else
{
// need IPv4 address to identify interface
Inet4Address
target
=
Net
.
anyInet4Address
(
interf
);
if
(
target
==
null
)
throw
new
IOException
(
"Network interface not configured for IPv4"
);
int
targetAddress
=
Net
.
inet4AsInt
(
target
);
Net
.
setInterface4
(
fd
,
targetAddress
);
}
return
this
;
}
// remaining options don't need any special handling
Net
.
setSocketOption
(
fd
,
Net
.
UNSPEC
,
name
,
value
);
return
this
;
}
}
@Override
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
getOption
(
SocketOption
<
T
>
name
)
throws
IOException
{
if
(
name
==
null
)
throw
new
NullPointerException
();
if
(!
options
().
contains
(
name
))
throw
new
IllegalArgumentException
(
"Invalid option name"
);
synchronized
(
stateLock
)
{
ensureOpen
();
if
(
name
==
StandardSocketOption
.
IP_TOS
)
{
// IPv4 only; always return 0 on IPv6
if
(
family
==
StandardProtocolFamily
.
INET
)
{
return
(
T
)
Net
.
getSocketOption
(
fd
,
family
,
name
);
}
else
{
return
(
T
)
Integer
.
valueOf
(
0
);
}
}
if
(
name
==
StandardSocketOption
.
IP_MULTICAST_TTL
||
name
==
StandardSocketOption
.
IP_MULTICAST_LOOP
)
{
return
(
T
)
Net
.
getSocketOption
(
fd
,
family
,
name
);
}
if
(
name
==
StandardSocketOption
.
IP_MULTICAST_IF
)
{
if
(
family
==
StandardProtocolFamily
.
INET
)
{
int
address
=
Net
.
getInterface4
(
fd
);
if
(
address
==
0
)
return
null
;
// default interface
InetAddress
ia
=
Net
.
inet4FromInt
(
address
);
NetworkInterface
ni
=
NetworkInterface
.
getByInetAddress
(
ia
);
if
(
ni
==
null
)
throw
new
IOException
(
"Unable to map address to interface"
);
return
(
T
)
ni
;
}
else
{
int
index
=
Net
.
getInterface6
(
fd
);
if
(
index
==
0
)
return
null
;
// default interface
NetworkInterface
ni
=
NetworkInterface
.
getByIndex
(
index
);
if
(
ni
==
null
)
throw
new
IOException
(
"Unable to map index to interface"
);
return
(
T
)
ni
;
}
}
// no special handling
return
(
T
)
Net
.
getSocketOption
(
fd
,
Net
.
UNSPEC
,
name
);
}
}
private
static
class
LazyInitialization
{
static
final
Set
<
SocketOption
<?>>
defaultOptions
=
defaultOptions
();
private
static
Set
<
SocketOption
<?>>
defaultOptions
()
{
HashSet
<
SocketOption
<?>>
set
=
new
HashSet
<
SocketOption
<?>>(
8
);
set
.
add
(
StandardSocketOption
.
SO_SNDBUF
);
set
.
add
(
StandardSocketOption
.
SO_RCVBUF
);
set
.
add
(
StandardSocketOption
.
SO_REUSEADDR
);
set
.
add
(
StandardSocketOption
.
SO_BROADCAST
);
set
.
add
(
StandardSocketOption
.
IP_TOS
);
set
.
add
(
StandardSocketOption
.
IP_MULTICAST_IF
);
set
.
add
(
StandardSocketOption
.
IP_MULTICAST_TTL
);
set
.
add
(
StandardSocketOption
.
IP_MULTICAST_LOOP
);
return
Collections
.
unmodifiableSet
(
set
);
}
}
@Override
public
final
Set
<
SocketOption
<?>>
options
()
{
return
LazyInitialization
.
defaultOptions
;
}
private
void
ensureOpen
()
throws
ClosedChannelException
{
private
void
ensureOpen
()
throws
ClosedChannelException
{
if
(!
isOpen
())
if
(!
isOpen
())
throw
new
ClosedChannelException
();
throw
new
ClosedChannelException
();
...
@@ -135,8 +310,10 @@ class DatagramChannelImpl
...
@@ -135,8 +310,10 @@ class DatagramChannelImpl
synchronized
(
readLock
)
{
synchronized
(
readLock
)
{
ensureOpen
();
ensureOpen
();
// If socket is not bound then behave as if nothing received
// If socket is not bound then behave as if nothing received
if
(!
isBound
())
// ## NotYetBoundException ??
// Will be fixed by 6621699
if
(
localAddress
()
==
null
)
{
return
null
;
return
null
;
}
int
n
=
0
;
int
n
=
0
;
ByteBuffer
bb
=
null
;
ByteBuffer
bb
=
null
;
try
{
try
{
...
@@ -267,6 +444,12 @@ class DatagramChannelImpl
...
@@ -267,6 +444,12 @@ class DatagramChannelImpl
do
{
do
{
n
=
send
(
fd
,
src
,
target
);
n
=
send
(
fd
,
src
,
target
);
}
while
((
n
==
IOStatus
.
INTERRUPTED
)
&&
isOpen
());
}
while
((
n
==
IOStatus
.
INTERRUPTED
)
&&
isOpen
());
synchronized
(
stateLock
)
{
if
(
isOpen
()
&&
(
localAddress
==
null
))
{
localAddress
=
Net
.
localAddress
(
fd
);
}
}
return
IOStatus
.
normalize
(
n
);
return
IOStatus
.
normalize
(
n
);
}
finally
{
}
finally
{
writerThread
=
0
;
writerThread
=
0
;
...
@@ -316,7 +499,8 @@ class DatagramChannelImpl
...
@@ -316,7 +499,8 @@ class DatagramChannelImpl
assert
(
pos
<=
lim
);
assert
(
pos
<=
lim
);
int
rem
=
(
pos
<=
lim
?
lim
-
pos
:
0
);
int
rem
=
(
pos
<=
lim
?
lim
-
pos
:
0
);
int
written
=
send0
(
fd
,
((
DirectBuffer
)
bb
).
address
()
+
pos
,
boolean
preferIPv6
=
(
family
!=
StandardProtocolFamily
.
INET
);
int
written
=
send0
(
preferIPv6
,
fd
,
((
DirectBuffer
)
bb
).
address
()
+
pos
,
rem
,
target
);
rem
,
target
);
if
(
written
>
0
)
if
(
written
>
0
)
bb
.
position
(
pos
+
written
);
bb
.
position
(
pos
+
written
);
...
@@ -453,42 +637,8 @@ class DatagramChannelImpl
...
@@ -453,42 +637,8 @@ class DatagramChannelImpl
IOUtil
.
configureBlocking
(
fd
,
block
);
IOUtil
.
configureBlocking
(
fd
,
block
);
}
}
public
SocketOpts
options
()
{
synchronized
(
stateLock
)
{
if
(
options
==
null
)
{
SocketOptsImpl
.
Dispatcher
d
=
new
SocketOptsImpl
.
Dispatcher
()
{
int
getInt
(
int
opt
)
throws
IOException
{
return
Net
.
getIntOption
(
fd
,
opt
);
}
void
setInt
(
int
opt
,
int
arg
)
throws
IOException
{
Net
.
setIntOption
(
fd
,
opt
,
arg
);
}
};
options
=
new
SocketOptsImpl
.
IP
(
d
);
}
return
options
;
}
}
public
boolean
isBound
()
{
return
Net
.
localPortNumber
(
fd
)
!=
0
;
}
public
SocketAddress
localAddress
()
{
public
SocketAddress
localAddress
()
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
if
(
isConnected
()
&&
(
localAddress
==
null
))
{
// Socket was not bound before connecting,
// so ask what the address turned out to be
localAddress
=
Net
.
localAddress
(
fd
);
}
SecurityManager
sm
=
System
.
getSecurityManager
();
if
(
sm
!=
null
)
{
InetSocketAddress
isa
=
(
InetSocketAddress
)
localAddress
;
sm
.
checkConnect
(
isa
.
getAddress
().
getHostAddress
(),
-
1
);
}
return
localAddress
;
return
localAddress
;
}
}
}
}
...
@@ -499,22 +649,37 @@ class DatagramChannelImpl
...
@@ -499,22 +649,37 @@ class DatagramChannelImpl
}
}
}
}
public
void
bind
(
SocketAddress
local
)
throws
IOException
{
@Override
public
DatagramChannel
bind
(
SocketAddress
local
)
throws
IOException
{
synchronized
(
readLock
)
{
synchronized
(
readLock
)
{
synchronized
(
writeLock
)
{
synchronized
(
writeLock
)
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
ensureOpen
();
ensureOpen
();
if
(
isBound
()
)
if
(
localAddress
!=
null
)
throw
new
AlreadyBoundException
();
throw
new
AlreadyBoundException
();
InetSocketAddress
isa
=
Net
.
checkAddress
(
local
);
InetSocketAddress
isa
;
if
(
local
==
null
)
{
isa
=
new
InetSocketAddress
(
0
);
}
else
{
isa
=
Net
.
checkAddress
(
local
);
// only Inet4Address allowed with IPv4 socket
if
(
family
==
StandardProtocolFamily
.
INET
)
{
InetAddress
addr
=
isa
.
getAddress
();
if
(!(
addr
instanceof
Inet4Address
))
throw
new
UnsupportedAddressTypeException
();
}
}
SecurityManager
sm
=
System
.
getSecurityManager
();
SecurityManager
sm
=
System
.
getSecurityManager
();
if
(
sm
!=
null
)
if
(
sm
!=
null
)
{
sm
.
checkListen
(
isa
.
getPort
());
sm
.
checkListen
(
isa
.
getPort
());
Net
.
bind
(
fd
,
isa
.
getAddress
(),
isa
.
getPort
());
}
Net
.
bind
(
family
,
fd
,
isa
.
getAddress
(),
isa
.
getPort
());
localAddress
=
Net
.
localAddress
(
fd
);
localAddress
=
Net
.
localAddress
(
fd
);
}
}
}
}
}
}
return
this
;
}
}
public
boolean
isConnected
()
{
public
boolean
isConnected
()
{
...
@@ -533,7 +698,6 @@ class DatagramChannelImpl
...
@@ -533,7 +698,6 @@ class DatagramChannelImpl
}
}
public
DatagramChannel
connect
(
SocketAddress
sa
)
throws
IOException
{
public
DatagramChannel
connect
(
SocketAddress
sa
)
throws
IOException
{
int
trafficClass
=
0
;
int
localPort
=
0
;
int
localPort
=
0
;
synchronized
(
readLock
)
{
synchronized
(
readLock
)
{
...
@@ -545,10 +709,10 @@ class DatagramChannelImpl
...
@@ -545,10 +709,10 @@ class DatagramChannelImpl
if
(
sm
!=
null
)
if
(
sm
!=
null
)
sm
.
checkConnect
(
isa
.
getAddress
().
getHostAddress
(),
sm
.
checkConnect
(
isa
.
getAddress
().
getHostAddress
(),
isa
.
getPort
());
isa
.
getPort
());
int
n
=
Net
.
connect
(
fd
,
int
n
=
Net
.
connect
(
family
,
fd
,
isa
.
getAddress
(),
isa
.
getAddress
(),
isa
.
getPort
(),
isa
.
getPort
());
trafficClass
);
if
(
n
<=
0
)
if
(
n
<=
0
)
throw
new
Error
();
// Can't happen
throw
new
Error
();
// Can't happen
...
@@ -558,6 +722,11 @@ class DatagramChannelImpl
...
@@ -558,6 +722,11 @@ class DatagramChannelImpl
sender
=
isa
;
sender
=
isa
;
cachedSenderInetAddress
=
isa
.
getAddress
();
cachedSenderInetAddress
=
isa
.
getAddress
();
cachedSenderPort
=
isa
.
getPort
();
cachedSenderPort
=
isa
.
getPort
();
// Socket was not bound before connecting,
if
(
localAddress
==
null
)
{
localAddress
=
Net
.
localAddress
(
fd
);
}
}
}
}
}
}
}
...
@@ -584,9 +753,215 @@ class DatagramChannelImpl
...
@@ -584,9 +753,215 @@ class DatagramChannelImpl
return
this
;
return
this
;
}
}
/**
* Joins channel's socket to the given group/interface and
* optional source address.
*/
private
MembershipKey
innerJoin
(
InetAddress
group
,
NetworkInterface
interf
,
InetAddress
source
)
throws
IOException
{
if
(!
group
.
isMulticastAddress
())
throw
new
IllegalArgumentException
(
"Group not a multicast address"
);
// check multicast address is compatible with this socket
if
(!(
group
instanceof
Inet4Address
))
{
if
(
family
==
StandardProtocolFamily
.
INET
)
throw
new
IllegalArgumentException
(
"Group is not IPv4 address"
);
if
(!(
group
instanceof
Inet6Address
))
throw
new
IllegalArgumentException
(
"Address type not supported"
);
}
// check source address
if
(
source
!=
null
)
{
if
(
source
.
isAnyLocalAddress
())
throw
new
IllegalArgumentException
(
"Source address is a wildcard address"
);
if
(
source
.
isMulticastAddress
())
throw
new
IllegalArgumentException
(
"Source address is multicast address"
);
if
(
source
.
getClass
()
!=
group
.
getClass
())
throw
new
IllegalArgumentException
(
"Source address is different type to group"
);
}
SecurityManager
sm
=
System
.
getSecurityManager
();
if
(
sm
!=
null
)
sm
.
checkMulticast
(
group
);
synchronized
(
stateLock
)
{
if
(!
isOpen
())
throw
new
ClosedChannelException
();
// check the registry to see if we are already a member of the group
if
(
registry
==
null
)
{
registry
=
new
MembershipRegistry
();
}
else
{
// return existing membership key
MembershipKey
key
=
registry
.
checkMembership
(
group
,
interf
,
source
);
if
(
key
!=
null
)
return
key
;
}
MembershipKeyImpl
key
;
if
(
family
==
StandardProtocolFamily
.
INET6
)
{
int
index
=
interf
.
getIndex
();
if
(
index
==
-
1
)
throw
new
IOException
(
"Network interface cannot be identified"
);
// need multicast and source address as byte arrays
byte
[]
groupAddress
=
Net
.
inet6AsByteArray
(
group
);
byte
[]
sourceAddress
=
(
source
==
null
)
?
null
:
Net
.
inet6AsByteArray
(
source
);
// join the group
int
n
=
Net
.
join6
(
fd
,
groupAddress
,
index
,
sourceAddress
);
if
(
n
==
IOStatus
.
UNAVAILABLE
)
throw
new
UnsupportedOperationException
();
key
=
new
MembershipKeyImpl
.
Type6
(
this
,
group
,
interf
,
source
,
groupAddress
,
index
,
sourceAddress
);
}
else
{
// need IPv4 address to identify interface
Inet4Address
target
=
Net
.
anyInet4Address
(
interf
);
if
(
target
==
null
)
throw
new
IOException
(
"Network interface not configured for IPv4"
);
int
groupAddress
=
Net
.
inet4AsInt
(
group
);
int
targetAddress
=
Net
.
inet4AsInt
(
target
);
int
sourceAddress
=
(
source
==
null
)
?
0
:
Net
.
inet4AsInt
(
source
);
// join the group
int
n
=
Net
.
join4
(
fd
,
groupAddress
,
targetAddress
,
sourceAddress
);
if
(
n
==
IOStatus
.
UNAVAILABLE
)
throw
new
UnsupportedOperationException
();
key
=
new
MembershipKeyImpl
.
Type4
(
this
,
group
,
interf
,
source
,
groupAddress
,
targetAddress
,
sourceAddress
);
}
registry
.
add
(
key
);
return
key
;
}
}
@Override
public
MembershipKey
join
(
InetAddress
group
,
NetworkInterface
interf
)
throws
IOException
{
return
innerJoin
(
group
,
interf
,
null
);
}
@Override
public
MembershipKey
join
(
InetAddress
group
,
NetworkInterface
interf
,
InetAddress
source
)
throws
IOException
{
if
(
source
==
null
)
throw
new
NullPointerException
(
"source address is null"
);
return
innerJoin
(
group
,
interf
,
source
);
}
// package-private
void
drop
(
MembershipKeyImpl
key
)
throws
IOException
{
assert
key
.
getChannel
()
==
this
;
synchronized
(
stateLock
)
{
if
(!
key
.
isValid
())
return
;
if
(
family
==
StandardProtocolFamily
.
INET6
)
{
MembershipKeyImpl
.
Type6
key6
=
(
MembershipKeyImpl
.
Type6
)
key
;
Net
.
drop6
(
fd
,
key6
.
group
(),
key6
.
index
(),
key6
.
source
());
}
else
{
MembershipKeyImpl
.
Type4
key4
=
(
MembershipKeyImpl
.
Type4
)
key
;
Net
.
drop4
(
fd
,
key4
.
group
(),
key4
.
interfaceAddress
(),
key4
.
source
());
}
key
.
invalidate
();
registry
.
remove
(
key
);
}
}
/**
* Block datagrams from given source if a memory to receive all
* datagrams.
*/
void
block
(
MembershipKeyImpl
key
,
InetAddress
source
)
throws
IOException
{
assert
key
.
getChannel
()
==
this
;
assert
key
.
getSourceAddress
()
==
null
;
synchronized
(
stateLock
)
{
if
(!
key
.
isValid
())
throw
new
IllegalStateException
(
"key is no longer valid"
);
if
(
source
.
isAnyLocalAddress
())
throw
new
IllegalArgumentException
(
"Source address is a wildcard address"
);
if
(
source
.
isMulticastAddress
())
throw
new
IllegalArgumentException
(
"Source address is multicast address"
);
if
(
source
.
getClass
()
!=
key
.
getGroup
().
getClass
())
throw
new
IllegalArgumentException
(
"Source address is different type to group"
);
int
n
;
if
(
family
==
StandardProtocolFamily
.
INET6
)
{
MembershipKeyImpl
.
Type6
key6
=
(
MembershipKeyImpl
.
Type6
)
key
;
n
=
Net
.
block6
(
fd
,
key6
.
group
(),
key6
.
index
(),
Net
.
inet6AsByteArray
(
source
));
}
else
{
MembershipKeyImpl
.
Type4
key4
=
(
MembershipKeyImpl
.
Type4
)
key
;
n
=
Net
.
block4
(
fd
,
key4
.
group
(),
key4
.
interfaceAddress
(),
Net
.
inet4AsInt
(
source
));
}
if
(
n
==
IOStatus
.
UNAVAILABLE
)
{
// ancient kernel
throw
new
UnsupportedOperationException
();
}
}
}
/**
* Unblock given source.
*/
void
unblock
(
MembershipKeyImpl
key
,
InetAddress
source
)
throws
IOException
{
assert
key
.
getChannel
()
==
this
;
assert
key
.
getSourceAddress
()
==
null
;
synchronized
(
stateLock
)
{
if
(!
key
.
isValid
())
throw
new
IllegalStateException
(
"key is no longer valid"
);
if
(
family
==
StandardProtocolFamily
.
INET6
)
{
MembershipKeyImpl
.
Type6
key6
=
(
MembershipKeyImpl
.
Type6
)
key
;
Net
.
unblock6
(
fd
,
key6
.
group
(),
key6
.
index
(),
Net
.
inet6AsByteArray
(
source
));
}
else
{
MembershipKeyImpl
.
Type4
key4
=
(
MembershipKeyImpl
.
Type4
)
key
;
Net
.
unblock4
(
fd
,
key4
.
group
(),
key4
.
interfaceAddress
(),
Net
.
inet4AsInt
(
source
));
}
}
}
protected
void
implCloseSelectableChannel
()
throws
IOException
{
protected
void
implCloseSelectableChannel
()
throws
IOException
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
nd
.
preClose
(
fd
);
nd
.
preClose
(
fd
);
// if member of mulitcast group then invalidate all keys
if
(
registry
!=
null
)
registry
.
invalidateAll
();
long
th
;
long
th
;
if
((
th
=
readerThread
)
!=
0
)
if
((
th
=
readerThread
)
!=
0
)
NativeThread
.
signal
(
th
);
NativeThread
.
signal
(
th
);
...
@@ -695,8 +1070,8 @@ class DatagramChannelImpl
...
@@ -695,8 +1070,8 @@ class DatagramChannelImpl
boolean
connected
)
boolean
connected
)
throws
IOException
;
throws
IOException
;
private
native
int
send0
(
FileDescriptor
fd
,
long
address
,
int
len
,
private
native
int
send0
(
boolean
preferIPv6
,
FileDescriptor
fd
,
long
address
,
int
len
,
SocketAddress
sa
)
SocketAddress
sa
)
throws
IOException
;
throws
IOException
;
static
{
static
{
...
...
src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
浏览文件 @
ec347b32
...
@@ -45,16 +45,9 @@ public class DatagramSocketAdaptor
...
@@ -45,16 +45,9 @@ public class DatagramSocketAdaptor
// The channel being adapted
// The channel being adapted
private
final
DatagramChannelImpl
dc
;
private
final
DatagramChannelImpl
dc
;
// Option adaptor object, created on demand
private
volatile
OptionAdaptor
opts
=
null
;
// Timeout "option" value for receives
// Timeout "option" value for receives
private
volatile
int
timeout
=
0
;
private
volatile
int
timeout
=
0
;
// Traffic-class/Type-of-service
private
volatile
int
trafficClass
=
0
;
// ## super will create a useless impl
// ## super will create a useless impl
private
DatagramSocketAdaptor
(
DatagramChannelImpl
dc
)
throws
IOException
{
private
DatagramSocketAdaptor
(
DatagramChannelImpl
dc
)
throws
IOException
{
// Invoke the DatagramSocketAdaptor(SocketAddress) constructor,
// Invoke the DatagramSocketAdaptor(SocketAddress) constructor,
...
@@ -82,7 +75,7 @@ public class DatagramSocketAdaptor
...
@@ -82,7 +75,7 @@ public class DatagramSocketAdaptor
throw
new
IllegalArgumentException
(
"connect: "
+
port
);
throw
new
IllegalArgumentException
(
"connect: "
+
port
);
if
(
remote
==
null
)
if
(
remote
==
null
)
throw
new
IllegalArgumentException
(
"connect: null address"
);
throw
new
IllegalArgumentException
(
"connect: null address"
);
if
(
!
isClosed
())
if
(
isClosed
())
return
;
return
;
try
{
try
{
dc
.
connect
(
remote
);
dc
.
connect
(
remote
);
...
@@ -124,11 +117,11 @@ public class DatagramSocketAdaptor
...
@@ -124,11 +117,11 @@ public class DatagramSocketAdaptor
}
}
public
boolean
isBound
()
{
public
boolean
isBound
()
{
return
dc
.
isBound
()
;
return
dc
.
localAddress
()
!=
null
;
}
}
public
boolean
isConnected
()
{
public
boolean
isConnected
()
{
return
dc
.
isConnected
()
;
return
dc
.
remoteAddress
()
!=
null
;
}
}
public
InetAddress
getInetAddress
()
{
public
InetAddress
getInetAddress
()
{
...
@@ -157,7 +150,7 @@ public class DatagramSocketAdaptor
...
@@ -157,7 +150,7 @@ public class DatagramSocketAdaptor
// Legacy DatagramSocket will send in this case
// Legacy DatagramSocket will send in this case
// and set address and port of the packet
// and set address and port of the packet
InetSocketAddress
isa
=
(
InetSocketAddress
)
InetSocketAddress
isa
=
(
InetSocketAddress
)
dc
.
remoteAddress
;
dc
.
remoteAddress
()
;
p
.
setPort
(
isa
.
getPort
());
p
.
setPort
(
isa
.
getPort
());
p
.
setAddress
(
isa
.
getAddress
());
p
.
setAddress
(
isa
.
getAddress
());
dc
.
write
(
bb
);
dc
.
write
(
bb
);
...
@@ -241,21 +234,32 @@ public class DatagramSocketAdaptor
...
@@ -241,21 +234,32 @@ public class DatagramSocketAdaptor
public
InetAddress
getLocalAddress
()
{
public
InetAddress
getLocalAddress
()
{
if
(
isClosed
())
if
(
isClosed
())
return
null
;
return
null
;
try
{
SocketAddress
local
=
dc
.
localAddress
();
return
Net
.
asInetSocketAddress
(
dc
.
localAddress
()).
getAddress
();
if
(
local
==
null
)
}
catch
(
Exception
x
)
{
local
=
new
InetSocketAddress
(
0
);
return
new
InetSocketAddress
(
0
).
getAddress
();
InetAddress
result
=
((
InetSocketAddress
)
local
).
getAddress
();
SecurityManager
sm
=
System
.
getSecurityManager
();
if
(
sm
!=
null
)
{
try
{
sm
.
checkConnect
(
result
.
getHostAddress
(),
-
1
);
}
catch
(
SecurityException
x
)
{
return
new
InetSocketAddress
(
0
).
getAddress
();
}
}
}
return
result
;
}
}
public
int
getLocalPort
()
{
public
int
getLocalPort
()
{
if
(
isClosed
())
if
(
isClosed
())
return
-
1
;
return
-
1
;
try
{
try
{
return
Net
.
asInetSocketAddress
(
dc
.
localAddress
()).
getPort
();
SocketAddress
local
=
dc
.
getLocalAddress
();
if
(
local
!=
null
)
{
return
((
InetSocketAddress
)
local
).
getPort
();
}
}
catch
(
Exception
x
)
{
}
catch
(
Exception
x
)
{
return
0
;
}
}
return
0
;
}
}
public
void
setSoTimeout
(
int
timeout
)
throws
SocketException
{
public
void
setSoTimeout
(
int
timeout
)
throws
SocketException
{
...
@@ -266,55 +270,87 @@ public class DatagramSocketAdaptor
...
@@ -266,55 +270,87 @@ public class DatagramSocketAdaptor
return
timeout
;
return
timeout
;
}
}
private
OptionAdaptor
opts
()
{
private
void
setBooleanOption
(
SocketOption
<
Boolean
>
name
,
boolean
value
)
if
(
opts
==
null
)
throws
SocketException
opts
=
new
OptionAdaptor
(
dc
);
{
return
opts
;
try
{
dc
.
setOption
(
name
,
value
);
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
private
void
setIntOption
(
SocketOption
<
Integer
>
name
,
int
value
)
throws
SocketException
{
try
{
dc
.
setOption
(
name
,
value
);
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
private
boolean
getBooleanOption
(
SocketOption
<
Boolean
>
name
)
throws
SocketException
{
try
{
return
dc
.
getOption
(
name
).
booleanValue
();
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
return
false
;
// keep compiler happy
}
}
private
int
getIntOption
(
SocketOption
<
Integer
>
name
)
throws
SocketException
{
try
{
return
dc
.
getOption
(
name
).
intValue
();
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
return
-
1
;
// keep compiler happy
}
}
}
public
void
setSendBufferSize
(
int
size
)
throws
SocketException
{
public
void
setSendBufferSize
(
int
size
)
throws
SocketException
{
opts
().
setSendBufferSize
(
size
);
if
(
size
<=
0
)
throw
new
IllegalArgumentException
(
"Invalid send size"
);
setIntOption
(
StandardSocketOption
.
SO_SNDBUF
,
size
);
}
}
public
int
getSendBufferSize
()
throws
SocketException
{
public
int
getSendBufferSize
()
throws
SocketException
{
return
opts
().
getSendBufferSize
(
);
return
getIntOption
(
StandardSocketOption
.
SO_SNDBUF
);
}
}
public
void
setReceiveBufferSize
(
int
size
)
throws
SocketException
{
public
void
setReceiveBufferSize
(
int
size
)
throws
SocketException
{
opts
().
setReceiveBufferSize
(
size
);
if
(
size
<=
0
)
throw
new
IllegalArgumentException
(
"Invalid receive size"
);
setIntOption
(
StandardSocketOption
.
SO_RCVBUF
,
size
);
}
}
public
int
getReceiveBufferSize
()
throws
SocketException
{
public
int
getReceiveBufferSize
()
throws
SocketException
{
return
opts
().
getReceiveBufferSize
(
);
return
getIntOption
(
StandardSocketOption
.
SO_RCVBUF
);
}
}
public
void
setReuseAddress
(
boolean
on
)
throws
SocketException
{
public
void
setReuseAddress
(
boolean
on
)
throws
SocketException
{
opts
().
setReuseAddress
(
on
);
setBooleanOption
(
StandardSocketOption
.
SO_REUSEADDR
,
on
);
}
}
public
boolean
getReuseAddress
()
throws
SocketException
{
public
boolean
getReuseAddress
()
throws
SocketException
{
return
opts
().
getReuseAddress
();
return
getBooleanOption
(
StandardSocketOption
.
SO_REUSEADDR
);
}
}
public
void
setBroadcast
(
boolean
on
)
throws
SocketException
{
public
void
setBroadcast
(
boolean
on
)
throws
SocketException
{
opts
().
setBroadcast
(
on
);
setBooleanOption
(
StandardSocketOption
.
SO_BROADCAST
,
on
);
}
}
public
boolean
getBroadcast
()
throws
SocketException
{
public
boolean
getBroadcast
()
throws
SocketException
{
return
opts
().
getBroadcast
(
);
return
getBooleanOption
(
StandardSocketOption
.
SO_BROADCAST
);
}
}
public
void
setTrafficClass
(
int
tc
)
throws
SocketException
{
public
void
setTrafficClass
(
int
tc
)
throws
SocketException
{
opts
().
setTrafficClass
(
tc
);
setIntOption
(
StandardSocketOption
.
IP_TOS
,
tc
);
trafficClass
=
tc
;
}
}
public
int
getTrafficClass
()
throws
SocketException
{
public
int
getTrafficClass
()
throws
SocketException
{
int
tc
=
opts
().
getTrafficClass
();
return
getIntOption
(
StandardSocketOption
.
IP_TOS
);
if
(
tc
<
0
)
{
tc
=
trafficClass
;
}
return
tc
;
}
}
public
void
close
()
{
public
void
close
()
{
...
...
src/share/classes/sun/nio/ch/ExtendedSocketOption.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
sun.nio.ch
;
import
java.net.SocketOption
;
/**
* Defines socket options that are supported by the implementation
* but not defined in StandardSocketOption.
*/
class
ExtendedSocketOption
{
private
ExtendedSocketOption
()
{
}
static
final
SocketOption
<
Boolean
>
SO_OOBINLINE
=
new
SocketOption
<
Boolean
>()
{
public
String
name
()
{
return
"SO_OOBINLINE"
;
}
public
Class
<
Boolean
>
type
()
{
return
Boolean
.
class
;
}
public
String
toString
()
{
return
name
();
}
};
}
src/share/classes/sun/nio/ch/MembershipKeyImpl.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
sun.nio.ch
;
import
java.nio.channels.*
;
import
java.net.InetAddress
;
import
java.net.NetworkInterface
;
import
java.io.IOException
;
import
java.util.HashSet
;
/**
* MembershipKey implementation.
*/
class
MembershipKeyImpl
extends
MembershipKey
{
private
final
MulticastChannel
ch
;
private
final
InetAddress
group
;
private
final
NetworkInterface
interf
;
private
final
InetAddress
source
;
// true when key is valid
private
volatile
boolean
valid
=
true
;
// lock used when creating or accessing blockedSet
private
Object
stateLock
=
new
Object
();
// set of source addresses that are blocked
private
HashSet
<
InetAddress
>
blockedSet
;
private
MembershipKeyImpl
(
MulticastChannel
ch
,
InetAddress
group
,
NetworkInterface
interf
,
InetAddress
source
)
{
this
.
ch
=
ch
;
this
.
group
=
group
;
this
.
interf
=
interf
;
this
.
source
=
source
;
}
/**
* MembershipKey will additional context for IPv4 membership
*/
static
class
Type4
extends
MembershipKeyImpl
{
private
final
int
groupAddress
;
private
final
int
interfAddress
;
private
final
int
sourceAddress
;
Type4
(
MulticastChannel
ch
,
InetAddress
group
,
NetworkInterface
interf
,
InetAddress
source
,
int
groupAddress
,
int
interfAddress
,
int
sourceAddress
)
{
super
(
ch
,
group
,
interf
,
source
);
this
.
groupAddress
=
groupAddress
;
this
.
interfAddress
=
interfAddress
;
this
.
sourceAddress
=
sourceAddress
;
}
int
group
()
{
return
groupAddress
;
}
int
interfaceAddress
()
{
return
interfAddress
;
}
int
source
()
{
return
sourceAddress
;
}
}
/**
* MembershipKey will additional context for IPv6 membership
*/
static
class
Type6
extends
MembershipKeyImpl
{
private
final
byte
[]
groupAddress
;
private
final
int
index
;
private
final
byte
[]
sourceAddress
;
Type6
(
MulticastChannel
ch
,
InetAddress
group
,
NetworkInterface
interf
,
InetAddress
source
,
byte
[]
groupAddress
,
int
index
,
byte
[]
sourceAddress
)
{
super
(
ch
,
group
,
interf
,
source
);
this
.
groupAddress
=
groupAddress
;
this
.
index
=
index
;
this
.
sourceAddress
=
sourceAddress
;
}
byte
[]
group
()
{
return
groupAddress
;
}
int
index
()
{
return
index
;
}
byte
[]
source
()
{
return
sourceAddress
;
}
}
public
boolean
isValid
()
{
return
valid
;
}
// package-private
void
invalidate
()
{
valid
=
false
;
}
public
void
drop
()
throws
IOException
{
// delegate to channel
((
DatagramChannelImpl
)
ch
).
drop
(
this
);
}
@Override
public
MulticastChannel
getChannel
()
{
return
ch
;
}
@Override
public
InetAddress
getGroup
()
{
return
group
;
}
@Override
public
NetworkInterface
getNetworkInterface
()
{
return
interf
;
}
@Override
public
InetAddress
getSourceAddress
()
{
return
source
;
}
@Override
public
MembershipKey
block
(
InetAddress
toBlock
)
throws
IOException
{
if
(
source
!=
null
)
throw
new
IllegalStateException
(
"key is source-specific"
);
synchronized
(
stateLock
)
{
if
((
blockedSet
!=
null
)
&&
blockedSet
.
contains
(
toBlock
))
{
// already blocked, nothing to do
return
this
;
}
((
DatagramChannelImpl
)
ch
).
block
(
this
,
toBlock
);
// created blocked set if required and add source address
if
(
blockedSet
==
null
)
blockedSet
=
new
HashSet
<
InetAddress
>();
blockedSet
.
add
(
toBlock
);
}
return
this
;
}
@Override
public
MembershipKey
unblock
(
InetAddress
toUnblock
)
throws
IOException
{
synchronized
(
stateLock
)
{
if
((
blockedSet
==
null
)
||
!
blockedSet
.
contains
(
toUnblock
))
throw
new
IllegalStateException
(
"not blocked"
);
((
DatagramChannelImpl
)
ch
).
unblock
(
this
,
toUnblock
);
blockedSet
.
remove
(
toUnblock
);
}
return
this
;
}
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
(
64
);
sb
.
append
(
'<'
);
sb
.
append
(
group
.
getHostAddress
());
sb
.
append
(
','
);
sb
.
append
(
interf
.
getName
());
if
(
source
!=
null
)
{
sb
.
append
(
','
);
sb
.
append
(
source
.
getHostAddress
());
}
sb
.
append
(
'>'
);
return
sb
.
toString
();
}
}
src/share/classes/sun/nio/ch/MembershipRegistry.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
sun.nio.ch
;
import
java.nio.channels.*
;
import
java.net.InetAddress
;
import
java.net.NetworkInterface
;
import
java.util.*
;
/**
* Simple registry of membership keys for a MulticastChannel.
*
* Instances of this object are not safe by multiple concurrent threads.
*/
class
MembershipRegistry
{
// map multicast group to keys
private
Map
<
InetAddress
,
List
<
MembershipKeyImpl
>>
groups
=
null
;
MembershipRegistry
()
{
}
/**
* Checks registry for membership of the group on the given
* network interface.
*/
MembershipKey
checkMembership
(
InetAddress
group
,
NetworkInterface
interf
,
InetAddress
source
)
{
if
(
groups
!=
null
)
{
List
<
MembershipKeyImpl
>
keys
=
groups
.
get
(
group
);
if
(
keys
!=
null
)
{
for
(
MembershipKeyImpl
key:
keys
)
{
if
(
key
.
getNetworkInterface
().
equals
(
interf
))
{
// already a member to receive all packets so return
// existing key or detect conflict
if
(
source
==
null
)
{
if
(
key
.
getSourceAddress
()
==
null
)
return
key
;
throw
new
IllegalStateException
(
"Already a member to receive all packets"
);
}
// already have source-specific membership so return key
// or detect conflict
if
(
key
.
getSourceAddress
()
==
null
)
throw
new
IllegalStateException
(
"Already have source-specific membership"
);
if
(
source
.
equals
(
key
.
getSourceAddress
()))
return
key
;
}
}
}
}
return
null
;
}
/**
* Add membership to the registry, returning a new membership key.
*/
void
add
(
MembershipKeyImpl
key
)
{
InetAddress
group
=
key
.
getGroup
();
List
<
MembershipKeyImpl
>
keys
;
if
(
groups
==
null
)
{
groups
=
new
HashMap
<
InetAddress
,
List
<
MembershipKeyImpl
>>();
keys
=
null
;
}
else
{
keys
=
groups
.
get
(
group
);
}
if
(
keys
==
null
)
{
keys
=
new
LinkedList
<
MembershipKeyImpl
>();
groups
.
put
(
group
,
keys
);
}
keys
.
add
(
key
);
}
/**
* Remove a key from the registry
*/
void
remove
(
MembershipKeyImpl
key
)
{
InetAddress
group
=
key
.
getGroup
();
List
<
MembershipKeyImpl
>
keys
=
groups
.
get
(
group
);
if
(
keys
!=
null
)
{
Iterator
<
MembershipKeyImpl
>
i
=
keys
.
iterator
();
while
(
i
.
hasNext
())
{
if
(
i
.
next
()
==
key
)
{
i
.
remove
();
break
;
}
}
if
(
keys
.
isEmpty
())
{
groups
.
remove
(
group
);
}
}
}
/**
* Invalidate all keys in the registry
*/
void
invalidateAll
()
{
for
(
InetAddress
group:
groups
.
keySet
())
{
for
(
MembershipKeyImpl
key:
groups
.
get
(
group
))
{
key
.
invalidate
();
}
}
}
}
src/share/classes/sun/nio/ch/Net.java
浏览文件 @
ec347b32
...
@@ -26,21 +26,43 @@
...
@@ -26,21 +26,43 @@
package
sun.nio.ch
;
package
sun.nio.ch
;
import
java.io.*
;
import
java.io.*
;
import
java.lang.reflect.*
;
import
java.net.*
;
import
java.net.*
;
import
java.nio.channels.*
;
import
java.nio.channels.*
;
import
java.util.*
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
class
Net
{
// package-private
class
Net
{
// package-private
private
Net
()
{
}
private
Net
()
{
}
// unspecified protocol family
static
final
ProtocolFamily
UNSPEC
=
new
ProtocolFamily
()
{
public
String
name
()
{
return
"UNSPEC"
;
}
};
// -- Miscellaneous utilities --
// -- Miscellaneous utilities --
private
static
volatile
boolean
checkedIPv6
=
false
;
private
static
volatile
boolean
isIPv6Available
;
/**
* Tells whether dual-IPv4/IPv6 sockets should be used.
*/
static
boolean
isIPv6Available
()
{
if
(!
checkedIPv6
)
{
isIPv6Available
=
isIPv6Available0
();
checkedIPv6
=
true
;
}
return
isIPv6Available
;
}
static
InetSocketAddress
checkAddress
(
SocketAddress
sa
)
{
static
InetSocketAddress
checkAddress
(
SocketAddress
sa
)
{
if
(
sa
==
null
)
if
(
sa
==
null
)
throw
new
IllegalArgument
Exception
();
throw
new
NullPointer
Exception
();
if
(!(
sa
instanceof
InetSocketAddress
))
if
(!(
sa
instanceof
InetSocketAddress
))
throw
new
UnsupportedAddressTypeException
();
// ## needs arg
throw
new
UnsupportedAddressTypeException
();
// ## needs arg
InetSocketAddress
isa
=
(
InetSocketAddress
)
sa
;
InetSocketAddress
isa
=
(
InetSocketAddress
)
sa
;
...
@@ -63,6 +85,8 @@ class Net { // package-private
...
@@ -63,6 +85,8 @@ class Net { // package-private
Exception
nx
=
x
;
Exception
nx
=
x
;
if
(
x
instanceof
ClosedChannelException
)
if
(
x
instanceof
ClosedChannelException
)
nx
=
new
SocketException
(
"Socket is closed"
);
nx
=
new
SocketException
(
"Socket is closed"
);
else
if
(
x
instanceof
NotYetConnectedException
)
nx
=
new
SocketException
(
"Socket is not connected"
);
else
if
(
x
instanceof
AlreadyBoundException
)
else
if
(
x
instanceof
AlreadyBoundException
)
nx
=
new
SocketException
(
"Already bound"
);
nx
=
new
SocketException
(
"Already bound"
);
else
if
(
x
instanceof
NotYetBoundException
)
else
if
(
x
instanceof
NotYetBoundException
)
...
@@ -105,73 +129,359 @@ class Net { // package-private
...
@@ -105,73 +129,359 @@ class Net { // package-private
translateException
(
x
,
false
);
translateException
(
x
,
false
);
}
}
/**
* Returns any IPv4 address of the given network interface, or
* null if the interface does not have any IPv4 addresses.
*/
static
Inet4Address
anyInet4Address
(
final
NetworkInterface
interf
)
{
return
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Inet4Address
>()
{
public
Inet4Address
run
()
{
Enumeration
<
InetAddress
>
addrs
=
interf
.
getInetAddresses
();
while
(
addrs
.
hasMoreElements
())
{
InetAddress
addr
=
addrs
.
nextElement
();
if
(
addr
instanceof
Inet4Address
)
{
return
(
Inet4Address
)
addr
;
}
}
return
null
;
}
});
}
/**
* Returns an IPv4 address as an int.
*/
static
int
inet4AsInt
(
InetAddress
ia
)
{
if
(
ia
instanceof
Inet4Address
)
{
byte
[]
addr
=
ia
.
getAddress
();
int
address
=
addr
[
3
]
&
0xFF
;
address
|=
((
addr
[
2
]
<<
8
)
&
0xFF00
);
address
|=
((
addr
[
1
]
<<
16
)
&
0xFF0000
);
address
|=
((
addr
[
0
]
<<
24
)
&
0xFF000000
);
return
address
;
}
throw
new
AssertionError
(
"Should not reach here"
);
}
/**
* Returns an InetAddress from the given IPv4 address
* represented as an int.
*/
static
InetAddress
inet4FromInt
(
int
address
)
{
byte
[]
addr
=
new
byte
[
4
];
addr
[
0
]
=
(
byte
)
((
address
>>>
24
)
&
0xFF
);
addr
[
1
]
=
(
byte
)
((
address
>>>
16
)
&
0xFF
);
addr
[
2
]
=
(
byte
)
((
address
>>>
8
)
&
0xFF
);
addr
[
3
]
=
(
byte
)
(
address
&
0xFF
);
try
{
return
InetAddress
.
getByAddress
(
addr
);
}
catch
(
UnknownHostException
uhe
)
{
throw
new
AssertionError
(
"Should not reach here"
);
}
}
/**
* Returns an IPv6 address as a byte array
*/
static
byte
[]
inet6AsByteArray
(
InetAddress
ia
)
{
if
(
ia
instanceof
Inet6Address
)
{
return
ia
.
getAddress
();
}
// need to construct IPv4-mapped address
if
(
ia
instanceof
Inet4Address
)
{
byte
[]
ip4address
=
ia
.
getAddress
();
byte
[]
address
=
new
byte
[
16
];
address
[
10
]
=
(
byte
)
0xff
;
address
[
11
]
=
(
byte
)
0xff
;
address
[
12
]
=
ip4address
[
0
];
address
[
13
]
=
ip4address
[
1
];
address
[
14
]
=
ip4address
[
2
];
address
[
15
]
=
ip4address
[
3
];
return
address
;
}
throw
new
AssertionError
(
"Should not reach here"
);
}
// -- Socket options
static
void
setSocketOption
(
FileDescriptor
fd
,
ProtocolFamily
family
,
SocketOption
name
,
Object
value
)
throws
IOException
{
if
(
value
==
null
)
throw
new
IllegalArgumentException
(
"Invalid option value"
);
// only simple values supported by this method
Class
<?>
type
=
name
.
type
();
if
(
type
!=
Integer
.
class
&&
type
!=
Boolean
.
class
)
throw
new
AssertionError
(
"Should not reach here"
);
// special handling
if
(
name
==
StandardSocketOption
.
SO_RCVBUF
||
name
==
StandardSocketOption
.
SO_SNDBUF
)
{
int
i
=
((
Integer
)
value
).
intValue
();
if
(
i
<
0
)
throw
new
IllegalArgumentException
(
"Invalid send/receive buffer size"
);
}
if
(
name
==
StandardSocketOption
.
SO_LINGER
)
{
int
i
=
((
Integer
)
value
).
intValue
();
if
(
i
<
0
)
value
=
Integer
.
valueOf
(-
1
);
if
(
i
>
65535
)
value
=
Integer
.
valueOf
(
65535
);
}
if
(
name
==
StandardSocketOption
.
IP_TOS
)
{
int
i
=
((
Integer
)
value
).
intValue
();
if
(
i
<
0
||
i
>
255
)
throw
new
IllegalArgumentException
(
"Invalid IP_TOS value"
);
}
if
(
name
==
StandardSocketOption
.
IP_MULTICAST_TTL
)
{
int
i
=
((
Integer
)
value
).
intValue
();
if
(
i
<
0
||
i
>
255
)
throw
new
IllegalArgumentException
(
"Invalid TTL/hop value"
);
}
// map option name to platform level/name
OptionKey
key
=
SocketOptionRegistry
.
findOption
(
name
,
family
);
if
(
key
==
null
)
throw
new
AssertionError
(
"Option not found"
);
int
arg
;
if
(
type
==
Integer
.
class
)
{
arg
=
((
Integer
)
value
).
intValue
();
}
else
{
boolean
b
=
((
Boolean
)
value
).
booleanValue
();
arg
=
(
b
)
?
1
:
0
;
}
boolean
mayNeedConversion
=
(
family
==
UNSPEC
);
setIntOption0
(
fd
,
mayNeedConversion
,
key
.
level
(),
key
.
name
(),
arg
);
}
static
Object
getSocketOption
(
FileDescriptor
fd
,
ProtocolFamily
family
,
SocketOption
name
)
throws
IOException
{
Class
<?>
type
=
name
.
type
();
// only simple values supported by this method
if
(
type
!=
Integer
.
class
&&
type
!=
Boolean
.
class
)
throw
new
AssertionError
(
"Should not reach here"
);
// map option name to platform level/name
OptionKey
key
=
SocketOptionRegistry
.
findOption
(
name
,
family
);
if
(
key
==
null
)
throw
new
AssertionError
(
"Option not found"
);
boolean
mayNeedConversion
=
(
family
==
UNSPEC
);
int
value
=
getIntOption0
(
fd
,
mayNeedConversion
,
key
.
level
(),
key
.
name
());
if
(
type
==
Integer
.
class
)
{
return
Integer
.
valueOf
(
value
);
}
else
{
return
(
value
==
0
)
?
Boolean
.
FALSE
:
Boolean
.
TRUE
;
}
}
// -- Socket operations --
// -- Socket operations --
static
native
boolean
isIPv6Available0
();
static
FileDescriptor
socket
(
boolean
stream
)
{
static
FileDescriptor
socket
(
boolean
stream
)
{
return
IOUtil
.
newFD
(
socket0
(
stream
,
false
));
return
socket
(
UNSPEC
,
stream
);
}
static
FileDescriptor
socket
(
ProtocolFamily
family
,
boolean
stream
)
{
boolean
preferIPv6
=
isIPv6Available
()
&&
(
family
!=
StandardProtocolFamily
.
INET
);
return
IOUtil
.
newFD
(
socket0
(
preferIPv6
,
stream
,
false
));
}
}
static
FileDescriptor
serverSocket
(
boolean
stream
)
{
static
FileDescriptor
serverSocket
(
boolean
stream
)
{
return
IOUtil
.
newFD
(
socket0
(
stream
,
true
));
return
IOUtil
.
newFD
(
socket0
(
isIPv6Available
(),
stream
,
true
));
}
}
// Due to oddities SO_REUSEADDR on windows reuse is ignored
// Due to oddities SO_REUSEADDR on windows reuse is ignored
private
static
native
int
socket0
(
boolean
stream
,
boolean
reuse
);
private
static
native
int
socket0
(
boolean
preferIPv6
,
boolean
stream
,
boolean
reuse
);
static
void
bind
(
FileDescriptor
fd
,
InetAddress
addr
,
int
port
)
throws
IOException
{
bind
(
UNSPEC
,
fd
,
addr
,
port
);
}
static
native
void
bind
(
FileDescriptor
fd
,
InetAddress
addr
,
int
port
)
static
void
bind
(
ProtocolFamily
family
,
FileDescriptor
fd
,
InetAddress
addr
,
int
port
)
throws
IOException
{
boolean
preferIPv6
=
isIPv6Available
()
&&
(
family
!=
StandardProtocolFamily
.
INET
);
bind0
(
preferIPv6
,
fd
,
addr
,
port
);
}
private
static
native
void
bind0
(
boolean
preferIPv6
,
FileDescriptor
fd
,
InetAddress
addr
,
int
port
)
throws
IOException
;
throws
IOException
;
static
native
int
connect
(
FileDescriptor
fd
,
static
native
void
listen
(
FileDescriptor
fd
,
int
backlog
)
throws
IOException
;
InetAddress
remote
,
int
remotePort
,
static
int
connect
(
FileDescriptor
fd
,
InetAddress
remote
,
int
remotePort
)
int
trafficClass
)
throws
IOException
{
return
connect
(
UNSPEC
,
fd
,
remote
,
remotePort
);
}
static
int
connect
(
ProtocolFamily
family
,
FileDescriptor
fd
,
InetAddress
remote
,
int
remotePort
)
throws
IOException
{
boolean
preferIPv6
=
isIPv6Available
()
&&
(
family
!=
StandardProtocolFamily
.
INET
);
return
connect0
(
preferIPv6
,
fd
,
remote
,
remotePort
);
}
private
static
native
int
connect0
(
boolean
preferIPv6
,
FileDescriptor
fd
,
InetAddress
remote
,
int
remotePort
)
throws
IOException
;
throws
IOException
;
public
final
static
int
SHUT_RD
=
0
;
public
final
static
int
SHUT_WR
=
1
;
public
final
static
int
SHUT_RDWR
=
2
;
static
native
void
shutdown
(
FileDescriptor
fd
,
int
how
)
throws
IOException
;
private
static
native
int
localPort
(
FileDescriptor
fd
)
private
static
native
int
localPort
(
FileDescriptor
fd
)
throws
IOException
;
throws
IOException
;
private
static
native
InetAddress
localInetAddress
(
FileDescriptor
fd
)
private
static
native
InetAddress
localInetAddress
(
FileDescriptor
fd
)
throws
IOException
;
throws
IOException
;
static
InetSocketAddress
localAddress
(
FileDescriptor
fd
)
{
static
InetSocketAddress
localAddress
(
FileDescriptor
fd
)
try
{
throws
IOException
return
new
InetSocketAddress
(
localInetAddress
(
fd
),
{
localPort
(
fd
));
return
new
InetSocketAddress
(
localInetAddress
(
fd
),
localPort
(
fd
));
}
catch
(
IOException
x
)
{
throw
new
Error
(
x
);
// Can't happen
}
}
}
static
int
localPortNumber
(
FileDescriptor
fd
)
{
private
static
native
int
remotePort
(
FileDescriptor
fd
)
try
{
throws
IOException
;
return
localPort
(
fd
);
}
catch
(
IOException
x
)
{
private
static
native
InetAddress
remoteInetAddress
(
FileDescriptor
fd
)
throw
new
Error
(
x
);
// Can't happen
throws
IOException
;
}
static
InetSocketAddress
remoteAddress
(
FileDescriptor
fd
)
throws
IOException
{
return
new
InetSocketAddress
(
remoteInetAddress
(
fd
),
remotePort
(
fd
));
}
private
static
native
int
getIntOption0
(
FileDescriptor
fd
,
boolean
mayNeedConversion
,
int
level
,
int
opt
)
throws
IOException
;
private
static
native
void
setIntOption0
(
FileDescriptor
fd
,
boolean
mayNeedConversion
,
int
level
,
int
opt
,
int
arg
)
throws
IOException
;
// -- Multicast support --
/**
* Join IPv4 multicast group
*/
static
int
join4
(
FileDescriptor
fd
,
int
group
,
int
interf
,
int
source
)
throws
IOException
{
return
joinOrDrop4
(
true
,
fd
,
group
,
interf
,
source
);
}
/**
* Drop membership of IPv4 multicast group
*/
static
void
drop4
(
FileDescriptor
fd
,
int
group
,
int
interf
,
int
source
)
throws
IOException
{
joinOrDrop4
(
false
,
fd
,
group
,
interf
,
source
);
}
private
static
native
int
joinOrDrop4
(
boolean
join
,
FileDescriptor
fd
,
int
group
,
int
interf
,
int
source
)
throws
IOException
;
/**
* Block IPv4 source
*/
static
int
block4
(
FileDescriptor
fd
,
int
group
,
int
interf
,
int
source
)
throws
IOException
{
return
blockOrUnblock4
(
true
,
fd
,
group
,
interf
,
source
);
}
/**
* Unblock IPv6 source
*/
static
void
unblock4
(
FileDescriptor
fd
,
int
group
,
int
interf
,
int
source
)
throws
IOException
{
blockOrUnblock4
(
false
,
fd
,
group
,
interf
,
source
);
}
}
private
static
native
int
getIntOption0
(
FileDescriptor
fd
,
int
opt
)
private
static
native
int
blockOrUnblock4
(
boolean
block
,
FileDescriptor
fd
,
int
group
,
int
interf
,
int
source
)
throws
IOException
;
throws
IOException
;
static
int
getIntOption
(
FileDescriptor
fd
,
int
opt
)
/**
* Join IPv6 multicast group
*/
static
int
join6
(
FileDescriptor
fd
,
byte
[]
group
,
int
index
,
byte
[]
source
)
throws
IOException
throws
IOException
{
{
return
getIntOption0
(
fd
,
opt
);
return
joinOrDrop6
(
true
,
fd
,
group
,
index
,
source
);
}
}
/**
* Drop membership of IPv6 multicast group
*/
static
void
drop6
(
FileDescriptor
fd
,
byte
[]
group
,
int
index
,
byte
[]
source
)
throws
IOException
{
joinOrDrop6
(
false
,
fd
,
group
,
index
,
source
);
}
private
static
native
void
setIntOption0
(
FileDescriptor
fd
,
private
static
native
int
joinOrDrop6
(
boolean
join
,
FileDescriptor
fd
,
byte
[]
group
,
int
index
,
byte
[]
source
)
int
opt
,
int
arg
)
throws
IOException
;
throws
IOException
;
static
void
setIntOption
(
FileDescriptor
fd
,
int
opt
,
int
arg
)
/**
* Block IPv6 source
*/
static
int
block6
(
FileDescriptor
fd
,
byte
[]
group
,
int
index
,
byte
[]
source
)
throws
IOException
{
return
blockOrUnblock6
(
true
,
fd
,
group
,
index
,
source
);
}
/**
* Unblock IPv6 source
*/
static
void
unblock6
(
FileDescriptor
fd
,
byte
[]
group
,
int
index
,
byte
[]
source
)
throws
IOException
throws
IOException
{
{
setIntOption0
(
fd
,
opt
,
arg
);
blockOrUnblock6
(
false
,
fd
,
group
,
index
,
source
);
}
}
static
native
int
blockOrUnblock6
(
boolean
block
,
FileDescriptor
fd
,
byte
[]
group
,
int
index
,
byte
[]
source
)
throws
IOException
;
static
native
void
setInterface4
(
FileDescriptor
fd
,
int
interf
)
throws
IOException
;
static
native
int
getInterface4
(
FileDescriptor
fd
)
throws
IOException
;
static
native
void
setInterface6
(
FileDescriptor
fd
,
int
index
)
throws
IOException
;
static
native
int
getInterface6
(
FileDescriptor
fd
)
throws
IOException
;
private
static
native
void
initIDs
();
private
static
native
void
initIDs
();
static
{
static
{
...
...
src/share/classes/sun/nio/ch/OptionAdaptor.java
已删除
100644 → 0
浏览文件 @
70763cd4
/*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
sun.nio.ch
;
import
java.io.*
;
import
java.net.*
;
import
java.nio.*
;
import
java.nio.channels.*
;
// Adaptor class for java.net-style options
//
// The option get/set methods in the socket, server-socket, and datagram-socket
// adaptors delegate to an instance of this class.
//
class
OptionAdaptor
{
// package-private
private
final
SocketOpts
.
IP
opts
;
OptionAdaptor
(
SocketChannelImpl
sc
)
{
opts
=
(
SocketOpts
.
IP
)
sc
.
options
();
}
OptionAdaptor
(
ServerSocketChannelImpl
ssc
)
{
opts
=
(
SocketOpts
.
IP
)
ssc
.
options
();
}
OptionAdaptor
(
DatagramChannelImpl
dc
)
{
opts
=
(
SocketOpts
.
IP
)
dc
.
options
();
}
private
SocketOpts
.
IP
opts
()
{
return
opts
;
}
private
SocketOpts
.
IP
.
TCP
tcpOpts
()
{
return
(
SocketOpts
.
IP
.
TCP
)
opts
;
}
public
void
setTcpNoDelay
(
boolean
on
)
throws
SocketException
{
try
{
tcpOpts
().
noDelay
(
on
);
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
public
boolean
getTcpNoDelay
()
throws
SocketException
{
try
{
return
tcpOpts
().
noDelay
();
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
return
false
;
// Never happens
}
}
public
void
setSoLinger
(
boolean
on
,
int
linger
)
throws
SocketException
{
try
{
if
(
linger
>
65535
)
linger
=
65535
;
opts
().
linger
(
on
?
linger
:
-
1
);
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
public
int
getSoLinger
()
throws
SocketException
{
try
{
return
opts
().
linger
();
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
return
0
;
// Never happens
}
}
public
void
setOOBInline
(
boolean
on
)
throws
SocketException
{
try
{
opts
().
outOfBandInline
(
on
);
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
public
boolean
getOOBInline
()
throws
SocketException
{
try
{
return
opts
().
outOfBandInline
();
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
return
false
;
// Never happens
}
}
public
void
setSendBufferSize
(
int
size
)
throws
SocketException
{
try
{
opts
().
sendBufferSize
(
size
);
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
public
int
getSendBufferSize
()
throws
SocketException
{
try
{
return
opts
().
sendBufferSize
();
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
return
0
;
// Never happens
}
}
public
void
setReceiveBufferSize
(
int
size
)
throws
SocketException
{
try
{
opts
().
receiveBufferSize
(
size
);
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
public
int
getReceiveBufferSize
()
throws
SocketException
{
try
{
return
opts
().
receiveBufferSize
();
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
return
0
;
// Never happens
}
}
public
void
setKeepAlive
(
boolean
on
)
throws
SocketException
{
try
{
opts
().
keepAlive
(
on
);
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
public
boolean
getKeepAlive
()
throws
SocketException
{
try
{
return
opts
().
keepAlive
();
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
return
false
;
// Never happens
}
}
public
void
setTrafficClass
(
int
tc
)
throws
SocketException
{
if
(
tc
<
0
||
tc
>
255
)
throw
new
IllegalArgumentException
(
"tc is not in range 0 -- 255"
);
try
{
opts
().
typeOfService
(
tc
);
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
public
int
getTrafficClass
()
throws
SocketException
{
try
{
return
opts
().
typeOfService
();
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
return
0
;
// Never happens
}
}
public
void
setReuseAddress
(
boolean
on
)
throws
SocketException
{
try
{
opts
().
reuseAddress
(
on
);
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
public
boolean
getReuseAddress
()
throws
SocketException
{
try
{
return
opts
().
reuseAddress
();
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
return
false
;
// Never happens
}
}
public
void
setBroadcast
(
boolean
on
)
throws
SocketException
{
try
{
opts
().
broadcast
(
on
);
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
public
boolean
getBroadcast
()
throws
SocketException
{
try
{
return
opts
().
broadcast
();
}
catch
(
Exception
x
)
{
Net
.
translateToSocketException
(
x
);
return
false
;
// Never happens
}
}
}
src/share/classes/sun/nio/ch/
SocketOpts
.java
→
src/share/classes/sun/nio/ch/
OptionKey
.java
浏览文件 @
ec347b32
/*
/*
* Copyright 200
1
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 200
7-2008
Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -25,91 +25,24 @@
...
@@ -25,91 +25,24 @@
package
sun.nio.ch
;
package
sun.nio.ch
;
import
java.io.IOException
;
/**
import
java.nio.*
;
* Represents the level/name of a socket option
import
java.net.NetworkInterface
;
*/
// Typical use:
//
// sc.options()
// .noDelay(true)
// .typeOfService(SocketOpts.IP.TOS_RELIABILITY)
// .sendBufferSize(1024)
// .receiveBufferSize(1024)
// .keepAlive(true);
//
public
interface
SocketOpts
{
// SocketOptions already used in java.net
// Options that apply to all kinds of sockets
// SO_BROADCAST
public
abstract
boolean
broadcast
()
throws
IOException
;
public
abstract
SocketOpts
broadcast
(
boolean
b
)
throws
IOException
;
// SO_KEEPALIVE
public
abstract
boolean
keepAlive
()
throws
IOException
;
public
abstract
SocketOpts
keepAlive
(
boolean
b
)
throws
IOException
;
// SO_LINGER
public
abstract
int
linger
()
throws
IOException
;
public
abstract
SocketOpts
linger
(
int
n
)
throws
IOException
;
// SO_OOBINLINE
public
abstract
boolean
outOfBandInline
()
throws
IOException
;
public
abstract
SocketOpts
outOfBandInline
(
boolean
b
)
throws
IOException
;
// SO_RCVBUF
public
abstract
int
receiveBufferSize
()
throws
IOException
;
public
abstract
SocketOpts
receiveBufferSize
(
int
n
)
throws
IOException
;
// SO_SNDBUF
public
abstract
int
sendBufferSize
()
throws
IOException
;
public
abstract
SocketOpts
sendBufferSize
(
int
n
)
throws
IOException
;
// SO_REUSEADDR
public
abstract
boolean
reuseAddress
()
throws
IOException
;
public
abstract
SocketOpts
reuseAddress
(
boolean
b
)
throws
IOException
;
// IP-specific options
public
static
interface
IP
extends
SocketOpts
{
// IP_MULTICAST_IF2
public
abstract
NetworkInterface
multicastInterface
()
throws
IOException
;
public
abstract
IP
multicastInterface
(
NetworkInterface
ni
)
throws
IOException
;
// IP_MULTICAST_LOOP
public
abstract
boolean
multicastLoop
()
throws
IOException
;
public
abstract
IP
multicastLoop
(
boolean
b
)
throws
IOException
;
// IP_TOS
public
static
final
int
TOS_LOWDELAY
=
0x10
;
public
static
final
int
TOS_THROUGHPUT
=
0x08
;
public
static
final
int
TOS_RELIABILITY
=
0x04
;
public
static
final
int
TOS_MINCOST
=
0x02
;
public
abstract
int
typeOfService
()
throws
IOException
;
public
abstract
IP
typeOfService
(
int
tos
)
throws
IOException
;
// TCP-specific options
public
static
interface
TCP
class
OptionKey
{
extends
IP
private
int
level
;
{
private
int
name
;
// TCP_NODELAY
public
abstract
boolean
noDelay
()
throws
IOException
;
public
abstract
TCP
noDelay
(
boolean
b
)
throws
IOException
;
}
OptionKey
(
int
level
,
int
name
)
{
this
.
level
=
level
;
this
.
name
=
name
;
}
int
level
()
{
return
level
;
}
}
int
name
()
{
return
name
;
}
}
}
src/share/classes/sun/nio/ch/SelectorProviderImpl.java
浏览文件 @
ec347b32
...
@@ -29,6 +29,7 @@ import java.io.FileDescriptor;
...
@@ -29,6 +29,7 @@ import java.io.FileDescriptor;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.net.ServerSocket
;
import
java.net.ServerSocket
;
import
java.net.Socket
;
import
java.net.Socket
;
import
java.net.ProtocolFamily
;
import
java.nio.channels.*
;
import
java.nio.channels.*
;
import
java.nio.channels.spi.*
;
import
java.nio.channels.spi.*
;
...
@@ -41,6 +42,10 @@ public abstract class SelectorProviderImpl
...
@@ -41,6 +42,10 @@ public abstract class SelectorProviderImpl
return
new
DatagramChannelImpl
(
this
);
return
new
DatagramChannelImpl
(
this
);
}
}
public
DatagramChannel
openDatagramChannel
(
ProtocolFamily
family
)
throws
IOException
{
return
new
DatagramChannelImpl
(
this
,
family
);
}
public
Pipe
openPipe
()
throws
IOException
{
public
Pipe
openPipe
()
throws
IOException
{
return
new
PipeImpl
(
this
);
return
new
PipeImpl
(
this
);
}
}
...
@@ -54,5 +59,4 @@ public abstract class SelectorProviderImpl
...
@@ -54,5 +59,4 @@ public abstract class SelectorProviderImpl
public
SocketChannel
openSocketChannel
()
throws
IOException
{
public
SocketChannel
openSocketChannel
()
throws
IOException
{
return
new
SocketChannelImpl
(
this
);
return
new
SocketChannelImpl
(
this
);
}
}
}
}
src/share/classes/sun/nio/ch/ServerSocketAdaptor.java
浏览文件 @
ec347b32
...
@@ -44,9 +44,6 @@ public class ServerSocketAdaptor // package-private
...
@@ -44,9 +44,6 @@ public class ServerSocketAdaptor // package-private
// The channel being adapted
// The channel being adapted
private
final
ServerSocketChannelImpl
ssc
;
private
final
ServerSocketChannelImpl
ssc
;
// Option adaptor object, created on demand
private
volatile
OptionAdaptor
opts
=
null
;
// Timeout "option" value for accepts
// Timeout "option" value for accepts
private
volatile
int
timeout
=
0
;
private
volatile
int
timeout
=
0
;
...
@@ -174,18 +171,21 @@ public class ServerSocketAdaptor // package-private
...
@@ -174,18 +171,21 @@ public class ServerSocketAdaptor // package-private
return
timeout
;
return
timeout
;
}
}
private
OptionAdaptor
opts
()
{
if
(
opts
==
null
)
opts
=
new
OptionAdaptor
(
ssc
);
return
opts
;
}
public
void
setReuseAddress
(
boolean
on
)
throws
SocketException
{
public
void
setReuseAddress
(
boolean
on
)
throws
SocketException
{
opts
().
setReuseAddress
(
on
);
try
{
ssc
.
setOption
(
StandardSocketOption
.
SO_REUSEADDR
,
on
);
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
}
public
boolean
getReuseAddress
()
throws
SocketException
{
public
boolean
getReuseAddress
()
throws
SocketException
{
return
opts
().
getReuseAddress
();
try
{
return
ssc
.
getOption
(
StandardSocketOption
.
SO_REUSEADDR
).
booleanValue
();
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
return
false
;
// Never happens
}
}
}
public
String
toString
()
{
public
String
toString
()
{
...
@@ -197,11 +197,23 @@ public class ServerSocketAdaptor // package-private
...
@@ -197,11 +197,23 @@ public class ServerSocketAdaptor // package-private
}
}
public
void
setReceiveBufferSize
(
int
size
)
throws
SocketException
{
public
void
setReceiveBufferSize
(
int
size
)
throws
SocketException
{
opts
().
setReceiveBufferSize
(
size
);
// size 0 valid for ServerSocketChannel, invalid for ServerSocket
if
(
size
<=
0
)
throw
new
IllegalArgumentException
(
"size cannot be 0 or negative"
);
try
{
ssc
.
setOption
(
StandardSocketOption
.
SO_RCVBUF
,
size
);
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
}
public
int
getReceiveBufferSize
()
throws
SocketException
{
public
int
getReceiveBufferSize
()
throws
SocketException
{
return
opts
().
getReceiveBufferSize
();
try
{
return
ssc
.
getOption
(
StandardSocketOption
.
SO_RCVBUF
).
intValue
();
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
return
-
1
;
// Never happens
}
}
}
}
}
src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
浏览文件 @
ec347b32
...
@@ -33,8 +33,7 @@ import java.nio.channels.*;
...
@@ -33,8 +33,7 @@ import java.nio.channels.*;
import
java.nio.channels.spi.*
;
import
java.nio.channels.spi.*
;
import
java.security.AccessController
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
import
java.security.PrivilegedAction
;
import
java.util.HashSet
;
import
java.util.*
;
import
java.util.Iterator
;
/**
/**
...
@@ -75,10 +74,7 @@ class ServerSocketChannelImpl
...
@@ -75,10 +74,7 @@ class ServerSocketChannelImpl
private
int
state
=
ST_UNINITIALIZED
;
private
int
state
=
ST_UNINITIALIZED
;
// Binding
// Binding
private
SocketAddress
localAddress
=
null
;
// null => unbound
private
SocketAddress
localAddress
;
// null => unbound
// Options, created on demand
private
SocketOpts
.
IP
.
TCP
options
=
null
;
// Our socket adaptor, if any
// Our socket adaptor, if any
ServerSocket
socket
;
ServerSocket
socket
;
...
@@ -103,7 +99,6 @@ class ServerSocketChannelImpl
...
@@ -103,7 +99,6 @@ class ServerSocketChannelImpl
localAddress
=
Net
.
localAddress
(
fd
);
localAddress
=
Net
.
localAddress
(
fd
);
}
}
public
ServerSocket
socket
()
{
public
ServerSocket
socket
()
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
if
(
socket
==
null
)
if
(
socket
==
null
)
...
@@ -112,6 +107,69 @@ class ServerSocketChannelImpl
...
@@ -112,6 +107,69 @@ class ServerSocketChannelImpl
}
}
}
}
@Override
public
SocketAddress
getLocalAddress
()
throws
IOException
{
synchronized
(
stateLock
)
{
if
(!
isOpen
())
return
null
;
return
localAddress
;
}
}
@Override
public
ServerSocketChannel
setOption
(
SocketOption
name
,
Object
value
)
throws
IOException
{
if
(
name
==
null
)
throw
new
NullPointerException
();
if
(!
options
().
contains
(
name
))
throw
new
IllegalArgumentException
(
"invalid option name"
);
synchronized
(
stateLock
)
{
if
(!
isOpen
())
throw
new
ClosedChannelException
();
// no options that require special handling
Net
.
setSocketOption
(
fd
,
Net
.
UNSPEC
,
name
,
value
);
return
this
;
}
}
@Override
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
getOption
(
SocketOption
<
T
>
name
)
throws
IOException
{
if
(
name
==
null
)
throw
new
NullPointerException
();
if
(!
options
().
contains
(
name
))
throw
new
IllegalArgumentException
(
"invalid option name"
);
synchronized
(
stateLock
)
{
if
(!
isOpen
())
throw
new
ClosedChannelException
();
// no options that require special handling
return
(
T
)
Net
.
getSocketOption
(
fd
,
Net
.
UNSPEC
,
name
);
}
}
private
static
class
LazyInitialization
{
static
final
Set
<
SocketOption
<?>>
defaultOptions
=
defaultOptions
();
private
static
Set
<
SocketOption
<?>>
defaultOptions
()
{
HashSet
<
SocketOption
<?>>
set
=
new
HashSet
<
SocketOption
<?>>(
2
);
set
.
add
(
StandardSocketOption
.
SO_RCVBUF
);
set
.
add
(
StandardSocketOption
.
SO_REUSEADDR
);
return
Collections
.
unmodifiableSet
(
set
);
}
}
@Override
public
final
Set
<
SocketOption
<?>>
options
()
{
return
LazyInitialization
.
defaultOptions
;
}
public
boolean
isBound
()
{
public
boolean
isBound
()
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
return
localAddress
!=
null
;
return
localAddress
!=
null
;
...
@@ -124,22 +182,25 @@ class ServerSocketChannelImpl
...
@@ -124,22 +182,25 @@ class ServerSocketChannelImpl
}
}
}
}
public
void
bind
(
SocketAddress
local
,
int
backlog
)
throws
IOException
{
@Override
public
ServerSocketChannel
bind
(
SocketAddress
local
,
int
backlog
)
throws
IOException
{
synchronized
(
lock
)
{
synchronized
(
lock
)
{
if
(!
isOpen
())
if
(!
isOpen
())
throw
new
ClosedChannelException
();
throw
new
ClosedChannelException
();
if
(
isBound
())
if
(
isBound
())
throw
new
AlreadyBoundException
();
throw
new
AlreadyBoundException
();
InetSocketAddress
isa
=
Net
.
checkAddress
(
local
);
InetSocketAddress
isa
=
(
local
==
null
)
?
new
InetSocketAddress
(
0
)
:
Net
.
checkAddress
(
local
);
SecurityManager
sm
=
System
.
getSecurityManager
();
SecurityManager
sm
=
System
.
getSecurityManager
();
if
(
sm
!=
null
)
if
(
sm
!=
null
)
sm
.
checkListen
(
isa
.
getPort
());
sm
.
checkListen
(
isa
.
getPort
());
Net
.
bind
(
fd
,
isa
.
getAddress
(),
isa
.
getPort
());
Net
.
bind
(
fd
,
isa
.
getAddress
(),
isa
.
getPort
());
listen
(
fd
,
backlog
<
1
?
50
:
backlog
);
Net
.
listen
(
fd
,
backlog
<
1
?
50
:
backlog
);
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
localAddress
=
Net
.
localAddress
(
fd
);
localAddress
=
Net
.
localAddress
(
fd
);
}
}
}
}
return
this
;
}
}
public
SocketChannel
accept
()
throws
IOException
{
public
SocketChannel
accept
()
throws
IOException
{
...
@@ -196,24 +257,6 @@ class ServerSocketChannelImpl
...
@@ -196,24 +257,6 @@ class ServerSocketChannelImpl
IOUtil
.
configureBlocking
(
fd
,
block
);
IOUtil
.
configureBlocking
(
fd
,
block
);
}
}
public
SocketOpts
options
()
{
synchronized
(
stateLock
)
{
if
(
options
==
null
)
{
SocketOptsImpl
.
Dispatcher
d
=
new
SocketOptsImpl
.
Dispatcher
()
{
int
getInt
(
int
opt
)
throws
IOException
{
return
Net
.
getIntOption
(
fd
,
opt
);
}
void
setInt
(
int
opt
,
int
arg
)
throws
IOException
{
Net
.
setIntOption
(
fd
,
opt
,
arg
);
}
};
options
=
new
SocketOptsImpl
.
IP
.
TCP
(
d
);
}
return
options
;
}
}
protected
void
implCloseSelectableChannel
()
throws
IOException
{
protected
void
implCloseSelectableChannel
()
throws
IOException
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
nd
.
preClose
(
fd
);
nd
.
preClose
(
fd
);
...
@@ -320,9 +363,6 @@ class ServerSocketChannelImpl
...
@@ -320,9 +363,6 @@ class ServerSocketChannelImpl
// -- Native methods --
// -- Native methods --
private
static
native
void
listen
(
FileDescriptor
fd
,
int
backlog
)
throws
IOException
;
// Accepts a new connection, setting the given file descriptor to refer to
// Accepts a new connection, setting the given file descriptor to refer to
// the new socket and setting isaa[0] to the socket's remote address.
// the new socket and setting isaa[0] to the socket's remote address.
// Returns 1 on success, or IOStatus.UNAVAILABLE (if non-blocking and no
// Returns 1 on success, or IOStatus.UNAVAILABLE (if non-blocking and no
...
...
src/share/classes/sun/nio/ch/SocketAdaptor.java
浏览文件 @
ec347b32
...
@@ -54,16 +54,9 @@ public class SocketAdaptor
...
@@ -54,16 +54,9 @@ public class SocketAdaptor
// The channel being adapted
// The channel being adapted
private
final
SocketChannelImpl
sc
;
private
final
SocketChannelImpl
sc
;
// Option adaptor object, created on demand
private
volatile
OptionAdaptor
opts
=
null
;
// Timeout "option" value for reads
// Timeout "option" value for reads
private
volatile
int
timeout
=
0
;
private
volatile
int
timeout
=
0
;
// Traffic-class/Type-of-service
private
volatile
int
trafficClass
=
0
;
// ## super will create a useless impl
// ## super will create a useless impl
private
SocketAdaptor
(
SocketChannelImpl
sc
)
{
private
SocketAdaptor
(
SocketChannelImpl
sc
)
{
this
.
sc
=
sc
;
this
.
sc
=
sc
;
...
@@ -145,8 +138,6 @@ public class SocketAdaptor
...
@@ -145,8 +138,6 @@ public class SocketAdaptor
public
void
bind
(
SocketAddress
local
)
throws
IOException
{
public
void
bind
(
SocketAddress
local
)
throws
IOException
{
try
{
try
{
if
(
local
==
null
)
local
=
new
InetSocketAddress
(
0
);
sc
.
bind
(
local
);
sc
.
bind
(
local
);
}
catch
(
Exception
x
)
{
}
catch
(
Exception
x
)
{
Net
.
translateException
(
x
);
Net
.
translateException
(
x
);
...
@@ -154,27 +145,39 @@ public class SocketAdaptor
...
@@ -154,27 +145,39 @@ public class SocketAdaptor
}
}
public
InetAddress
getInetAddress
()
{
public
InetAddress
getInetAddress
()
{
if
(!
sc
.
isConnected
())
SocketAddress
remote
=
sc
.
remoteAddress
();
if
(
remote
==
null
)
{
return
null
;
return
null
;
return
Net
.
asInetSocketAddress
(
sc
.
remoteAddress
()).
getAddress
();
}
else
{
return
((
InetSocketAddress
)
remote
).
getAddress
();
}
}
}
public
InetAddress
getLocalAddress
()
{
public
InetAddress
getLocalAddress
()
{
if
(!
sc
.
isBound
())
if
(
sc
.
isOpen
())
{
return
new
InetSocketAddress
(
0
).
getAddress
();
SocketAddress
local
=
sc
.
localAddress
();
return
Net
.
asInetSocketAddress
(
sc
.
localAddress
()).
getAddress
();
if
(
local
!=
null
)
return
((
InetSocketAddress
)
local
).
getAddress
();
}
return
new
InetSocketAddress
(
0
).
getAddress
();
}
}
public
int
getPort
()
{
public
int
getPort
()
{
if
(!
sc
.
isConnected
())
SocketAddress
remote
=
sc
.
remoteAddress
();
if
(
remote
==
null
)
{
return
0
;
return
0
;
return
Net
.
asInetSocketAddress
(
sc
.
remoteAddress
()).
getPort
();
}
else
{
return
((
InetSocketAddress
)
remote
).
getPort
();
}
}
}
public
int
getLocalPort
()
{
public
int
getLocalPort
()
{
if
(!
sc
.
isBound
())
SocketAddress
local
=
sc
.
localAddress
();
if
(
local
==
null
)
{
return
-
1
;
return
-
1
;
return
Net
.
asInetSocketAddress
(
sc
.
localAddress
()).
getPort
();
}
else
{
return
((
InetSocketAddress
)
local
).
getPort
();
}
}
}
private
class
SocketInputStream
private
class
SocketInputStream
...
@@ -276,26 +279,60 @@ public class SocketAdaptor
...
@@ -276,26 +279,60 @@ public class SocketAdaptor
return
os
;
return
os
;
}
}
private
OptionAdaptor
opts
()
{
private
void
setBooleanOption
(
SocketOption
<
Boolean
>
name
,
boolean
value
)
if
(
opts
==
null
)
throws
SocketException
opts
=
new
OptionAdaptor
(
sc
);
{
return
opts
;
try
{
sc
.
setOption
(
name
,
value
);
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
private
void
setIntOption
(
SocketOption
<
Integer
>
name
,
int
value
)
throws
SocketException
{
try
{
sc
.
setOption
(
name
,
value
);
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
}
}
private
boolean
getBooleanOption
(
SocketOption
<
Boolean
>
name
)
throws
SocketException
{
try
{
return
sc
.
getOption
(
name
).
booleanValue
();
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
return
false
;
// keep compiler happy
}
}
private
int
getIntOption
(
SocketOption
<
Integer
>
name
)
throws
SocketException
{
try
{
return
sc
.
getOption
(
name
).
intValue
();
}
catch
(
IOException
x
)
{
Net
.
translateToSocketException
(
x
);
return
-
1
;
// keep compiler happy
}
}
}
public
void
setTcpNoDelay
(
boolean
on
)
throws
SocketException
{
public
void
setTcpNoDelay
(
boolean
on
)
throws
SocketException
{
opts
().
setTcpNoDelay
(
on
);
setBooleanOption
(
StandardSocketOption
.
TCP_NODELAY
,
on
);
}
}
public
boolean
getTcpNoDelay
()
throws
SocketException
{
public
boolean
getTcpNoDelay
()
throws
SocketException
{
return
opts
().
getTcpNoDelay
(
);
return
getBooleanOption
(
StandardSocketOption
.
TCP_NODELAY
);
}
}
public
void
setSoLinger
(
boolean
on
,
int
linger
)
throws
SocketException
{
public
void
setSoLinger
(
boolean
on
,
int
linger
)
throws
SocketException
{
opts
().
setSoLinger
(
on
,
linger
);
if
(!
on
)
linger
=
-
1
;
setIntOption
(
StandardSocketOption
.
SO_LINGER
,
linger
);
}
}
public
int
getSoLinger
()
throws
SocketException
{
public
int
getSoLinger
()
throws
SocketException
{
return
opts
().
getSoLinger
(
);
return
getIntOption
(
StandardSocketOption
.
SO_LINGER
);
}
}
public
void
sendUrgentData
(
int
data
)
throws
IOException
{
public
void
sendUrgentData
(
int
data
)
throws
IOException
{
...
@@ -303,11 +340,11 @@ public class SocketAdaptor
...
@@ -303,11 +340,11 @@ public class SocketAdaptor
}
}
public
void
setOOBInline
(
boolean
on
)
throws
SocketException
{
public
void
setOOBInline
(
boolean
on
)
throws
SocketException
{
opts
().
setOOBInline
(
on
);
setBooleanOption
(
ExtendedSocketOption
.
SO_OOBINLINE
,
on
);
}
}
public
boolean
getOOBInline
()
throws
SocketException
{
public
boolean
getOOBInline
()
throws
SocketException
{
return
opts
().
getOOBInline
(
);
return
getBooleanOption
(
ExtendedSocketOption
.
SO_OOBINLINE
);
}
}
public
void
setSoTimeout
(
int
timeout
)
throws
SocketException
{
public
void
setSoTimeout
(
int
timeout
)
throws
SocketException
{
...
@@ -321,48 +358,49 @@ public class SocketAdaptor
...
@@ -321,48 +358,49 @@ public class SocketAdaptor
}
}
public
void
setSendBufferSize
(
int
size
)
throws
SocketException
{
public
void
setSendBufferSize
(
int
size
)
throws
SocketException
{
opts
().
setSendBufferSize
(
size
);
// size 0 valid for SocketChannel, invalid for Socket
if
(
size
<=
0
)
throw
new
IllegalArgumentException
(
"Invalid send size"
);
setIntOption
(
StandardSocketOption
.
SO_SNDBUF
,
size
);
}
}
public
int
getSendBufferSize
()
throws
SocketException
{
public
int
getSendBufferSize
()
throws
SocketException
{
return
opts
().
getSendBufferSize
(
);
return
getIntOption
(
StandardSocketOption
.
SO_SNDBUF
);
}
}
public
void
setReceiveBufferSize
(
int
size
)
throws
SocketException
{
public
void
setReceiveBufferSize
(
int
size
)
throws
SocketException
{
opts
().
setReceiveBufferSize
(
size
);
// size 0 valid for SocketChannel, invalid for Socket
if
(
size
<=
0
)
throw
new
IllegalArgumentException
(
"Invalid receive size"
);
setIntOption
(
StandardSocketOption
.
SO_RCVBUF
,
size
);
}
}
public
int
getReceiveBufferSize
()
throws
SocketException
{
public
int
getReceiveBufferSize
()
throws
SocketException
{
return
opts
().
getReceiveBufferSize
(
);
return
getIntOption
(
StandardSocketOption
.
SO_RCVBUF
);
}
}
public
void
setKeepAlive
(
boolean
on
)
throws
SocketException
{
public
void
setKeepAlive
(
boolean
on
)
throws
SocketException
{
opts
().
setKeepAlive
(
on
);
setBooleanOption
(
StandardSocketOption
.
SO_KEEPALIVE
,
on
);
}
}
public
boolean
getKeepAlive
()
throws
SocketException
{
public
boolean
getKeepAlive
()
throws
SocketException
{
return
opts
().
getKeepAlive
(
);
return
getBooleanOption
(
StandardSocketOption
.
SO_KEEPALIVE
);
}
}
public
void
setTrafficClass
(
int
tc
)
throws
SocketException
{
public
void
setTrafficClass
(
int
tc
)
throws
SocketException
{
opts
().
setTrafficClass
(
tc
);
setIntOption
(
StandardSocketOption
.
IP_TOS
,
tc
);
trafficClass
=
tc
;
}
}
public
int
getTrafficClass
()
throws
SocketException
{
public
int
getTrafficClass
()
throws
SocketException
{
int
tc
=
opts
().
getTrafficClass
();
return
getIntOption
(
StandardSocketOption
.
IP_TOS
);
if
(
tc
<
0
)
{
tc
=
trafficClass
;
}
return
tc
;
}
}
public
void
setReuseAddress
(
boolean
on
)
throws
SocketException
{
public
void
setReuseAddress
(
boolean
on
)
throws
SocketException
{
opts
().
setReuseAddress
(
on
);
setBooleanOption
(
StandardSocketOption
.
SO_REUSEADDR
,
on
);
}
}
public
boolean
getReuseAddress
()
throws
SocketException
{
public
boolean
getReuseAddress
()
throws
SocketException
{
return
opts
().
getReuseAddress
(
);
return
getBooleanOption
(
StandardSocketOption
.
SO_REUSEADDR
);
}
}
public
void
close
()
throws
IOException
{
public
void
close
()
throws
IOException
{
...
@@ -402,7 +440,7 @@ public class SocketAdaptor
...
@@ -402,7 +440,7 @@ public class SocketAdaptor
}
}
public
boolean
isBound
()
{
public
boolean
isBound
()
{
return
sc
.
isBound
()
;
return
sc
.
localAddress
()
!=
null
;
}
}
public
boolean
isClosed
()
{
public
boolean
isClosed
()
{
...
...
src/share/classes/sun/nio/ch/SocketChannelImpl.java
浏览文件 @
ec347b32
...
@@ -31,6 +31,7 @@ import java.net.*;
...
@@ -31,6 +31,7 @@ import java.net.*;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.nio.channels.*
;
import
java.nio.channels.*
;
import
java.nio.channels.spi.*
;
import
java.nio.channels.spi.*
;
import
java.util.*
;
/**
/**
...
@@ -78,19 +79,16 @@ class SocketChannelImpl
...
@@ -78,19 +79,16 @@ class SocketChannelImpl
private
int
state
=
ST_UNINITIALIZED
;
private
int
state
=
ST_UNINITIALIZED
;
// Binding
// Binding
private
SocketAddress
localAddress
=
null
;
private
SocketAddress
localAddress
;
private
SocketAddress
remoteAddress
=
null
;
private
SocketAddress
remoteAddress
;
// Input/Output open
// Input/Output open
private
boolean
isInputOpen
=
true
;
private
boolean
isInputOpen
=
true
;
private
boolean
isOutputOpen
=
true
;
private
boolean
isOutputOpen
=
true
;
private
boolean
readyToConnect
=
false
;
private
boolean
readyToConnect
=
false
;
// Options, created on demand
private
SocketOpts
.
IP
.
TCP
options
=
null
;
// Socket adaptor, created on demand
// Socket adaptor, created on demand
private
Socket
socket
=
null
;
private
Socket
socket
;
// -- End of fields protected by stateLock
// -- End of fields protected by stateLock
...
@@ -114,6 +112,7 @@ class SocketChannelImpl
...
@@ -114,6 +112,7 @@ class SocketChannelImpl
this
.
fd
=
fd
;
this
.
fd
=
fd
;
this
.
fdVal
=
IOUtil
.
fdVal
(
fd
);
this
.
fdVal
=
IOUtil
.
fdVal
(
fd
);
this
.
state
=
ST_CONNECTED
;
this
.
state
=
ST_CONNECTED
;
this
.
localAddress
=
Net
.
localAddress
(
fd
);
this
.
remoteAddress
=
remote
;
this
.
remoteAddress
=
remote
;
}
}
...
@@ -125,6 +124,98 @@ class SocketChannelImpl
...
@@ -125,6 +124,98 @@ class SocketChannelImpl
}
}
}
}
@Override
public
SocketAddress
getLocalAddress
()
throws
IOException
{
synchronized
(
stateLock
)
{
if
(!
isOpen
())
return
null
;
return
localAddress
;
}
}
@Override
public
SocketAddress
getConnectedAddress
()
throws
IOException
{
synchronized
(
stateLock
)
{
if
(!
isOpen
())
return
null
;
return
remoteAddress
;
}
}
@Override
public
SocketChannel
setOption
(
SocketOption
name
,
Object
value
)
throws
IOException
{
if
(
name
==
null
)
throw
new
NullPointerException
();
if
(!
options
().
contains
(
name
))
throw
new
IllegalArgumentException
(
"Invalid option name"
);
synchronized
(
stateLock
)
{
if
(!
isOpen
())
throw
new
ClosedChannelException
();
// special handling for IP_TOS: no-op when IPv6
if
(
name
==
StandardSocketOption
.
IP_TOS
)
{
if
(!
Net
.
isIPv6Available
())
Net
.
setSocketOption
(
fd
,
StandardProtocolFamily
.
INET
,
name
,
value
);
return
this
;
}
// no options that require special handling
Net
.
setSocketOption
(
fd
,
Net
.
UNSPEC
,
name
,
value
);
return
this
;
}
}
@Override
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
getOption
(
SocketOption
<
T
>
name
)
throws
IOException
{
if
(
name
==
null
)
throw
new
NullPointerException
();
if
(!
options
().
contains
(
name
))
throw
new
IllegalArgumentException
(
"Invalid option name"
);
synchronized
(
stateLock
)
{
if
(!
isOpen
())
throw
new
ClosedChannelException
();
// special handling for IP_TOS: always return 0 when IPv6
if
(
name
==
StandardSocketOption
.
IP_TOS
)
{
return
(
Net
.
isIPv6Available
())
?
(
T
)
Integer
.
valueOf
(
0
)
:
(
T
)
Net
.
getSocketOption
(
fd
,
StandardProtocolFamily
.
INET
,
name
);
}
// no options that require special handling
return
(
T
)
Net
.
getSocketOption
(
fd
,
Net
.
UNSPEC
,
name
);
}
}
private
static
class
LazyInitialization
{
static
final
Set
<
SocketOption
<?>>
defaultOptions
=
defaultOptions
();
private
static
Set
<
SocketOption
<?>>
defaultOptions
()
{
HashSet
<
SocketOption
<?>>
set
=
new
HashSet
<
SocketOption
<?>>(
8
);
set
.
add
(
StandardSocketOption
.
SO_SNDBUF
);
set
.
add
(
StandardSocketOption
.
SO_RCVBUF
);
set
.
add
(
StandardSocketOption
.
SO_KEEPALIVE
);
set
.
add
(
StandardSocketOption
.
SO_REUSEADDR
);
set
.
add
(
StandardSocketOption
.
SO_LINGER
);
set
.
add
(
StandardSocketOption
.
TCP_NODELAY
);
// additional options required by socket adaptor
set
.
add
(
StandardSocketOption
.
IP_TOS
);
set
.
add
(
ExtendedSocketOption
.
SO_OOBINLINE
);
return
Collections
.
unmodifiableSet
(
set
);
}
}
@Override
public
final
Set
<
SocketOption
<?>>
options
()
{
return
LazyInitialization
.
defaultOptions
;
}
private
boolean
ensureReadOpen
()
throws
ClosedChannelException
{
private
boolean
ensureReadOpen
()
throws
ClosedChannelException
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
if
(!
isOpen
())
if
(!
isOpen
())
...
@@ -410,43 +501,8 @@ class SocketChannelImpl
...
@@ -410,43 +501,8 @@ class SocketChannelImpl
IOUtil
.
configureBlocking
(
fd
,
block
);
IOUtil
.
configureBlocking
(
fd
,
block
);
}
}
public
SocketOpts
options
()
{
synchronized
(
stateLock
)
{
if
(
options
==
null
)
{
SocketOptsImpl
.
Dispatcher
d
=
new
SocketOptsImpl
.
Dispatcher
()
{
int
getInt
(
int
opt
)
throws
IOException
{
return
Net
.
getIntOption
(
fd
,
opt
);
}
void
setInt
(
int
opt
,
int
arg
)
throws
IOException
{
Net
.
setIntOption
(
fd
,
opt
,
arg
);
}
};
options
=
new
SocketOptsImpl
.
IP
.
TCP
(
d
);
}
return
options
;
}
}
public
boolean
isBound
()
{
synchronized
(
stateLock
)
{
if
(
state
==
ST_CONNECTED
)
return
true
;
return
localAddress
!=
null
;
}
}
public
SocketAddress
localAddress
()
{
public
SocketAddress
localAddress
()
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
if
(
state
==
ST_CONNECTED
&&
(
localAddress
==
null
||
((
InetSocketAddress
)
localAddress
).
getAddress
().
isAnyLocalAddress
()))
{
// Socket was not bound before connecting or
// Socket was bound with an "anyLocalAddress"
localAddress
=
Net
.
localAddress
(
fd
);
}
return
localAddress
;
return
localAddress
;
}
}
}
}
...
@@ -457,19 +513,25 @@ class SocketChannelImpl
...
@@ -457,19 +513,25 @@ class SocketChannelImpl
}
}
}
}
public
void
bind
(
SocketAddress
local
)
throws
IOException
{
@Override
public
SocketChannel
bind
(
SocketAddress
local
)
throws
IOException
{
synchronized
(
readLock
)
{
synchronized
(
readLock
)
{
synchronized
(
writeLock
)
{
synchronized
(
writeLock
)
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
ensureOpenAndUnconnected
();
if
(!
isOpen
())
throw
new
ClosedChannelException
();
if
(
state
==
ST_PENDING
)
throw
new
ConnectionPendingException
();
if
(
localAddress
!=
null
)
if
(
localAddress
!=
null
)
throw
new
AlreadyBoundException
();
throw
new
AlreadyBoundException
();
InetSocketAddress
isa
=
Net
.
checkAddress
(
local
);
InetSocketAddress
isa
=
(
local
==
null
)
?
new
InetSocketAddress
(
0
)
:
Net
.
checkAddress
(
local
);
Net
.
bind
(
fd
,
isa
.
getAddress
(),
isa
.
getPort
());
Net
.
bind
(
fd
,
isa
.
getAddress
(),
isa
.
getPort
());
localAddress
=
Net
.
localAddress
(
fd
);
localAddress
=
Net
.
localAddress
(
fd
);
}
}
}
}
}
}
return
this
;
}
}
public
boolean
isConnected
()
{
public
boolean
isConnected
()
{
...
@@ -496,7 +558,6 @@ class SocketChannelImpl
...
@@ -496,7 +558,6 @@ class SocketChannelImpl
}
}
public
boolean
connect
(
SocketAddress
sa
)
throws
IOException
{
public
boolean
connect
(
SocketAddress
sa
)
throws
IOException
{
int
trafficClass
=
0
;
// ## Pick up from options
int
localPort
=
0
;
int
localPort
=
0
;
synchronized
(
readLock
)
{
synchronized
(
readLock
)
{
...
@@ -524,13 +585,24 @@ class SocketChannelImpl
...
@@ -524,13 +585,24 @@ class SocketChannelImpl
ia
=
InetAddress
.
getLocalHost
();
ia
=
InetAddress
.
getLocalHost
();
n
=
Net
.
connect
(
fd
,
n
=
Net
.
connect
(
fd
,
ia
,
ia
,
isa
.
getPort
(),
isa
.
getPort
());
trafficClass
);
if
(
(
n
==
IOStatus
.
INTERRUPTED
)
if
(
(
n
==
IOStatus
.
INTERRUPTED
)
&&
isOpen
())
&&
isOpen
())
continue
;
continue
;
break
;
break
;
}
}
synchronized
(
stateLock
)
{
if
(
isOpen
()
&&
(
localAddress
==
null
)
||
((
InetSocketAddress
)
localAddress
)
.
getAddress
().
isAnyLocalAddress
())
{
// Socket was not bound before connecting or
// Socket was bound with an "anyLocalAddress"
localAddress
=
Net
.
localAddress
(
fd
);
}
}
}
finally
{
}
finally
{
readerCleanup
();
readerCleanup
();
end
((
n
>
0
)
||
(
n
==
IOStatus
.
UNAVAILABLE
));
end
((
n
>
0
)
||
(
n
==
IOStatus
.
UNAVAILABLE
));
...
@@ -646,29 +718,37 @@ class SocketChannelImpl
...
@@ -646,29 +718,37 @@ class SocketChannelImpl
}
}
}
}
public
final
static
int
SHUT_RD
=
0
;
@Override
public
final
static
int
SHUT_WR
=
1
;
public
SocketChannel
shutdownInput
()
throws
IOException
{
public
final
static
int
SHUT_RDWR
=
2
;
public
void
shutdownInput
()
throws
IOException
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
if
(!
isOpen
())
if
(!
isOpen
())
throw
new
ClosedChannelException
();
throw
new
ClosedChannelException
();
isInputOpen
=
false
;
if
(!
isConnected
())
shutdown
(
fd
,
SHUT_RD
);
throw
new
NotYetConnectedException
();
if
(
readerThread
!=
0
)
if
(
isInputOpen
)
{
NativeThread
.
signal
(
readerThread
);
Net
.
shutdown
(
fd
,
Net
.
SHUT_RD
);
if
(
readerThread
!=
0
)
NativeThread
.
signal
(
readerThread
);
isInputOpen
=
false
;
}
return
this
;
}
}
}
}
public
void
shutdownOutput
()
throws
IOException
{
@Override
public
SocketChannel
shutdownOutput
()
throws
IOException
{
synchronized
(
stateLock
)
{
synchronized
(
stateLock
)
{
if
(!
isOpen
())
if
(!
isOpen
())
throw
new
ClosedChannelException
();
throw
new
ClosedChannelException
();
isOutputOpen
=
false
;
if
(!
isConnected
())
shutdown
(
fd
,
SHUT_WR
);
throw
new
NotYetConnectedException
();
if
(
writerThread
!=
0
)
if
(
isOutputOpen
)
{
NativeThread
.
signal
(
writerThread
);
Net
.
shutdown
(
fd
,
Net
.
SHUT_WR
);
if
(
writerThread
!=
0
)
NativeThread
.
signal
(
writerThread
);
isOutputOpen
=
false
;
}
return
this
;
}
}
}
}
...
@@ -869,9 +949,6 @@ class SocketChannelImpl
...
@@ -869,9 +949,6 @@ class SocketChannelImpl
boolean
block
,
boolean
ready
)
boolean
block
,
boolean
ready
)
throws
IOException
;
throws
IOException
;
private
static
native
void
shutdown
(
FileDescriptor
fd
,
int
how
)
throws
IOException
;
static
{
static
{
Util
.
load
();
Util
.
load
();
nd
=
new
SocketDispatcher
();
nd
=
new
SocketDispatcher
();
...
...
src/share/classes/sun/nio/ch/SocketOptsImpl.java
已删除
100644 → 0
浏览文件 @
70763cd4
/*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
sun.nio.ch
;
import
java.io.FileDescriptor
;
import
java.io.IOException
;
import
java.net.NetworkInterface
;
import
java.net.SocketOptions
;
import
java.nio.channels.*
;
class
SocketOptsImpl
implements
SocketOpts
{
static
abstract
class
Dispatcher
{
abstract
int
getInt
(
int
opt
)
throws
IOException
;
abstract
void
setInt
(
int
opt
,
int
arg
)
throws
IOException
;
// Others that pass addresses, etc., will come later
}
private
final
Dispatcher
d
;
SocketOptsImpl
(
Dispatcher
d
)
{
this
.
d
=
d
;
}
protected
boolean
getBoolean
(
int
opt
)
throws
IOException
{
return
d
.
getInt
(
opt
)
>
0
;
}
protected
void
setBoolean
(
int
opt
,
boolean
b
)
throws
IOException
{
d
.
setInt
(
opt
,
b
?
1
:
0
);
}
protected
int
getInt
(
int
opt
)
throws
IOException
{
return
d
.
getInt
(
opt
);
}
protected
void
setInt
(
int
opt
,
int
n
)
throws
IOException
{
d
.
setInt
(
opt
,
n
);
}
protected
NetworkInterface
getNetworkInterface
(
int
opt
)
throws
IOException
{
throw
new
UnsupportedOperationException
(
"NYI"
);
}
protected
void
setNetworkInterface
(
int
opt
,
NetworkInterface
ni
)
throws
IOException
{
throw
new
UnsupportedOperationException
(
"NYI"
);
}
protected
void
addToString
(
StringBuffer
sb
,
String
s
)
{
char
c
=
sb
.
charAt
(
sb
.
length
()
-
1
);
if
((
c
!=
'['
)
&&
(
c
!=
'='
))
sb
.
append
(
' '
);
sb
.
append
(
s
);
}
protected
void
addToString
(
StringBuffer
sb
,
int
n
)
{
addToString
(
sb
,
Integer
.
toString
(
n
));
}
// SO_BROADCAST
public
boolean
broadcast
()
throws
IOException
{
return
getBoolean
(
SocketOptions
.
SO_BROADCAST
);
}
public
SocketOpts
broadcast
(
boolean
b
)
throws
IOException
{
setBoolean
(
SocketOptions
.
SO_BROADCAST
,
b
);
return
this
;
}
// SO_KEEPALIVE
public
boolean
keepAlive
()
throws
IOException
{
return
getBoolean
(
SocketOptions
.
SO_KEEPALIVE
);
}
public
SocketOpts
keepAlive
(
boolean
b
)
throws
IOException
{
setBoolean
(
SocketOptions
.
SO_KEEPALIVE
,
b
);
return
this
;
}
// SO_LINGER
public
int
linger
()
throws
IOException
{
return
getInt
(
SocketOptions
.
SO_LINGER
);
}
public
SocketOpts
linger
(
int
n
)
throws
IOException
{
setInt
(
SocketOptions
.
SO_LINGER
,
n
);
return
this
;
}
// SO_OOBINLINE
public
boolean
outOfBandInline
()
throws
IOException
{
return
getBoolean
(
SocketOptions
.
SO_OOBINLINE
);
}
public
SocketOpts
outOfBandInline
(
boolean
b
)
throws
IOException
{
setBoolean
(
SocketOptions
.
SO_OOBINLINE
,
b
);
return
this
;
}
// SO_RCVBUF
public
int
receiveBufferSize
()
throws
IOException
{
return
getInt
(
SocketOptions
.
SO_RCVBUF
);
}
public
SocketOpts
receiveBufferSize
(
int
n
)
throws
IOException
{
if
(
n
<=
0
)
throw
new
IllegalArgumentException
(
"Invalid receive size"
);
setInt
(
SocketOptions
.
SO_RCVBUF
,
n
);
return
this
;
}
// SO_SNDBUF
public
int
sendBufferSize
()
throws
IOException
{
return
getInt
(
SocketOptions
.
SO_SNDBUF
);
}
public
SocketOpts
sendBufferSize
(
int
n
)
throws
IOException
{
if
(
n
<=
0
)
throw
new
IllegalArgumentException
(
"Invalid send size"
);
setInt
(
SocketOptions
.
SO_SNDBUF
,
n
);
return
this
;
}
// SO_REUSEADDR
public
boolean
reuseAddress
()
throws
IOException
{
return
getBoolean
(
SocketOptions
.
SO_REUSEADDR
);
}
public
SocketOpts
reuseAddress
(
boolean
b
)
throws
IOException
{
setBoolean
(
SocketOptions
.
SO_REUSEADDR
,
b
);
return
this
;
}
// toString
protected
void
toString
(
StringBuffer
sb
)
throws
IOException
{
int
n
;
if
(
broadcast
())
addToString
(
sb
,
"broadcast"
);
if
(
keepAlive
())
addToString
(
sb
,
"keepalive"
);
if
((
n
=
linger
())
>
0
)
{
addToString
(
sb
,
"linger="
);
addToString
(
sb
,
n
);
}
if
(
outOfBandInline
())
addToString
(
sb
,
"oobinline"
);
if
((
n
=
receiveBufferSize
())
>
0
)
{
addToString
(
sb
,
"rcvbuf="
);
addToString
(
sb
,
n
);
}
if
((
n
=
sendBufferSize
())
>
0
)
{
addToString
(
sb
,
"sndbuf="
);
addToString
(
sb
,
n
);
}
if
(
reuseAddress
())
addToString
(
sb
,
"reuseaddr"
);
}
public
String
toString
()
{
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
this
.
getClass
().
getInterfaces
()[
0
].
getName
());
sb
.
append
(
'['
);
int
i
=
sb
.
length
();
try
{
toString
(
sb
);
}
catch
(
IOException
x
)
{
sb
.
setLength
(
i
);
sb
.
append
(
"closed"
);
}
sb
.
append
(
']'
);
return
sb
.
toString
();
}
// IP-specific socket options
static
class
IP
extends
SocketOptsImpl
implements
SocketOpts
.
IP
{
IP
(
Dispatcher
d
)
{
super
(
d
);
}
// IP_MULTICAST_IF2
// ## Do we need IP_MULTICAST_IF also?
public
NetworkInterface
multicastInterface
()
throws
IOException
{
return
getNetworkInterface
(
SocketOptions
.
IP_MULTICAST_IF2
);
}
public
SocketOpts
.
IP
multicastInterface
(
NetworkInterface
ni
)
throws
IOException
{
setNetworkInterface
(
SocketOptions
.
IP_MULTICAST_IF2
,
ni
);
return
this
;
}
// IP_MULTICAST_LOOP
public
boolean
multicastLoop
()
throws
IOException
{
return
getBoolean
(
SocketOptions
.
IP_MULTICAST_LOOP
);
}
public
SocketOpts
.
IP
multicastLoop
(
boolean
b
)
throws
IOException
{
setBoolean
(
SocketOptions
.
IP_MULTICAST_LOOP
,
b
);
return
this
;
}
// IP_TOS
public
int
typeOfService
()
throws
IOException
{
return
getInt
(
SocketOptions
.
IP_TOS
);
}
public
SocketOpts
.
IP
typeOfService
(
int
tos
)
throws
IOException
{
setInt
(
SocketOptions
.
IP_TOS
,
tos
);
return
this
;
}
// toString
protected
void
toString
(
StringBuffer
sb
)
throws
IOException
{
super
.
toString
(
sb
);
int
n
;
if
((
n
=
typeOfService
())
>
0
)
{
addToString
(
sb
,
"tos="
);
addToString
(
sb
,
n
);
}
}
// TCP-specific IP options
public
static
class
TCP
extends
SocketOptsImpl
.
IP
implements
SocketOpts
.
IP
.
TCP
{
TCP
(
Dispatcher
d
)
{
super
(
d
);
}
// TCP_NODELAY
public
boolean
noDelay
()
throws
IOException
{
return
getBoolean
(
SocketOptions
.
TCP_NODELAY
);
}
public
SocketOpts
.
IP
.
TCP
noDelay
(
boolean
b
)
throws
IOException
{
setBoolean
(
SocketOptions
.
TCP_NODELAY
,
b
);
return
this
;
}
// toString
protected
void
toString
(
StringBuffer
sb
)
throws
IOException
{
super
.
toString
(
sb
);
if
(
noDelay
())
addToString
(
sb
,
"nodelay"
);
}
}
}
}
src/share/native/java/net/net_util.c
浏览文件 @
ec347b32
...
@@ -82,7 +82,7 @@ void init(JNIEnv *env) {
...
@@ -82,7 +82,7 @@ void init(JNIEnv *env) {
}
}
}
}
jobject
JNIEXPORT
jobject
JNICALL
NET_SockaddrToInetAddress
(
JNIEnv
*
env
,
struct
sockaddr
*
him
,
int
*
port
)
{
NET_SockaddrToInetAddress
(
JNIEnv
*
env
,
struct
sockaddr
*
him
,
int
*
port
)
{
jobject
iaObj
;
jobject
iaObj
;
init
(
env
);
init
(
env
);
...
@@ -159,7 +159,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
...
@@ -159,7 +159,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
return
iaObj
;
return
iaObj
;
}
}
jint
JNIEXPORT
jint
JNICALL
NET_SockaddrEqualsInetAddress
(
JNIEnv
*
env
,
struct
sockaddr
*
him
,
jobject
iaObj
)
NET_SockaddrEqualsInetAddress
(
JNIEnv
*
env
,
struct
sockaddr
*
him
,
jobject
iaObj
)
{
{
jint
family
=
(
*
env
)
->
GetIntField
(
env
,
iaObj
,
ia_familyID
)
==
IPv4
?
jint
family
=
(
*
env
)
->
GetIntField
(
env
,
iaObj
,
ia_familyID
)
==
IPv4
?
...
...
src/share/native/java/net/net_util.h
浏览文件 @
ec347b32
...
@@ -116,7 +116,7 @@ NET_AllocSockaddr(struct sockaddr **him, int *len);
...
@@ -116,7 +116,7 @@ NET_AllocSockaddr(struct sockaddr **him, int *len);
JNIEXPORT
int
JNICALL
JNIEXPORT
int
JNICALL
NET_InetAddressToSockaddr
(
JNIEnv
*
env
,
jobject
iaObj
,
int
port
,
struct
sockaddr
*
him
,
int
*
len
,
jboolean
v4MappedAddress
);
NET_InetAddressToSockaddr
(
JNIEnv
*
env
,
jobject
iaObj
,
int
port
,
struct
sockaddr
*
him
,
int
*
len
,
jboolean
v4MappedAddress
);
jobject
JNIEXPORT
jobject
JNICALL
NET_SockaddrToInetAddress
(
JNIEnv
*
env
,
struct
sockaddr
*
him
,
int
*
port
);
NET_SockaddrToInetAddress
(
JNIEnv
*
env
,
struct
sockaddr
*
him
,
int
*
port
);
void
initLocalAddrTable
();
void
initLocalAddrTable
();
...
@@ -124,10 +124,10 @@ void initLocalAddrTable ();
...
@@ -124,10 +124,10 @@ void initLocalAddrTable ();
void
void
NET_SetTrafficClass
(
struct
sockaddr
*
him
,
int
trafficClass
);
NET_SetTrafficClass
(
struct
sockaddr
*
him
,
int
trafficClass
);
jint
JNIEXPORT
jint
JNICALL
NET_GetPortFromSockaddr
(
struct
sockaddr
*
him
);
NET_GetPortFromSockaddr
(
struct
sockaddr
*
him
);
jint
JNIEXPORT
jint
JNICALL
NET_SockaddrEqualsInetAddress
(
JNIEnv
*
env
,
struct
sockaddr
*
him
,
jobject
iaObj
);
NET_SockaddrEqualsInetAddress
(
JNIEnv
*
env
,
struct
sockaddr
*
him
,
jobject
iaObj
);
int
int
...
...
src/share/native/sun/nio/ch/genSocketOptionRegistry.c
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#include <stdio.h>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif
/**
* Generates sun.nio.ch.SocketOptionRegistry, a class that maps Java-level
* socket options to the platform specific level and option.
*/
static
void
out
(
char
*
s
)
{
printf
(
"%s
\n
"
,
s
);
}
static
void
emit
(
const
char
*
name
,
char
*
family
,
int
level
,
int
optname
)
{
printf
(
" map.put(new RegistryKey(%s, %s),"
,
name
,
family
);
printf
(
" new OptionKey(%d, %d));
\n
"
,
level
,
optname
);
}
static
void
emit_unspec
(
const
char
*
name
,
int
level
,
int
optname
)
{
emit
(
name
,
"Net.UNSPEC"
,
level
,
optname
);
}
static
void
emit_inet
(
const
char
*
name
,
int
level
,
int
optname
)
{
emit
(
name
,
"StandardProtocolFamily.INET"
,
level
,
optname
);
}
static
void
emit_inet6
(
const
char
*
name
,
int
level
,
int
optname
)
{
emit
(
name
,
"StandardProtocolFamily.INET6"
,
level
,
optname
);
}
int
main
(
int
argc
,
const
char
*
argv
[])
{
out
(
"// AUTOMATICALLY GENERATED FILE - DO NOT EDIT "
);
out
(
"package sun.nio.ch; "
);
out
(
"import java.net.SocketOption; "
);
out
(
"import java.net.StandardSocketOption; "
);
out
(
"import java.net.ProtocolFamily; "
);
out
(
"import java.net.StandardProtocolFamily; "
);
out
(
"import java.util.Map; "
);
out
(
"import java.util.HashMap; "
);
out
(
"class SocketOptionRegistry { "
);
out
(
" private SocketOptionRegistry() { } "
);
out
(
" private static class RegistryKey { "
);
out
(
" private final SocketOption name; "
);
out
(
" private final ProtocolFamily family; "
);
out
(
" RegistryKey(SocketOption name, ProtocolFamily family) { "
);
out
(
" this.name = name; "
);
out
(
" this.family = family; "
);
out
(
" } "
);
out
(
" public int hashCode() { "
);
out
(
" return name.hashCode() + family.hashCode(); "
);
out
(
" } "
);
out
(
" public boolean equals(Object ob) { "
);
out
(
" if (ob == null) return false; "
);
out
(
" if (!(ob instanceof RegistryKey)) return false; "
);
out
(
" RegistryKey other = (RegistryKey)ob; "
);
out
(
" if (this.name != other.name) return false; "
);
out
(
" if (this.family != other.family) return false; "
);
out
(
" return true; "
);
out
(
" } "
);
out
(
" } "
);
out
(
" private static class LazyInitialization { "
);
out
(
" static final Map<RegistryKey,OptionKey> options = options(); "
);
out
(
" private static Map<RegistryKey,OptionKey> options() { "
);
out
(
" Map<RegistryKey,OptionKey> map = "
);
out
(
" new HashMap<RegistryKey,OptionKey>(); "
);
emit_unspec
(
"StandardSocketOption.SO_BROADCAST"
,
SOL_SOCKET
,
SO_BROADCAST
);
emit_unspec
(
"StandardSocketOption.SO_KEEPALIVE"
,
SOL_SOCKET
,
SO_KEEPALIVE
);
emit_unspec
(
"StandardSocketOption.SO_LINGER"
,
SOL_SOCKET
,
SO_LINGER
);
emit_unspec
(
"StandardSocketOption.SO_SNDBUF"
,
SOL_SOCKET
,
SO_SNDBUF
);
emit_unspec
(
"StandardSocketOption.SO_RCVBUF"
,
SOL_SOCKET
,
SO_RCVBUF
);
emit_unspec
(
"StandardSocketOption.SO_REUSEADDR"
,
SOL_SOCKET
,
SO_REUSEADDR
);
emit_unspec
(
"StandardSocketOption.TCP_NODELAY"
,
IPPROTO_TCP
,
TCP_NODELAY
);
emit_inet
(
"StandardSocketOption.IP_TOS"
,
IPPROTO_IP
,
IP_TOS
);
emit_inet
(
"StandardSocketOption.IP_MULTICAST_IF"
,
IPPROTO_IP
,
IP_MULTICAST_IF
);
emit_inet
(
"StandardSocketOption.IP_MULTICAST_TTL"
,
IPPROTO_IP
,
IP_MULTICAST_TTL
);
emit_inet
(
"StandardSocketOption.IP_MULTICAST_LOOP"
,
IPPROTO_IP
,
IP_MULTICAST_LOOP
);
#ifdef AF_INET6
emit_inet6
(
"StandardSocketOption.IP_MULTICAST_IF"
,
IPPROTO_IPV6
,
IPV6_MULTICAST_IF
);
emit_inet6
(
"StandardSocketOption.IP_MULTICAST_TTL"
,
IPPROTO_IPV6
,
IPV6_MULTICAST_HOPS
);
emit_inet6
(
"StandardSocketOption.IP_MULTICAST_LOOP"
,
IPPROTO_IPV6
,
IPV6_MULTICAST_LOOP
);
#endif
emit_unspec
(
"ExtendedSocketOption.SO_OOBINLINE"
,
SOL_SOCKET
,
SO_OOBINLINE
);
out
(
" return map; "
);
out
(
" } "
);
out
(
" } "
);
out
(
" public static OptionKey findOption(SocketOption name, ProtocolFamily family) { "
);
out
(
" RegistryKey key = new RegistryKey(name, family); "
);
out
(
" return LazyInitialization.options.get(key); "
);
out
(
" } "
);
out
(
"} "
);
return
0
;
}
src/share/sample/nio/multicast/MulticastAddress.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import
java.net.InetAddress
;
import
java.net.NetworkInterface
;
import
java.net.UnknownHostException
;
import
java.net.SocketException
;
/**
* Parses and represents a multicast address.
*/
class
MulticastAddress
{
private
final
InetAddress
group
;
private
final
int
port
;
private
final
NetworkInterface
interf
;
private
MulticastAddress
(
InetAddress
group
,
int
port
,
NetworkInterface
interf
)
{
this
.
group
=
group
;
this
.
port
=
port
;
this
.
interf
=
interf
;
}
InetAddress
group
()
{
return
group
;
}
int
port
()
{
return
port
;
}
/**
* @return The network interface, may be {@code null}
*/
NetworkInterface
interf
()
{
return
interf
;
}
/**
* Parses a string of the form "group:port[@interface]", returning
* a MulticastAddress representing the address
*/
static
MulticastAddress
parse
(
String
s
)
{
String
[]
components
=
s
.
split
(
"@"
);
if
(
components
.
length
>
2
)
throw
new
IllegalArgumentException
(
"At most one '@' expected"
);
// get group and port
String
target
=
components
[
0
];
int
len
=
components
[
0
].
length
();
int
colon
=
components
[
0
].
lastIndexOf
(
':'
);
if
((
colon
<
1
)
||
(
colon
>
(
len
-
2
)))
throw
new
IllegalArgumentException
(
"group:port expected"
);
String
groupString
=
target
.
substring
(
0
,
colon
);
int
port
=
-
1
;
try
{
port
=
Integer
.
parseInt
(
target
.
substring
(
colon
+
1
,
len
));
}
catch
(
NumberFormatException
x
)
{
throw
new
IllegalArgumentException
(
x
);
}
// handle IPv6 literal address
if
(
groupString
.
charAt
(
0
)
==
'['
)
{
len
=
groupString
.
length
();
if
(
groupString
.
charAt
(
len
-
1
)
!=
']'
)
throw
new
IllegalArgumentException
(
"missing ']'"
);
groupString
=
groupString
.
substring
(
1
,
len
-
1
);
if
(
groupString
.
length
()
==
0
)
throw
new
IllegalArgumentException
(
"missing IPv6 address"
);
}
// get group address
InetAddress
group
=
null
;
try
{
group
=
InetAddress
.
getByName
(
groupString
);
}
catch
(
UnknownHostException
x
)
{
throw
new
IllegalArgumentException
(
x
);
}
if
(!
group
.
isMulticastAddress
())
{
throw
new
IllegalArgumentException
(
"'"
+
group
.
getHostAddress
()
+
"' is not multicast address"
);
}
// optional interface
NetworkInterface
interf
=
null
;
if
(
components
.
length
==
2
)
{
try
{
interf
=
NetworkInterface
.
getByName
(
components
[
1
]);
}
catch
(
SocketException
x
)
{
throw
new
IllegalArgumentException
(
x
);
}
if
(
interf
==
null
)
{
throw
new
IllegalArgumentException
(
"'"
+
components
[
1
]
+
"' is not valid interface"
);
}
}
return
new
MulticastAddress
(
group
,
port
,
interf
);
}
}
src/share/sample/nio/multicast/Reader.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import
java.nio.channels.*
;
import
java.nio.charset.*
;
import
java.nio.ByteBuffer
;
import
java.net.*
;
import
java.io.IOException
;
import
java.util.*
;
public
class
Reader
{
static
void
usage
()
{
System
.
err
.
println
(
"usage: java Reader group:port@interf [-only source...] [-block source...]"
);
System
.
exit
(-
1
);
}
static
void
printDatagram
(
SocketAddress
sa
,
ByteBuffer
buf
)
{
System
.
out
.
format
(
"-- datagram from %s --\n"
,
((
InetSocketAddress
)
sa
).
getAddress
().
getHostAddress
());
System
.
out
.
println
(
Charset
.
defaultCharset
().
decode
(
buf
));
}
static
void
parseAddessList
(
String
s
,
List
<
InetAddress
>
list
)
throws
UnknownHostException
{
String
[]
sources
=
s
.
split
(
","
);
for
(
int
i
=
0
;
i
<
sources
.
length
;
i
++)
{
list
.
add
(
InetAddress
.
getByName
(
sources
[
i
]));
}
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
if
(
args
.
length
==
0
)
usage
();
// first parameter is the multicast address (interface required)
MulticastAddress
target
=
MulticastAddress
.
parse
(
args
[
0
]);
if
(
target
.
interf
()
==
null
)
usage
();
// addition arguments are source addresses to include or exclude
List
<
InetAddress
>
includeList
=
new
ArrayList
<
InetAddress
>();
List
<
InetAddress
>
excludeList
=
new
ArrayList
<
InetAddress
>();
int
argc
=
1
;
while
(
argc
<
args
.
length
)
{
String
option
=
args
[
argc
++];
if
(
argc
>=
args
.
length
)
usage
();
String
value
=
args
[
argc
++];
if
(
option
.
equals
(
"-only"
))
{
parseAddessList
(
value
,
includeList
);
continue
;
}
if
(
option
.
equals
(
"-block"
))
{
parseAddessList
(
value
,
excludeList
);
continue
;
}
usage
();
}
if
(!
includeList
.
isEmpty
()
&&
!
excludeList
.
isEmpty
())
{
usage
();
}
// create and bind socket
ProtocolFamily
family
=
StandardProtocolFamily
.
INET
;
if
(
target
.
group
()
instanceof
Inet6Address
)
{
family
=
StandardProtocolFamily
.
INET6
;
}
DatagramChannel
dc
=
DatagramChannel
.
open
(
family
)
.
setOption
(
StandardSocketOption
.
SO_REUSEADDR
,
true
)
.
bind
(
new
InetSocketAddress
(
target
.
port
()));
if
(
includeList
.
isEmpty
())
{
// join group and block addresses on the exclude list
MembershipKey
key
=
dc
.
join
(
target
.
group
(),
target
.
interf
());
for
(
InetAddress
source:
excludeList
)
{
key
.
block
(
source
);
}
}
else
{
// join with source-specific membership for each source
for
(
InetAddress
source:
includeList
)
{
dc
.
join
(
target
.
group
(),
target
.
interf
(),
source
);
}
}
// register socket with Selector
Selector
sel
=
Selector
.
open
();
dc
.
configureBlocking
(
false
);
dc
.
register
(
sel
,
SelectionKey
.
OP_READ
);
// print out each datagram that we receive
ByteBuffer
buf
=
ByteBuffer
.
allocateDirect
(
4096
);
for
(;;)
{
int
updated
=
sel
.
select
();
if
(
updated
>
0
)
{
Iterator
<
SelectionKey
>
iter
=
sel
.
selectedKeys
().
iterator
();
while
(
iter
.
hasNext
())
{
SelectionKey
sk
=
iter
.
next
();
iter
.
remove
();
DatagramChannel
ch
=
(
DatagramChannel
)
sk
.
channel
();
SocketAddress
sa
=
ch
.
receive
(
buf
);
if
(
sa
!=
null
)
{
buf
.
flip
();
printDatagram
(
sa
,
buf
);
buf
.
rewind
();
buf
.
limit
(
buf
.
capacity
());
}
}
}
}
}
}
src/share/sample/nio/multicast/Sender.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import
java.nio.channels.*
;
import
java.nio.charset.Charset
;
import
java.net.*
;
import
java.io.IOException
;
import
java.util.*
;
/**
* Sample multicast sender to send a message in a multicast datagram
* to a given group.
*/
public
class
Sender
{
private
static
void
usage
()
{
System
.
err
.
println
(
"usage: java Sender group:port[@interface] message"
);
System
.
exit
(-
1
);
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
if
(
args
.
length
<
2
)
usage
();
MulticastAddress
target
=
MulticastAddress
.
parse
(
args
[
0
]);
// create socket
ProtocolFamily
family
=
StandardProtocolFamily
.
INET
;
if
(
target
.
group
()
instanceof
Inet6Address
)
family
=
StandardProtocolFamily
.
INET6
;
DatagramChannel
dc
=
DatagramChannel
.
open
(
family
).
bind
(
new
InetSocketAddress
(
0
));
if
(
target
.
interf
()
!=
null
)
{
dc
.
setOption
(
StandardSocketOption
.
IP_MULTICAST_IF
,
target
.
interf
());
}
// send multicast packet
dc
.
send
(
Charset
.
defaultCharset
().
encode
(
args
[
1
]),
new
InetSocketAddress
(
target
.
group
(),
target
.
port
()));
dc
.
close
();
}
}
src/solaris/native/java/net/net_util_md.c
浏览文件 @
ec347b32
...
@@ -791,7 +791,7 @@ NET_SetTrafficClass(struct sockaddr *him, int trafficClass) {
...
@@ -791,7 +791,7 @@ NET_SetTrafficClass(struct sockaddr *him, int trafficClass) {
#endif
/* AF_INET6 */
#endif
/* AF_INET6 */
}
}
jint
JNIEXPORT
jint
JNICALL
NET_GetPortFromSockaddr
(
struct
sockaddr
*
him
)
{
NET_GetPortFromSockaddr
(
struct
sockaddr
*
him
)
{
#ifdef AF_INET6
#ifdef AF_INET6
if
(
him
->
sa_family
==
AF_INET6
)
{
if
(
him
->
sa_family
==
AF_INET6
)
{
...
...
src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
浏览文件 @
ec347b32
...
@@ -198,7 +198,7 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
...
@@ -198,7 +198,7 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
JNIEXPORT
jint
JNICALL
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_DatagramChannelImpl_send0
(
JNIEnv
*
env
,
jobject
this
,
Java_sun_nio_ch_DatagramChannelImpl_send0
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
,
jlong
address
,
jboolean
preferIPv6
,
jobject
fdo
,
jlong
address
,
jint
len
,
jobject
dest
)
jint
len
,
jobject
dest
)
{
{
jint
fd
=
fdval
(
env
,
fdo
);
jint
fd
=
fdval
(
env
,
fdo
);
...
@@ -215,7 +215,7 @@ Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
...
@@ -215,7 +215,7 @@ Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
if
(
NET_InetAddressToSockaddr
(
env
,
destAddress
,
destPort
,
if
(
NET_InetAddressToSockaddr
(
env
,
destAddress
,
destPort
,
(
struct
sockaddr
*
)
&
sa
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
JNI_TRUE
)
!=
0
)
{
&
sa_len
,
preferIPv6
)
!=
0
)
{
return
IOS_THROWN
;
return
IOS_THROWN
;
}
}
...
...
src/solaris/native/sun/nio/ch/FileKey.c
浏览文件 @
ec347b32
...
@@ -33,12 +33,6 @@
...
@@ -33,12 +33,6 @@
static
jfieldID
key_st_dev
;
/* id for FileKey.st_dev */
static
jfieldID
key_st_dev
;
/* id for FileKey.st_dev */
static
jfieldID
key_st_ino
;
/* id for FileKey.st_ino */
static
jfieldID
key_st_ino
;
/* id for FileKey.st_ino */
#define RESTARTABLE(_cmd, _result) do { \
do { \
_result = _cmd; \
} while ((_result == -1) && (errno == EINTR)); \
} while(0)
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_FileKey_initIDs
(
JNIEnv
*
env
,
jclass
clazz
)
Java_sun_nio_ch_FileKey_initIDs
(
JNIEnv
*
env
,
jclass
clazz
)
...
...
src/solaris/native/sun/nio/ch/Net.c
浏览文件 @
ec347b32
...
@@ -37,61 +37,171 @@
...
@@ -37,61 +37,171 @@
#include "net_util.h"
#include "net_util.h"
#include "net_util_md.h"
#include "net_util_md.h"
#include "nio_util.h"
#include "nio_util.h"
#include "java_net_SocketOptions.h"
#include "nio.h"
#include "nio.h"
#ifdef __linux__
/**
#include <sys/utsname.h>
* Definitions for source-specific multicast to allow for building
* with older header files.
*/
#ifdef __solaris__
#ifndef IP_BLOCK_SOURCE
#define IP_BLOCK_SOURCE 0x15
#define IP_UNBLOCK_SOURCE 0x16
#define IP_ADD_SOURCE_MEMBERSHIP 0x17
#define IP_DROP_SOURCE_MEMBERSHIP 0x18
#define MCAST_BLOCK_SOURCE 0x2b
#define MCAST_UNBLOCK_SOURCE 0x2c
#define MCAST_JOIN_SOURCE_GROUP 0x2d
#define MCAST_LEAVE_SOURCE_GROUP 0x2e
#define IPV6_MULTICAST_IF 17
#endif
/* IP_BLOCK_SOURCE */
#ifndef SO_BSDCOMPAT
#define SO_BSDCOMPAT 14
struct
my_ip_mreq_source
{
struct
in_addr
imr_multiaddr
;
struct
in_addr
imr_sourceaddr
;
struct
in_addr
imr_interface
;
};
/*
* Use #pragma pack() construct to force 32-bit alignment on amd64.
*/
#if defined(amd64)
#pragma pack(4)
#endif
#endif
struct
my_group_source_req
{
uint32_t
gsr_interface
;
/* interface index */
struct
sockaddr_storage
gsr_group
;
/* group address */
struct
sockaddr_storage
gsr_source
;
/* source address */
};
#if defined(amd64)
#pragma pack()
#endif
#endif
#endif
/* __solaris__ */
#ifdef __linux__
#ifndef IP_BLOCK_SOURCE
#define IP_BLOCK_SOURCE 38
#define IP_UNBLOCK_SOURCE 37
#define IP_ADD_SOURCE_MEMBERSHIP 39
#define IP_DROP_SOURCE_MEMBERSHIP 40
#define MCAST_BLOCK_SOURCE 43
#define MCAST_UNBLOCK_SOURCE 44
#define MCAST_JOIN_SOURCE_GROUP 42
#define MCAST_LEAVE_SOURCE_GROUP 45
#endif
/* IP_BLOCK_SOURCE */
struct
my_ip_mreq_source
{
struct
in_addr
imr_multiaddr
;
struct
in_addr
imr_interface
;
struct
in_addr
imr_sourceaddr
;
};
struct
my_group_source_req
{
uint32_t
gsr_interface
;
/* interface index */
struct
sockaddr_storage
gsr_group
;
/* group address */
struct
sockaddr_storage
gsr_source
;
/* source address */
};
#endif
/* __linux__ */
#define COPY_INET6_ADDRESS(env, source, target) \
(*env)->GetByteArrayRegion(env, source, 0, 16, target)
/*
* Copy IPv6 group, interface index, and IPv6 source address
* into group_source_req structure.
*/
static
void
initGroupSourceReq
(
JNIEnv
*
env
,
jbyteArray
group
,
jint
index
,
jbyteArray
source
,
struct
my_group_source_req
*
req
)
{
struct
sockaddr_in6
*
sin6
;
req
->
gsr_interface
=
(
uint32_t
)
index
;
sin6
=
(
struct
sockaddr_in6
*
)
&
(
req
->
gsr_group
);
sin6
->
sin6_family
=
AF_INET6
;
COPY_INET6_ADDRESS
(
env
,
group
,
(
jbyte
*
)
&
(
sin6
->
sin6_addr
));
sin6
=
(
struct
sockaddr_in6
*
)
&
(
req
->
gsr_source
);
sin6
->
sin6_family
=
AF_INET6
;
COPY_INET6_ADDRESS
(
env
,
source
,
(
jbyte
*
)
&
(
sin6
->
sin6_addr
));
}
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_initIDs
(
JNIEnv
*
env
,
jclass
clazz
)
Java_sun_nio_ch_Net_initIDs
(
JNIEnv
*
env
,
jclass
clazz
)
{
{
/* Here because Windows native code does need to init IDs */
/* Here because Windows native code does need to init IDs */
}
}
JNIEXPORT
jboolean
JNICALL
Java_sun_nio_ch_Net_isIPv6Available0
(
JNIEnv
*
env
,
jclass
cl
)
{
return
(
ipv6_available
())
?
JNI_TRUE
:
JNI_FALSE
;
}
JNIEXPORT
int
JNICALL
JNIEXPORT
int
JNICALL
Java_sun_nio_ch_Net_socket0
(
JNIEnv
*
env
,
jclass
cl
,
jboolean
stream
,
Java_sun_nio_ch_Net_socket0
(
JNIEnv
*
env
,
jclass
cl
,
jboolean
preferIPv6
,
jboolean
reuse
)
jboolean
stream
,
jboolean
reuse
)
{
{
int
fd
;
int
fd
;
int
type
=
(
stream
?
SOCK_STREAM
:
SOCK_DGRAM
);
int
domain
=
(
ipv6_available
()
&&
preferIPv6
)
?
AF_INET6
:
AF_INET
;
#ifdef AF_INET6
fd
=
socket
(
domain
,
type
,
0
);
if
(
ipv6_available
())
fd
=
socket
(
AF_INET6
,
(
stream
?
SOCK_STREAM
:
SOCK_DGRAM
),
0
);
else
#endif
/* AF_INET6 */
fd
=
socket
(
AF_INET
,
(
stream
?
SOCK_STREAM
:
SOCK_DGRAM
),
0
);
if
(
fd
<
0
)
{
if
(
fd
<
0
)
{
return
handleSocketError
(
env
,
errno
);
return
handleSocketError
(
env
,
errno
);
}
}
if
(
reuse
)
{
if
(
reuse
)
{
int
arg
=
1
;
int
arg
=
1
;
if
(
NET_SetSockOpt
(
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
char
*
)
&
arg
,
if
(
setsockopt
(
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
char
*
)
&
arg
,
sizeof
(
arg
))
<
0
)
{
sizeof
(
arg
))
<
0
)
{
JNU_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"SocketException"
,
"sun.nio.ch.Net.setIntOption"
);
close
(
fd
);
return
-
1
;
}
}
#ifdef __linux__
/* By default, Linux uses the route default */
if
(
domain
==
AF_INET6
&&
type
==
SOCK_DGRAM
)
{
int
arg
=
1
;
if
(
setsockopt
(
fd
,
IPPROTO_IPV6
,
IPV6_MULTICAST_HOPS
,
&
arg
,
sizeof
(
arg
))
<
0
)
{
JNU_ThrowByNameWithLastError
(
env
,
JNU_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"SocketException"
,
JNU_JAVANETPKG
"SocketException"
,
"sun.nio.ch.Net.setIntOption"
);
"sun.nio.ch.Net.setIntOption"
);
close
(
fd
);
return
-
1
;
}
}
}
}
#endif
return
fd
;
return
fd
;
}
}
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_bind
(
JNIEnv
*
env
,
jclass
clazz
,
/* ## Needs rest of PSI gunk */
Java_sun_nio_ch_Net_bind
0
(
JNIEnv
*
env
,
jclass
clazz
,
jboolean
preferIPv6
,
jobject
fdo
,
jobject
ia
,
int
port
)
jobject
fdo
,
jobject
iao
,
int
port
)
{
{
SOCKADDR
sa
;
SOCKADDR
sa
;
int
sa_len
=
SOCKADDR_LEN
;
int
sa_len
=
SOCKADDR_LEN
;
int
rv
=
0
;
int
rv
=
0
;
if
(
NET_InetAddressToSockaddr
(
env
,
ia
,
port
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
JNI_TRUE
)
!=
0
)
{
if
(
NET_InetAddressToSockaddr
(
env
,
ia
o
,
port
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
preferIPv6
)
!=
0
)
{
return
;
return
;
}
}
...
@@ -101,27 +211,27 @@ Java_sun_nio_ch_Net_bind(JNIEnv *env, jclass clazz, /* ## Needs rest of PSI gunk
...
@@ -101,27 +211,27 @@ Java_sun_nio_ch_Net_bind(JNIEnv *env, jclass clazz, /* ## Needs rest of PSI gunk
}
}
}
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_listen
(
JNIEnv
*
env
,
jclass
cl
,
jobject
fdo
,
jint
backlog
)
{
if
(
listen
(
fdval
(
env
,
fdo
),
backlog
)
<
0
)
handleSocketError
(
env
,
errno
);
}
JNIEXPORT
jint
JNICALL
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_connect
(
JNIEnv
*
env
,
jclass
clazz
,
Java_sun_nio_ch_Net_connect0
(
JNIEnv
*
env
,
jclass
clazz
,
jboolean
preferIPv6
,
jobject
fdo
,
jobject
iao
,
jint
port
,
jobject
fdo
,
jobject
iao
,
jint
port
)
jint
trafficClass
)
{
{
SOCKADDR
sa
;
SOCKADDR
sa
;
int
sa_len
=
SOCKADDR_LEN
;
int
sa_len
=
SOCKADDR_LEN
;
int
rv
;
int
rv
;
if
(
NET_InetAddressToSockaddr
(
env
,
iao
,
port
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
JNI_TRUE
)
!=
0
)
{
if
(
NET_InetAddressToSockaddr
(
env
,
iao
,
port
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
preferIPv6
)
!=
0
)
{
return
IOS_THROWN
;
return
IOS_THROWN
;
}
}
#ifdef AF_INET6
#if 0
if (trafficClass != 0 && ipv6_available()) { /* ## FIX */
NET_SetTrafficClass((struct sockaddr *)&sa, trafficClass);
}
#endif
#endif
rv
=
connect
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
sa_len
);
rv
=
connect
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
sa_len
);
if
(
rv
!=
0
)
{
if
(
rv
!=
0
)
{
if
(
errno
==
EINPROGRESS
)
{
if
(
errno
==
EINPROGRESS
)
{
...
@@ -159,119 +269,79 @@ Java_sun_nio_ch_Net_localInetAddress(JNIEnv *env, jclass clazz, jobject fdo)
...
@@ -159,119 +269,79 @@ Java_sun_nio_ch_Net_localInetAddress(JNIEnv *env, jclass clazz, jobject fdo)
return
NET_SockaddrToInetAddress
(
env
,
(
struct
sockaddr
*
)
&
sa
,
&
port
);
return
NET_SockaddrToInetAddress
(
env
,
(
struct
sockaddr
*
)
&
sa
,
&
port
);
}
}
#ifdef NEEDED
/* ## This is gross. We should generate platform-specific constant
* ## definitions into a .java file and use those directly.
*/
static
int
mapOption
(
JNIEnv
*
env
,
int
opt
,
int
*
klevel
,
int
*
kopt
)
{
switch
(
opt
)
{
case
java_net_SocketOptions_IP_TOS
:
*
klevel
=
IPPROTO_IP
;
*
kopt
=
IP_TOS
;
break
;
case
java_net_SocketOptions_SO_BROADCAST
:
case
java_net_SocketOptions_SO_KEEPALIVE
:
case
java_net_SocketOptions_SO_LINGER
:
case
java_net_SocketOptions_SO_OOBINLINE
:
case
java_net_SocketOptions_SO_RCVBUF
:
case
java_net_SocketOptions_SO_REUSEADDR
:
case
java_net_SocketOptions_SO_SNDBUF
:
*
klevel
=
SOL_SOCKET
;
break
;
case
java_net_SocketOptions_TCP_NODELAY
:
*
klevel
=
IPPROTO_IP
;
*
kopt
=
TCP_NODELAY
;
return
0
;
default:
JNU_ThrowByName
(
env
,
"java/lang/IllegalArgumentException"
,
NULL
);
return
-
1
;
}
switch
(
opt
)
{
case
java_net_SocketOptions_SO_BROADCAST
:
*
kopt
=
SO_BROADCAST
;
break
;
case
java_net_SocketOptions_SO_KEEPALIVE
:
*
kopt
=
SO_KEEPALIVE
;
break
;
case
java_net_SocketOptions_SO_LINGER
:
*
kopt
=
SO_LINGER
;
break
;
case
java_net_SocketOptions_SO_OOBINLINE
:
*
kopt
=
SO_OOBINLINE
;
break
;
case
java_net_SocketOptions_SO_RCVBUF
:
*
kopt
=
SO_RCVBUF
;
break
;
case
java_net_SocketOptions_SO_REUSEADDR
:
*
kopt
=
SO_REUSEADDR
;
break
;
case
java_net_SocketOptions_SO_SNDBUF
:
*
kopt
=
SO_SNDBUF
;
break
;
default:
return
-
1
;
}
return
0
;
}
#endif
JNIEXPORT
jint
JNICALL
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_getIntOption0
(
JNIEnv
*
env
,
jclass
clazz
,
Java_sun_nio_ch_Net_getIntOption0
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
,
j
object
fdo
,
jint
opt
)
j
boolean
mayNeedConversion
,
jint
level
,
jint
opt
)
{
{
int
klevel
,
kopt
;
int
result
;
int
result
;
struct
linger
linger
;
struct
linger
linger
;
u_char
carg
;
void
*
arg
;
void
*
arg
;
int
arglen
;
int
arglen
,
n
;
if
(
NET_MapSocketOption
(
opt
,
&
klevel
,
&
kopt
)
<
0
)
{
/* Option value is an int except for a few specific cases */
JNU_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"SocketException"
,
arg
=
(
void
*
)
&
result
;
"Unsupported socket option"
);
arglen
=
sizeof
(
result
);
return
-
1
;
if
(
level
==
IPPROTO_IP
&&
(
opt
==
IP_MULTICAST_TTL
||
opt
==
IP_MULTICAST_LOOP
))
{
arg
=
(
void
*
)
&
carg
;
arglen
=
sizeof
(
carg
);
}
}
if
(
opt
==
java_net_SocketOptions_
SO_LINGER
)
{
if
(
level
==
SOL_SOCKET
&&
opt
==
SO_LINGER
)
{
arg
=
(
void
*
)
&
linger
;
arg
=
(
void
*
)
&
linger
;
arglen
=
sizeof
(
linger
);
arglen
=
sizeof
(
linger
);
}
else
{
arg
=
(
void
*
)
&
result
;
arglen
=
sizeof
(
result
);
}
}
if
(
NET_GetSockOpt
(
fdval
(
env
,
fdo
),
klevel
,
kopt
,
arg
,
&
arglen
)
<
0
)
{
if
(
mayNeedConversion
)
{
n
=
NET_GetSockOpt
(
fdval
(
env
,
fdo
),
level
,
opt
,
arg
,
&
arglen
);
}
else
{
n
=
getsockopt
(
fdval
(
env
,
fdo
),
level
,
opt
,
arg
,
&
arglen
);
}
if
(
n
<
0
)
{
JNU_ThrowByNameWithLastError
(
env
,
JNU_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"SocketException"
,
JNU_JAVANETPKG
"SocketException"
,
"sun.nio.ch.Net.getIntOption"
);
"sun.nio.ch.Net.getIntOption"
);
return
-
1
;
return
-
1
;
}
}
if
(
opt
==
java_net_SocketOptions_SO_LINGER
)
if
(
level
==
IPPROTO_IP
&&
return
linger
.
l_onoff
?
linger
.
l_linger
:
-
1
;
(
opt
==
IP_MULTICAST_TTL
||
opt
==
IP_MULTICAST_LOOP
))
else
{
return
result
;
return
(
jint
)
carg
;
}
if
(
level
==
SOL_SOCKET
&&
opt
==
SO_LINGER
)
return
linger
.
l_onoff
?
(
jint
)
linger
.
l_linger
:
(
jint
)
-
1
;
return
(
jint
)
result
;
}
}
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_setIntOption0
(
JNIEnv
*
env
,
jclass
clazz
,
Java_sun_nio_ch_Net_setIntOption0
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
,
j
object
fdo
,
jint
opt
,
jint
arg
)
j
boolean
mayNeedConversion
,
jint
level
,
jint
opt
,
jint
arg
)
{
{
int
klevel
,
kopt
;
int
result
;
int
result
;
struct
linger
linger
;
struct
linger
linger
;
u_char
carg
;
void
*
parg
;
void
*
parg
;
int
arglen
;
int
arglen
,
n
;
if
(
NET_MapSocketOption
(
opt
,
&
klevel
,
&
kopt
)
<
0
)
{
/* Option value is an int except for a few specific cases */
JNU_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"SocketException"
,
parg
=
(
void
*
)
&
arg
;
"Unsupported socket option"
);
arglen
=
sizeof
(
arg
);
return
;
if
(
level
==
IPPROTO_IP
&&
(
opt
==
IP_MULTICAST_TTL
||
opt
==
IP_MULTICAST_LOOP
))
{
parg
=
(
void
*
)
&
carg
;
arglen
=
sizeof
(
carg
);
carg
=
(
u_char
)
arg
;
}
}
if
(
opt
==
java_net_SocketOptions_
SO_LINGER
)
{
if
(
level
==
SOL_SOCKET
&&
opt
==
SO_LINGER
)
{
parg
=
(
void
*
)
&
linger
;
parg
=
(
void
*
)
&
linger
;
arglen
=
sizeof
(
linger
);
arglen
=
sizeof
(
linger
);
if
(
arg
>=
0
)
{
if
(
arg
>=
0
)
{
...
@@ -281,19 +351,199 @@ Java_sun_nio_ch_Net_setIntOption0(JNIEnv *env, jclass clazz,
...
@@ -281,19 +351,199 @@ Java_sun_nio_ch_Net_setIntOption0(JNIEnv *env, jclass clazz,
linger
.
l_onoff
=
0
;
linger
.
l_onoff
=
0
;
linger
.
l_linger
=
0
;
linger
.
l_linger
=
0
;
}
}
}
else
{
parg
=
(
void
*
)
&
arg
;
arglen
=
sizeof
(
arg
);
}
}
if
(
NET_SetSockOpt
(
fdval
(
env
,
fdo
),
klevel
,
kopt
,
parg
,
arglen
)
<
0
)
{
if
(
mayNeedConversion
)
{
n
=
NET_SetSockOpt
(
fdval
(
env
,
fdo
),
level
,
opt
,
parg
,
arglen
);
}
else
{
n
=
setsockopt
(
fdval
(
env
,
fdo
),
level
,
opt
,
parg
,
arglen
);
}
if
(
n
<
0
)
{
JNU_ThrowByNameWithLastError
(
env
,
JNU_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"SocketException"
,
JNU_JAVANETPKG
"SocketException"
,
"sun.nio.ch.Net.setIntOption"
);
"sun.nio.ch.Net.setIntOption"
);
}
}
}
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_joinOrDrop4
(
JNIEnv
*
env
,
jobject
this
,
jboolean
join
,
jobject
fdo
,
jint
group
,
jint
interf
,
jint
source
)
{
struct
ip_mreq
mreq
;
struct
my_ip_mreq_source
mreq_source
;
int
opt
,
n
,
optlen
;
void
*
optval
;
if
(
source
==
0
)
{
mreq
.
imr_multiaddr
.
s_addr
=
htonl
(
group
);
mreq
.
imr_interface
.
s_addr
=
htonl
(
interf
);
opt
=
(
join
)
?
IP_ADD_MEMBERSHIP
:
IP_DROP_MEMBERSHIP
;
optval
=
(
void
*
)
&
mreq
;
optlen
=
sizeof
(
mreq
);
}
else
{
mreq_source
.
imr_multiaddr
.
s_addr
=
htonl
(
group
);
mreq_source
.
imr_sourceaddr
.
s_addr
=
htonl
(
source
);
mreq_source
.
imr_interface
.
s_addr
=
htonl
(
interf
);
opt
=
(
join
)
?
IP_ADD_SOURCE_MEMBERSHIP
:
IP_DROP_SOURCE_MEMBERSHIP
;
optval
=
(
void
*
)
&
mreq_source
;
optlen
=
sizeof
(
mreq_source
);
}
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IP
,
opt
,
optval
,
optlen
);
if
(
n
<
0
)
{
if
(
join
&&
(
errno
==
ENOPROTOOPT
))
return
IOS_UNAVAILABLE
;
handleSocketError
(
env
,
errno
);
}
return
0
;
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_blockOrUnblock4
(
JNIEnv
*
env
,
jobject
this
,
jboolean
block
,
jobject
fdo
,
jint
group
,
jint
interf
,
jint
source
)
{
struct
my_ip_mreq_source
mreq_source
;
int
n
;
int
opt
=
(
block
)
?
IP_BLOCK_SOURCE
:
IP_UNBLOCK_SOURCE
;
mreq_source
.
imr_multiaddr
.
s_addr
=
htonl
(
group
);
mreq_source
.
imr_sourceaddr
.
s_addr
=
htonl
(
source
);
mreq_source
.
imr_interface
.
s_addr
=
htonl
(
interf
);
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IP
,
opt
,
(
void
*
)
&
mreq_source
,
sizeof
(
mreq_source
));
if
(
n
<
0
)
{
if
(
block
&&
(
errno
==
ENOPROTOOPT
))
return
IOS_UNAVAILABLE
;
handleSocketError
(
env
,
errno
);
}
return
0
;
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_joinOrDrop6
(
JNIEnv
*
env
,
jobject
this
,
jboolean
join
,
jobject
fdo
,
jbyteArray
group
,
jint
index
,
jbyteArray
source
)
{
struct
ipv6_mreq
mreq6
;
struct
my_group_source_req
req
;
int
opt
,
n
,
optlen
;
void
*
optval
;
if
(
source
==
NULL
)
{
COPY_INET6_ADDRESS
(
env
,
group
,
(
jbyte
*
)
&
(
mreq6
.
ipv6mr_multiaddr
));
mreq6
.
ipv6mr_interface
=
(
int
)
index
;
opt
=
(
join
)
?
IPV6_ADD_MEMBERSHIP
:
IPV6_DROP_MEMBERSHIP
;
optval
=
(
void
*
)
&
mreq6
;
optlen
=
sizeof
(
mreq6
);
}
else
{
#ifdef __linux__
/* Include-mode filtering broken on Linux at least to 2.6.24 */
return
IOS_UNAVAILABLE
;
#else
initGroupSourceReq
(
env
,
group
,
index
,
source
,
&
req
);
opt
=
(
join
)
?
MCAST_JOIN_SOURCE_GROUP
:
MCAST_LEAVE_SOURCE_GROUP
;
optval
=
(
void
*
)
&
req
;
optlen
=
sizeof
(
req
);
#endif
}
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IPV6
,
opt
,
optval
,
optlen
);
if
(
n
<
0
)
{
if
(
join
&&
(
errno
==
ENOPROTOOPT
))
return
IOS_UNAVAILABLE
;
handleSocketError
(
env
,
errno
);
}
return
0
;
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_blockOrUnblock6
(
JNIEnv
*
env
,
jobject
this
,
jboolean
block
,
jobject
fdo
,
jbyteArray
group
,
jint
index
,
jbyteArray
source
)
{
struct
my_group_source_req
req
;
int
n
;
int
opt
=
(
block
)
?
MCAST_BLOCK_SOURCE
:
MCAST_UNBLOCK_SOURCE
;
initGroupSourceReq
(
env
,
group
,
index
,
source
,
&
req
);
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IPV6
,
opt
,
(
void
*
)
&
req
,
sizeof
(
req
));
if
(
n
<
0
)
{
if
(
block
&&
(
errno
==
ENOPROTOOPT
))
return
IOS_UNAVAILABLE
;
handleSocketError
(
env
,
errno
);
}
return
0
;
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_setInterface4
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
,
jint
interf
)
{
struct
in_addr
in
;
int
arglen
=
sizeof
(
struct
in_addr
);
int
n
;
in
.
s_addr
=
htonl
(
interf
);
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IP
,
IP_MULTICAST_IF
,
(
void
*
)
&
(
in
.
s_addr
),
arglen
);
if
(
n
<
0
)
{
handleSocketError
(
env
,
errno
);
}
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_getInterface4
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
)
{
struct
in_addr
in
;
int
arglen
=
sizeof
(
struct
in_addr
);
int
n
;
n
=
getsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IP
,
IP_MULTICAST_IF
,
(
void
*
)
&
in
,
&
arglen
);
if
(
n
<
0
)
{
handleSocketError
(
env
,
errno
);
return
-
1
;
}
return
ntohl
(
in
.
s_addr
);
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_setInterface6
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
,
jint
index
)
{
int
value
=
(
jint
)
index
;
int
arglen
=
sizeof
(
value
);
int
n
;
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IPV6
,
IPV6_MULTICAST_IF
,
(
void
*
)
&
(
index
),
arglen
);
if
(
n
<
0
)
{
handleSocketError
(
env
,
errno
);
}
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_getInterface6
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
)
{
int
index
;
int
arglen
=
sizeof
(
index
);
int
n
;
n
=
getsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IPV6
,
IPV6_MULTICAST_IF
,
(
void
*
)
&
index
,
&
arglen
);
if
(
n
<
0
)
{
handleSocketError
(
env
,
errno
);
return
-
1
;
}
return
(
jint
)
index
;
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_shutdown
(
JNIEnv
*
env
,
jclass
cl
,
jobject
fdo
,
jint
jhow
)
{
int
how
=
(
jhow
==
sun_nio_ch_Net_SHUT_RD
)
?
SHUT_RD
:
(
jhow
==
sun_nio_ch_Net_SHUT_WR
)
?
SHUT_WR
:
SHUT_RDWR
;
if
(
shutdown
(
fdval
(
env
,
fdo
),
how
)
<
0
)
handleSocketError
(
env
,
errno
);
}
/* Declared in nio_util.h */
/* Declared in nio_util.h */
...
...
src/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c
浏览文件 @
ec347b32
...
@@ -65,14 +65,6 @@ Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv *env, jclass c)
...
@@ -65,14 +65,6 @@ Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv *env, jclass c)
"(Ljava/net/InetAddress;I)V"
);
"(Ljava/net/InetAddress;I)V"
);
}
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_ServerSocketChannelImpl_listen
(
JNIEnv
*
env
,
jclass
cl
,
jobject
fdo
,
jint
backlog
)
{
if
(
listen
(
fdval
(
env
,
fdo
),
backlog
)
<
0
)
handleSocketError
(
env
,
errno
);
}
JNIEXPORT
jint
JNICALL
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_ServerSocketChannelImpl_accept0
(
JNIEnv
*
env
,
jobject
this
,
Java_sun_nio_ch_ServerSocketChannelImpl_accept0
(
JNIEnv
*
env
,
jobject
this
,
jobject
ssfdo
,
jobject
newfdo
,
jobject
ssfdo
,
jobject
newfdo
,
...
...
src/solaris/native/sun/nio/ch/SocketChannelImpl.c
浏览文件 @
ec347b32
...
@@ -35,10 +35,6 @@
...
@@ -35,10 +35,6 @@
#include <netinet/in.h>
#include <netinet/in.h>
#endif
#endif
#if defined(__solaris__) && !defined(_SOCKLEN_T)
typedef
size_t
socklen_t
;
/* New in SunOS 5.7, so need this for 5.6 */
#endif
#include "jni.h"
#include "jni.h"
#include "jni_util.h"
#include "jni_util.h"
#include "net_util.h"
#include "net_util.h"
...
@@ -88,12 +84,3 @@ Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this,
...
@@ -88,12 +84,3 @@ Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this,
}
}
return
0
;
return
0
;
}
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_SocketChannelImpl_shutdown
(
JNIEnv
*
env
,
jclass
cl
,
jobject
fdo
,
jint
how
)
{
if
(
shutdown
(
fdval
(
env
,
fdo
),
how
)
<
0
)
handleSocketError
(
env
,
errno
);
}
src/solaris/native/sun/nio/ch/nio_util.h
浏览文件 @
ec347b32
...
@@ -27,8 +27,15 @@
...
@@ -27,8 +27,15 @@
#include "jni_util.h"
#include "jni_util.h"
#include "jvm.h"
#include "jvm.h"
#include "jlong.h"
#include "jlong.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/types.h>
#define RESTARTABLE(_cmd, _result) do { \
do { \
_result = _cmd; \
} while((_result == -1) && (errno == EINTR)); \
} while(0)
/* NIO utility procedures */
/* NIO utility procedures */
...
...
src/windows/native/java/net/net_util_md.c
浏览文件 @
ec347b32
...
@@ -889,7 +889,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr
...
@@ -889,7 +889,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr
return
0
;
return
0
;
}
}
jint
JNIEXPORT
jint
JNICALL
NET_GetPortFromSockaddr
(
struct
sockaddr
*
him
)
{
NET_GetPortFromSockaddr
(
struct
sockaddr
*
him
)
{
if
(
him
->
sa_family
==
AF_INET6
)
{
if
(
him
->
sa_family
==
AF_INET6
)
{
return
ntohs
(((
struct
sockaddr_in6
*
)
him
)
->
sin6_port
);
return
ntohs
(((
struct
sockaddr_in6
*
)
him
)
->
sin6_port
);
...
...
src/windows/native/sun/nio/ch/DatagramChannelImpl.c
浏览文件 @
ec347b32
...
@@ -39,46 +39,9 @@ static jfieldID isa_portID; /* port in java.net.InetSocketAddress */
...
@@ -39,46 +39,9 @@ static jfieldID isa_portID; /* port in java.net.InetSocketAddress */
static
jfieldID
dci_senderID
;
/* sender in sun.nio.ch.DatagramChannelImpl */
static
jfieldID
dci_senderID
;
/* sender in sun.nio.ch.DatagramChannelImpl */
static
jfieldID
dci_senderAddrID
;
/* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
static
jfieldID
dci_senderAddrID
;
/* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
static
jfieldID
dci_senderPortID
;
/* sender port in sun.nio.ch.DatagramChannelImpl */
static
jfieldID
dci_senderPortID
;
/* sender port in sun.nio.ch.DatagramChannelImpl */
static
jfieldID
ia_addrID
;
static
jfieldID
ia_famID
;
static
jclass
isa_class
;
/* java.net.InetSocketAddress */
static
jclass
isa_class
;
/* java.net.InetSocketAddress */
static
jclass
ia_class
;
static
jmethodID
isa_ctorID
;
/* java.net.InetSocketAddress(InetAddress, int) */
static
jmethodID
isa_ctorID
;
/* .InetSocketAddress(InetAddress, int) */
static
jmethodID
ia_ctorID
;
/*
* Returns JNI_TRUE if DatagramChannelImpl has already cached an
* InetAddress/port corresponding to the socket address.
*/
static
jboolean
isSenderCached
(
JNIEnv
*
env
,
jobject
this
,
struct
sockaddr_in
*
sa
)
{
jobject
senderAddr
;
/* shouldn't happen until we have dual IPv4/IPv6 stack (post-XP ?) */
if
(
sa
->
sin_family
!=
AF_INET
)
{
return
JNI_FALSE
;
}
/*
* Compare source address to cached InetAddress
*/
senderAddr
=
(
*
env
)
->
GetObjectField
(
env
,
this
,
dci_senderAddrID
);
if
(
senderAddr
==
NULL
)
{
return
JNI_FALSE
;
}
if
((
jint
)
ntohl
(
sa
->
sin_addr
.
s_addr
)
!=
(
*
env
)
->
GetIntField
(
env
,
senderAddr
,
ia_addrID
))
{
return
JNI_FALSE
;
}
/*
* Compare source port to cached port
*/
if
((
jint
)
ntohs
(
sa
->
sin_port
)
!=
(
*
env
)
->
GetIntField
(
env
,
this
,
dci_senderPortID
))
{
return
JNI_FALSE
;
}
return
JNI_TRUE
;
}
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_DatagramChannelImpl_initIDs
(
JNIEnv
*
env
,
jclass
clazz
)
Java_sun_nio_ch_DatagramChannelImpl_initIDs
(
JNIEnv
*
env
,
jclass
clazz
)
...
@@ -99,32 +62,6 @@ Java_sun_nio_ch_DatagramChannelImpl_initIDs(JNIEnv *env, jclass clazz)
...
@@ -99,32 +62,6 @@ Java_sun_nio_ch_DatagramChannelImpl_initIDs(JNIEnv *env, jclass clazz)
"Ljava/net/InetAddress;"
);
"Ljava/net/InetAddress;"
);
dci_senderPortID
=
(
*
env
)
->
GetFieldID
(
env
,
clazz
,
dci_senderPortID
=
(
*
env
)
->
GetFieldID
(
env
,
clazz
,
"cachedSenderPort"
,
"I"
);
"cachedSenderPort"
,
"I"
);
clazz
=
(
*
env
)
->
FindClass
(
env
,
"java/net/Inet4Address"
);
ia_class
=
(
*
env
)
->
NewGlobalRef
(
env
,
clazz
);
ia_addrID
=
(
*
env
)
->
GetFieldID
(
env
,
clazz
,
"address"
,
"I"
);
ia_famID
=
(
*
env
)
->
GetFieldID
(
env
,
clazz
,
"family"
,
"I"
);
ia_ctorID
=
(
*
env
)
->
GetMethodID
(
env
,
clazz
,
"<init>"
,
"()V"
);
}
/*
* Return JNI_TRUE if this Windows edition supports ICMP Port Unreachable
*/
__inline
static
jboolean
supportPortUnreachable
()
{
static
jboolean
initDone
;
static
jboolean
portUnreachableSupported
;
if
(
!
initDone
)
{
OSVERSIONINFO
ver
;
ver
.
dwOSVersionInfoSize
=
sizeof
(
ver
);
GetVersionEx
(
&
ver
);
if
(
ver
.
dwPlatformId
==
VER_PLATFORM_WIN32_NT
&&
ver
.
dwMajorVersion
>=
5
)
{
portUnreachableSupported
=
JNI_TRUE
;
}
else
{
portUnreachableSupported
=
JNI_FALSE
;
}
initDone
=
JNI_TRUE
;
}
return
portUnreachableSupported
;
}
}
/*
/*
...
@@ -140,15 +77,8 @@ jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd)
...
@@ -140,15 +77,8 @@ jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd)
char
buf
[
1
];
char
buf
[
1
];
fd_set
tbl
;
fd_set
tbl
;
struct
timeval
t
=
{
0
,
0
};
struct
timeval
t
=
{
0
,
0
};
struct
sockaddr_in
rmtaddr
;
SOCKETADDRESS
sa
;
int
addrlen
=
sizeof
(
rmtaddr
);
int
addrlen
=
sizeof
(
sa
);
/*
* A no-op if this OS doesn't support it.
*/
if
(
!
supportPortUnreachable
())
{
return
JNI_FALSE
;
}
/*
/*
* Peek at the queue to see if there is an ICMP port unreachable. If there
* Peek at the queue to see if there is an ICMP port unreachable. If there
...
@@ -161,7 +91,7 @@ jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd)
...
@@ -161,7 +91,7 @@ jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd)
break
;
break
;
}
}
if
(
recvfrom
(
fd
,
buf
,
1
,
MSG_PEEK
,
if
(
recvfrom
(
fd
,
buf
,
1
,
MSG_PEEK
,
(
struct
sockaddr
*
)
&
rmtaddr
,
&
addrlen
)
!=
SOCKET_ERROR
)
{
(
struct
sockaddr
*
)
&
sa
,
&
addrlen
)
!=
SOCKET_ERROR
)
{
break
;
break
;
}
}
if
(
WSAGetLastError
()
!=
WSAECONNRESET
)
{
if
(
WSAGetLastError
()
!=
WSAECONNRESET
)
{
...
@@ -169,7 +99,7 @@ jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd)
...
@@ -169,7 +99,7 @@ jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd)
break
;
break
;
}
}
recvfrom
(
fd
,
buf
,
1
,
0
,
(
struct
sockaddr
*
)
&
rmtaddr
,
&
addrlen
);
recvfrom
(
fd
,
buf
,
1
,
0
,
(
struct
sockaddr
*
)
&
sa
,
&
addrlen
);
got_icmp
=
JNI_TRUE
;
got_icmp
=
JNI_TRUE
;
}
}
...
@@ -182,12 +112,12 @@ Java_sun_nio_ch_DatagramChannelImpl_disconnect0(JNIEnv *env, jobject this,
...
@@ -182,12 +112,12 @@ Java_sun_nio_ch_DatagramChannelImpl_disconnect0(JNIEnv *env, jobject this,
{
{
jint
fd
=
fdval
(
env
,
fdo
);
jint
fd
=
fdval
(
env
,
fdo
);
int
rv
=
0
;
int
rv
=
0
;
struct
sockaddr_in
p
sa
;
SOCKETADDRESS
sa
;
int
sa_len
=
sizeof
(
p
sa
);
int
sa_len
=
sizeof
(
sa
);
memset
(
&
p
sa
,
0
,
sa_len
);
memset
(
&
sa
,
0
,
sa_len
);
rv
=
connect
((
SOCKET
)
fd
,
(
struct
sockaddr
*
)
&
p
sa
,
sa_len
);
rv
=
connect
((
SOCKET
)
fd
,
(
struct
sockaddr
*
)
&
sa
,
sa_len
);
if
(
rv
==
SOCKET_ERROR
)
{
if
(
rv
==
SOCKET_ERROR
)
{
handleSocketError
(
env
,
WSAGetLastError
());
handleSocketError
(
env
,
WSAGetLastError
());
}
}
...
@@ -200,10 +130,11 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
...
@@ -200,10 +130,11 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
{
{
jint
fd
=
fdval
(
env
,
fdo
);
jint
fd
=
fdval
(
env
,
fdo
);
void
*
buf
=
(
void
*
)
jlong_to_ptr
(
address
);
void
*
buf
=
(
void
*
)
jlong_to_ptr
(
address
);
struct
sockaddr_in
p
sa
;
SOCKETADDRESS
sa
;
int
sa_len
=
sizeof
(
p
sa
);
int
sa_len
=
sizeof
(
sa
);
BOOL
retry
=
FALSE
;
BOOL
retry
=
FALSE
;
jint
n
;
jint
n
;
jobject
senderAddr
;
do
{
do
{
retry
=
FALSE
;
retry
=
FALSE
;
...
@@ -211,7 +142,7 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
...
@@ -211,7 +142,7 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
(
char
*
)
buf
,
(
char
*
)
buf
,
len
,
len
,
0
,
0
,
(
struct
sockaddr
*
)
&
p
sa
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
);
&
sa_len
);
if
(
n
==
SOCKET_ERROR
)
{
if
(
n
==
SOCKET_ERROR
)
{
...
@@ -233,21 +164,30 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
...
@@ -233,21 +164,30 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
}
}
}
while
(
retry
);
}
while
(
retry
);
if
(
!
isSenderCached
(
env
,
this
,
&
psa
))
{
/*
int
port
=
ntohs
(
psa
.
sin_port
);
* If the source address and port match the cached address
jobject
ia
=
(
*
env
)
->
NewObject
(
env
,
ia_class
,
ia_ctorID
);
* and port in DatagramChannelImpl then we don't need to
jobject
isa
=
NULL
;
* create InetAddress and InetSocketAddress objects.
*/
if
(
psa
.
sin_family
!=
AF_INET
)
{
senderAddr
=
(
*
env
)
->
GetObjectField
(
env
,
this
,
dci_senderAddrID
);
JNU_ThrowByName
(
env
,
JNU_JAVANETPKG
"SocketException"
,
if
(
senderAddr
!=
NULL
)
{
"Protocol family unavailable"
);
if
(
!
NET_SockaddrEqualsInetAddress
(
env
,
(
struct
sockaddr
*
)
&
sa
,
senderAddr
))
{
senderAddr
=
NULL
;
}
else
{
jint
port
=
(
*
env
)
->
GetIntField
(
env
,
this
,
dci_senderPortID
);
if
(
port
!=
NET_GetPortFromSockaddr
((
struct
sockaddr
*
)
&
sa
))
{
senderAddr
=
NULL
;
}
}
}
}
if
(
senderAddr
==
NULL
)
{
jobject
isa
=
NULL
;
int
port
;
jobject
ia
=
NET_SockaddrToInetAddress
(
env
,
(
struct
sockaddr
*
)
&
sa
,
&
port
);
if
(
ia
!=
NULL
)
{
if
(
ia
!=
NULL
)
{
// populate InetAddress (assumes AF_INET)
(
*
env
)
->
SetIntField
(
env
,
ia
,
ia_addrID
,
ntohl
(
psa
.
sin_addr
.
s_addr
));
// create InetSocketAddress
isa
=
(
*
env
)
->
NewObject
(
env
,
isa_class
,
isa_ctorID
,
ia
,
port
);
isa
=
(
*
env
)
->
NewObject
(
env
,
isa_class
,
isa_ctorID
,
ia
,
port
);
}
}
...
@@ -258,9 +198,8 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
...
@@ -258,9 +198,8 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
// update cachedSenderInetAddress/cachedSenderPort
// update cachedSenderInetAddress/cachedSenderPort
(
*
env
)
->
SetObjectField
(
env
,
this
,
dci_senderAddrID
,
ia
);
(
*
env
)
->
SetObjectField
(
env
,
this
,
dci_senderAddrID
,
ia
);
(
*
env
)
->
SetIntField
(
env
,
this
,
dci_senderPortID
,
port
);
(
*
env
)
->
SetIntField
(
env
,
this
,
dci_senderPortID
,
NET_GetPortFromSockaddr
((
struct
sockaddr
*
)
&
sa
));
// update sender
(
*
env
)
->
SetObjectField
(
env
,
this
,
dci_senderID
,
isa
);
(
*
env
)
->
SetObjectField
(
env
,
this
,
dci_senderID
,
isa
);
}
}
return
n
;
return
n
;
...
@@ -268,21 +207,20 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
...
@@ -268,21 +207,20 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
JNIEXPORT
jint
JNICALL
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_DatagramChannelImpl_send0
(
JNIEnv
*
env
,
jobject
this
,
Java_sun_nio_ch_DatagramChannelImpl_send0
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
,
jlong
address
,
jboolean
preferIPv6
,
jobject
fdo
,
jint
len
,
jobject
dest
)
jlong
address
,
jint
len
,
jobject
dest
)
{
{
jint
fd
=
fdval
(
env
,
fdo
);
jint
fd
=
fdval
(
env
,
fdo
);
void
*
buf
=
(
void
*
)
jlong_to_ptr
(
address
);
void
*
buf
=
(
void
*
)
jlong_to_ptr
(
address
);
SOCKETADDRESS
p
sa
;
SOCKETADDRESS
sa
;
int
sa_len
=
sizeof
(
psa
)
;
int
sa_len
;
jint
rv
=
0
;
jint
rv
=
0
;
jobject
destAddress
=
(
*
env
)
->
GetObjectField
(
env
,
dest
,
isa_addrID
);
jobject
destAddress
=
(
*
env
)
->
GetObjectField
(
env
,
dest
,
isa_addrID
);
jint
destPort
=
(
*
env
)
->
GetIntField
(
env
,
dest
,
isa_portID
);
jint
destPort
=
(
*
env
)
->
GetIntField
(
env
,
dest
,
isa_portID
);
if
(
NET_InetAddressToSockaddr
(
env
,
destAddress
,
destPort
,
if
(
NET_InetAddressToSockaddr
(
env
,
destAddress
,
destPort
,
(
struct
sockaddr
*
)
&
p
sa
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
JNI_FALSE
)
!=
0
)
{
&
sa_len
,
preferIPv6
)
!=
0
)
{
return
IOS_THROWN
;
return
IOS_THROWN
;
}
}
...
@@ -290,7 +228,7 @@ Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
...
@@ -290,7 +228,7 @@ Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
buf
,
buf
,
len
,
len
,
0
,
0
,
(
struct
sockaddr
*
)
&
p
sa
,
(
struct
sockaddr
*
)
&
sa
,
sa_len
);
sa_len
);
if
(
rv
==
SOCKET_ERROR
)
{
if
(
rv
==
SOCKET_ERROR
)
{
int
theErr
=
(
jint
)
WSAGetLastError
();
int
theErr
=
(
jint
)
WSAGetLastError
();
...
...
src/windows/native/sun/nio/ch/Net.c
浏览文件 @
ec347b32
...
@@ -36,51 +36,95 @@
...
@@ -36,51 +36,95 @@
#include "sun_nio_ch_Net.h"
#include "sun_nio_ch_Net.h"
/**
* Definitions to allow for building with older SDK include files.
*/
#ifndef MCAST_BLOCK_SOURCE
#define MCAST_BLOCK_SOURCE 43
#define MCAST_UNBLOCK_SOURCE 44
#define MCAST_JOIN_SOURCE_GROUP 45
#define MCAST_LEAVE_SOURCE_GROUP 46
#endif
/* MCAST_BLOCK_SOURCE */
static
jfieldID
ia_addrID
;
typedef
struct
my_ip_mreq_source
{
static
jclass
ia_class
;
IN_ADDR
imr_multiaddr
;
static
jmethodID
ia_ctorID
;
IN_ADDR
imr_sourceaddr
;
static
jfieldID
ia_famID
;
IN_ADDR
imr_interface
;
};
/**************************************************************
typedef
struct
my_group_source_req
{
* static method to store field IDs in initializers
ULONG
gsr_interface
;
SOCKADDR_STORAGE
gsr_group
;
SOCKADDR_STORAGE
gsr_source
;
};
/**
* Copy IPv6 address as jbytearray to target
*/
*/
#define COPY_INET6_ADDRESS(env, source, target) \
(*env)->GetByteArrayRegion(env, source, 0, 16, target)
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_initIDs
(
JNIEnv
*
env
,
jclass
clazz
)
Java_sun_nio_ch_Net_initIDs
(
JNIEnv
*
env
,
jclass
clazz
)
{
{
clazz
=
(
*
env
)
->
FindClass
(
env
,
"java/net/Inet4Address"
);
/* nothing to do */
ia_class
=
(
*
env
)
->
NewGlobalRef
(
env
,
clazz
);
ia_addrID
=
(
*
env
)
->
GetFieldID
(
env
,
clazz
,
"address"
,
"I"
);
ia_famID
=
(
*
env
)
->
GetFieldID
(
env
,
clazz
,
"family"
,
"I"
);
ia_ctorID
=
(
*
env
)
->
GetMethodID
(
env
,
clazz
,
"<init>"
,
"()V"
);
}
}
JNIEXPORT
jboolean
JNICALL
Java_sun_nio_ch_Net_isIPv6Available0
(
JNIEnv
*
env
,
jclass
cl
)
{
/*
* Return true if Windows Vista or newer, and IPv6 is configured
*/
OSVERSIONINFO
ver
;
ver
.
dwOSVersionInfoSize
=
sizeof
(
ver
);
GetVersionEx
(
&
ver
);
if
((
ver
.
dwPlatformId
==
VER_PLATFORM_WIN32_NT
)
&&
(
ver
.
dwMajorVersion
>=
6
)
&&
ipv6_available
())
{
return
JNI_TRUE
;
}
return
JNI_FALSE
;
}
JNIEXPORT
jint
JNICALL
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_socket0
(
JNIEnv
*
env
,
jclass
cl
,
jboolean
stream
,
Java_sun_nio_ch_Net_socket0
(
JNIEnv
*
env
,
jclass
cl
,
jboolean
preferIPv6
,
jboolean
reuse
)
jboolean
stream
,
jboolean
reuse
)
{
{
SOCKET
s
;
SOCKET
s
;
int
domain
=
(
preferIPv6
)
?
AF_INET6
:
AF_INET
;
s
=
socket
(
AF_INET
,
(
stream
?
SOCK_STREAM
:
SOCK_DGRAM
),
0
);
s
=
socket
(
domain
,
(
stream
?
SOCK_STREAM
:
SOCK_DGRAM
),
0
);
if
(
s
!=
INVALID_SOCKET
)
{
if
(
s
!=
INVALID_SOCKET
)
{
SetHandleInformation
((
HANDLE
)
s
,
HANDLE_FLAG_INHERIT
,
0
);
SetHandleInformation
((
HANDLE
)
s
,
HANDLE_FLAG_INHERIT
,
0
);
/* IPV6_V6ONLY is true by default */
if
(
domain
==
AF_INET6
)
{
int
opt
=
0
;
setsockopt
(
s
,
IPPROTO_IPV6
,
IPV6_V6ONLY
,
(
const
char
*
)
&
opt
,
sizeof
(
opt
));
}
}
else
{
}
else
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"socket"
);
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"socket"
);
}
}
return
(
jint
)
s
;
return
(
jint
)
s
;
}
}
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_bind
(
JNIEnv
*
env
,
jclass
clazz
,
Java_sun_nio_ch_Net_bind
0
(
JNIEnv
*
env
,
jclass
clazz
,
jboolean
preferIPv6
,
jobject
fdo
,
jobject
iao
,
jint
port
)
jobject
fdo
,
jobject
iao
,
jint
port
)
{
{
SOCKETADDRESS
sa
;
SOCKETADDRESS
sa
;
int
rv
;
int
rv
;
int
sa_len
=
sizeof
(
sa
)
;
int
sa_len
;
if
(
NET_InetAddressToSockaddr
(
env
,
iao
,
port
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
JNI_FALSE
)
!=
0
)
{
if
(
NET_InetAddressToSockaddr
(
env
,
iao
,
port
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
preferIPv6
)
!=
0
)
{
return
;
return
;
}
}
...
@@ -89,16 +133,25 @@ Java_sun_nio_ch_Net_bind(JNIEnv *env, jclass clazz,
...
@@ -89,16 +133,25 @@ Java_sun_nio_ch_Net_bind(JNIEnv *env, jclass clazz,
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"bind"
);
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"bind"
);
}
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_listen
(
JNIEnv
*
env
,
jclass
cl
,
jobject
fdo
,
jint
backlog
)
{
if
(
listen
(
fdval
(
env
,
fdo
),
backlog
)
==
SOCKET_ERROR
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"listen"
);
}
}
JNIEXPORT
jint
JNICALL
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_connect
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
,
jobject
ia
o
,
Java_sun_nio_ch_Net_connect
0
(
JNIEnv
*
env
,
jclass
clazz
,
jboolean
preferIPv6
,
jobject
fd
o
,
jint
port
,
jint
trafficClass
)
jobject
iao
,
jint
port
)
{
{
SOCKETADDRESS
sa
;
SOCKETADDRESS
sa
;
int
rv
;
int
rv
;
int
sa_len
=
sizeof
(
sa
)
;
int
sa_len
;
if
(
NET_InetAddressToSockaddr
(
env
,
iao
,
port
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
JNI_FALSE
)
!=
0
)
{
if
(
NET_InetAddressToSockaddr
(
env
,
iao
,
port
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
,
preferIPv6
)
!=
0
)
{
return
IOS_THROWN
;
return
IOS_THROWN
;
}
}
rv
=
connect
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
sa_len
);
rv
=
connect
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
sa_len
);
...
@@ -116,7 +169,7 @@ Java_sun_nio_ch_Net_connect(JNIEnv *env, jclass clazz, jobject fdo, jobject iao,
...
@@ -116,7 +169,7 @@ Java_sun_nio_ch_Net_connect(JNIEnv *env, jclass clazz, jobject fdo, jobject iao,
JNIEXPORT
jint
JNICALL
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_localPort
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
)
Java_sun_nio_ch_Net_localPort
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
)
{
{
struct
sockaddr_in
sa
;
SOCKETADDRESS
sa
;
int
sa_len
=
sizeof
(
sa
);
int
sa_len
=
sizeof
(
sa
);
if
(
getsockname
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
)
<
0
)
{
if
(
getsockname
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
)
<
0
)
{
...
@@ -127,50 +180,64 @@ Java_sun_nio_ch_Net_localPort(JNIEnv *env, jclass clazz, jobject fdo)
...
@@ -127,50 +180,64 @@ Java_sun_nio_ch_Net_localPort(JNIEnv *env, jclass clazz, jobject fdo)
NET_ThrowNew
(
env
,
error
,
"getsockname"
);
NET_ThrowNew
(
env
,
error
,
"getsockname"
);
return
IOS_THROWN
;
return
IOS_THROWN
;
}
}
return
(
jint
)
ntohs
(
sa
.
sin_port
);
return
NET_GetPortFromSockaddr
((
struct
sockaddr
*
)
&
sa
);
}
}
JNIEXPORT
jobject
JNICALL
JNIEXPORT
jobject
JNICALL
Java_sun_nio_ch_Net_localInetAddress
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
)
Java_sun_nio_ch_Net_localInetAddress
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
)
{
{
struct
sockaddr_in
sa
;
SOCKETADDRESS
sa
;
int
sa_len
=
sizeof
(
sa
);
int
sa_len
=
sizeof
(
sa
);
jobject
iao
;
int
port
;
if
(
getsockname
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
)
<
0
)
{
if
(
getsockname
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
)
<
0
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"getsockname"
);
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"getsockname"
);
return
NULL
;
return
NULL
;
}
}
return
NET_SockaddrToInetAddress
(
env
,
(
struct
sockaddr
*
)
&
sa
,
&
port
);
}
iao
=
(
*
env
)
->
NewObject
(
env
,
ia_class
,
ia_ctorID
);
JNIEXPORT
jint
JNICALL
if
(
iao
==
NULL
)
{
Java_sun_nio_ch_Net_remotePort
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
)
JNU_ThrowOutOfMemoryError
(
env
,
"heap allocation failure"
);
{
}
else
{
SOCKETADDRESS
sa
;
(
*
env
)
->
SetIntField
(
env
,
iao
,
ia_addrID
,
ntohl
(
sa
.
sin_addr
.
s_addr
));
int
sa_len
=
sizeof
(
sa
);
}
return
iao
;
if
(
getpeername
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
)
<
0
)
{
int
error
=
WSAGetLastError
();
if
(
error
==
WSAEINVAL
)
{
return
0
;
}
NET_ThrowNew
(
env
,
error
,
"getsockname"
);
return
IOS_THROWN
;
}
return
NET_GetPortFromSockaddr
((
struct
sockaddr
*
)
&
sa
);
}
}
JNIEXPORT
jobject
JNICALL
Java_sun_nio_ch_Net_remoteInetAddress
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
)
{
SOCKETADDRESS
sa
;
int
sa_len
=
sizeof
(
sa
);
int
port
;
if
(
getpeername
(
fdval
(
env
,
fdo
),
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
)
<
0
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"getsockname"
);
return
NULL
;
}
return
NET_SockaddrToInetAddress
(
env
,
(
struct
sockaddr
*
)
&
sa
,
&
port
);
}
JNIEXPORT
jint
JNICALL
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_getIntOption0
(
JNIEnv
*
env
,
jclass
clazz
,
Java_sun_nio_ch_Net_getIntOption0
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
,
j
object
fdo
,
jint
opt
)
j
boolean
mayNeedConversion
,
jint
level
,
jint
opt
)
{
{
int
klevel
,
kopt
;
int
result
=
0
;
int
result
;
struct
linger
linger
;
struct
linger
linger
;
char
*
arg
;
char
*
arg
;
int
arglen
;
int
arglen
,
n
;
if
(
NET_MapSocketOption
(
opt
,
&
klevel
,
&
kopt
)
<
0
)
{
JNU_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"SocketException"
,
"Unsupported socket option"
);
return
IOS_THROWN
;
}
if
(
opt
==
java_net_SocketOptions_
SO_LINGER
)
{
if
(
level
==
SOL_SOCKET
&&
opt
==
SO_LINGER
)
{
arg
=
(
char
*
)
&
linger
;
arg
=
(
char
*
)
&
linger
;
arglen
=
sizeof
(
linger
);
arglen
=
sizeof
(
linger
);
}
else
{
}
else
{
...
@@ -178,34 +245,40 @@ Java_sun_nio_ch_Net_getIntOption0(JNIEnv *env, jclass clazz,
...
@@ -178,34 +245,40 @@ Java_sun_nio_ch_Net_getIntOption0(JNIEnv *env, jclass clazz,
arglen
=
sizeof
(
result
);
arglen
=
sizeof
(
result
);
}
}
if
(
NET_GetSockOpt
(
fdval
(
env
,
fdo
),
klevel
,
kopt
,
arg
,
&
arglen
)
<
0
)
{
/**
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"sun.nio.ch.Net.setIntOption"
);
* HACK: IP_TOS is deprecated on Windows and querying the option
* returns a protocol error. NET_GetSockOpt handles this and uses
* a fallback mechanism.
*/
if
(
level
==
IPPROTO_IP
&&
opt
==
IP_TOS
)
{
mayNeedConversion
=
JNI_TRUE
;
}
if
(
mayNeedConversion
)
{
n
=
NET_GetSockOpt
(
fdval
(
env
,
fdo
),
level
,
opt
,
arg
,
&
arglen
);
}
else
{
n
=
getsockopt
(
fdval
(
env
,
fdo
),
level
,
opt
,
arg
,
&
arglen
);
}
if
(
n
<
0
)
{
handleSocketError
(
env
,
WSAGetLastError
());
return
IOS_THROWN
;
return
IOS_THROWN
;
}
}
if
(
opt
==
java_net_SocketOptions_
SO_LINGER
)
if
(
level
==
SOL_SOCKET
&&
opt
==
SO_LINGER
)
return
linger
.
l_onoff
?
linger
.
l_linger
:
-
1
;
return
linger
.
l_onoff
?
linger
.
l_linger
:
-
1
;
else
else
return
result
;
return
result
;
}
}
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_setIntOption0
(
JNIEnv
*
env
,
jclass
clazz
,
Java_sun_nio_ch_Net_setIntOption0
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
,
j
object
fdo
,
jint
opt
,
jint
arg
)
j
boolean
mayNeedConversion
,
jint
level
,
jint
opt
,
jint
arg
)
{
{
int
klevel
,
kopt
;
struct
linger
linger
;
struct
linger
linger
;
char
*
parg
;
char
*
parg
;
int
arglen
;
int
arglen
,
n
;
if
(
NET_MapSocketOption
(
opt
,
&
klevel
,
&
kopt
)
<
0
)
{
if
(
level
==
SOL_SOCKET
&&
opt
==
SO_LINGER
)
{
JNU_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"SocketException"
,
"Unsupported socket option"
);
return
;
}
if
(
opt
==
java_net_SocketOptions_SO_LINGER
)
{
parg
=
(
char
*
)
&
linger
;
parg
=
(
char
*
)
&
linger
;
arglen
=
sizeof
(
linger
);
arglen
=
sizeof
(
linger
);
if
(
arg
>=
0
)
{
if
(
arg
>=
0
)
{
...
@@ -220,7 +293,200 @@ Java_sun_nio_ch_Net_setIntOption0(JNIEnv *env, jclass clazz,
...
@@ -220,7 +293,200 @@ Java_sun_nio_ch_Net_setIntOption0(JNIEnv *env, jclass clazz,
arglen
=
sizeof
(
arg
);
arglen
=
sizeof
(
arg
);
}
}
if
(
NET_SetSockOpt
(
fdval
(
env
,
fdo
),
klevel
,
kopt
,
parg
,
arglen
)
<
0
)
{
if
(
mayNeedConversion
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"sun.nio.ch.Net.setIntOption"
);
n
=
NET_SetSockOpt
(
fdval
(
env
,
fdo
),
level
,
opt
,
parg
,
arglen
);
}
else
{
n
=
setsockopt
(
fdval
(
env
,
fdo
),
level
,
opt
,
parg
,
arglen
);
}
if
(
n
<
0
)
handleSocketError
(
env
,
WSAGetLastError
());
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_joinOrDrop4
(
JNIEnv
*
env
,
jobject
this
,
jboolean
join
,
jobject
fdo
,
jint
group
,
jint
interf
,
jint
source
)
{
struct
ip_mreq
mreq
;
struct
my_ip_mreq_source
mreq_source
;
int
opt
,
n
,
optlen
;
void
*
optval
;
if
(
source
==
0
)
{
mreq
.
imr_multiaddr
.
s_addr
=
htonl
(
group
);
mreq
.
imr_interface
.
s_addr
=
htonl
(
interf
);
opt
=
(
join
)
?
IP_ADD_MEMBERSHIP
:
IP_DROP_MEMBERSHIP
;
optval
=
(
void
*
)
&
mreq
;
optlen
=
sizeof
(
mreq
);
}
else
{
mreq_source
.
imr_multiaddr
.
s_addr
=
htonl
(
group
);
mreq_source
.
imr_sourceaddr
.
s_addr
=
htonl
(
source
);
mreq_source
.
imr_interface
.
s_addr
=
htonl
(
interf
);
opt
=
(
join
)
?
IP_ADD_SOURCE_MEMBERSHIP
:
IP_DROP_SOURCE_MEMBERSHIP
;
optval
=
(
void
*
)
&
mreq_source
;
optlen
=
sizeof
(
mreq_source
);
}
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IP
,
opt
,
optval
,
optlen
);
if
(
n
<
0
)
{
if
(
join
&&
(
WSAGetLastError
()
==
WSAENOPROTOOPT
))
return
IOS_UNAVAILABLE
;
handleSocketError
(
env
,
WSAGetLastError
());
}
return
0
;
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_blockOrUnblock4
(
JNIEnv
*
env
,
jobject
this
,
jboolean
block
,
jobject
fdo
,
jint
group
,
jint
interf
,
jint
source
)
{
struct
my_ip_mreq_source
mreq_source
;
int
n
;
int
opt
=
(
block
)
?
IP_BLOCK_SOURCE
:
IP_UNBLOCK_SOURCE
;
mreq_source
.
imr_multiaddr
.
s_addr
=
htonl
(
group
);
mreq_source
.
imr_sourceaddr
.
s_addr
=
htonl
(
source
);
mreq_source
.
imr_interface
.
s_addr
=
htonl
(
interf
);
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IP
,
opt
,
(
void
*
)
&
mreq_source
,
sizeof
(
mreq_source
));
if
(
n
<
0
)
{
if
(
block
&&
(
WSAGetLastError
()
==
WSAENOPROTOOPT
))
return
IOS_UNAVAILABLE
;
handleSocketError
(
env
,
WSAGetLastError
());
}
return
0
;
}
/**
* Call setsockopt with a IPPROTO_IPV6 level socket option
* and a group_source_req structure as the option value. The
* given IPv6 group, interface index, and IPv6 source address
* are copied into the structure.
*/
static
int
setGroupSourceReqOption
(
JNIEnv
*
env
,
jobject
fdo
,
int
opt
,
jbyteArray
group
,
jint
index
,
jbyteArray
source
)
{
struct
my_group_source_req
req
;
struct
sockaddr_in6
*
sin6
;
req
.
gsr_interface
=
(
ULONG
)
index
;
sin6
=
(
struct
sockaddr_in6
*
)
&
(
req
.
gsr_group
);
sin6
->
sin6_family
=
AF_INET6
;
COPY_INET6_ADDRESS
(
env
,
group
,
(
jbyte
*
)
&
(
sin6
->
sin6_addr
));
sin6
=
(
struct
sockaddr_in6
*
)
&
(
req
.
gsr_source
);
sin6
->
sin6_family
=
AF_INET6
;
COPY_INET6_ADDRESS
(
env
,
source
,
(
jbyte
*
)
&
(
sin6
->
sin6_addr
));
return
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IPV6
,
opt
,
(
void
*
)
&
req
,
sizeof
(
req
));
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_joinOrDrop6
(
JNIEnv
*
env
,
jobject
this
,
jboolean
join
,
jobject
fdo
,
jbyteArray
group
,
jint
index
,
jbyteArray
source
)
{
struct
ipv6_mreq
mreq6
;
int
n
;
if
(
source
==
NULL
)
{
int
opt
=
(
join
)
?
IPV6_ADD_MEMBERSHIP
:
IPV6_DROP_MEMBERSHIP
;
COPY_INET6_ADDRESS
(
env
,
group
,
(
jbyte
*
)
&
(
mreq6
.
ipv6mr_multiaddr
));
mreq6
.
ipv6mr_interface
=
(
int
)
index
;
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IPV6
,
opt
,
(
void
*
)
&
mreq6
,
sizeof
(
mreq6
));
}
else
{
int
opt
=
(
join
)
?
MCAST_JOIN_SOURCE_GROUP
:
MCAST_LEAVE_SOURCE_GROUP
;
n
=
setGroupSourceReqOption
(
env
,
fdo
,
opt
,
group
,
index
,
source
);
}
if
(
n
<
0
)
{
handleSocketError
(
env
,
errno
);
}
return
0
;
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_blockOrUnblock6
(
JNIEnv
*
env
,
jobject
this
,
jboolean
block
,
jobject
fdo
,
jbyteArray
group
,
jint
index
,
jbyteArray
source
)
{
int
opt
=
(
block
)
?
MCAST_BLOCK_SOURCE
:
MCAST_UNBLOCK_SOURCE
;
int
n
=
setGroupSourceReqOption
(
env
,
fdo
,
opt
,
group
,
index
,
source
);
if
(
n
<
0
)
{
handleSocketError
(
env
,
errno
);
}
return
0
;
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_setInterface4
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
,
jint
interf
)
{
struct
in_addr
in
;
int
arglen
=
sizeof
(
struct
in_addr
);
int
n
;
in
.
s_addr
=
htonl
(
interf
);
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IP
,
IP_MULTICAST_IF
,
(
void
*
)
&
(
in
.
s_addr
),
arglen
);
if
(
n
<
0
)
{
handleSocketError
(
env
,
WSAGetLastError
());
}
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_getInterface4
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
)
{
struct
in_addr
in
;
int
arglen
=
sizeof
(
struct
in_addr
);
int
n
;
n
=
getsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IP
,
IP_MULTICAST_IF
,
(
void
*
)
&
in
,
&
arglen
);
if
(
n
<
0
)
{
handleSocketError
(
env
,
WSAGetLastError
());
return
IOS_THROWN
;
}
return
ntohl
(
in
.
s_addr
);
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_setInterface6
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
,
jint
index
)
{
int
value
=
(
jint
)
index
;
int
arglen
=
sizeof
(
value
);
int
n
;
n
=
setsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IPV6
,
IPV6_MULTICAST_IF
,
(
void
*
)
&
(
index
),
arglen
);
if
(
n
<
0
)
{
handleSocketError
(
env
,
errno
);
}
}
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_Net_getInterface6
(
JNIEnv
*
env
,
jobject
this
,
jobject
fdo
)
{
int
index
;
int
arglen
=
sizeof
(
index
);
int
n
;
n
=
getsockopt
(
fdval
(
env
,
fdo
),
IPPROTO_IPV6
,
IPV6_MULTICAST_IF
,
(
void
*
)
&
index
,
&
arglen
);
if
(
n
<
0
)
{
handleSocketError
(
env
,
errno
);
return
-
1
;
}
return
(
jint
)
index
;
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_Net_shutdown
(
JNIEnv
*
env
,
jclass
cl
,
jobject
fdo
,
jint
jhow
)
{
int
how
=
(
jhow
==
sun_nio_ch_Net_SHUT_RD
)
?
SD_RECEIVE
:
(
jhow
==
sun_nio_ch_Net_SHUT_WR
)
?
SD_SEND
:
SD_BOTH
;
if
(
shutdown
(
fdval
(
env
,
fdo
),
how
)
==
SOCKET_ERROR
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"shutdown"
);
}
}
}
}
src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c
浏览文件 @
ec347b32
...
@@ -46,10 +46,6 @@
...
@@ -46,10 +46,6 @@
static
jfieldID
fd_fdID
;
/* java.io.FileDescriptor.fd */
static
jfieldID
fd_fdID
;
/* java.io.FileDescriptor.fd */
static
jclass
isa_class
;
/* java.net.InetSocketAddress */
static
jclass
isa_class
;
/* java.net.InetSocketAddress */
static
jmethodID
isa_ctorID
;
/* InetSocketAddress(InetAddress, int) */
static
jmethodID
isa_ctorID
;
/* InetSocketAddress(InetAddress, int) */
static
jclass
ia_class
;
/* java.net.InetAddress */
static
jmethodID
ia_ctorID
;
/* InetAddress() */
static
jfieldID
ia_addrID
;
/* java.net.InetAddress.address */
static
jfieldID
ia_famID
;
/* java.net.InetAddress.family */
/**************************************************************
/**************************************************************
...
@@ -66,12 +62,6 @@ Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv *env, jclass cls)
...
@@ -66,12 +62,6 @@ Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv *env, jclass cls)
isa_class
=
(
*
env
)
->
NewGlobalRef
(
env
,
cls
);
isa_class
=
(
*
env
)
->
NewGlobalRef
(
env
,
cls
);
isa_ctorID
=
(
*
env
)
->
GetMethodID
(
env
,
cls
,
"<init>"
,
isa_ctorID
=
(
*
env
)
->
GetMethodID
(
env
,
cls
,
"<init>"
,
"(Ljava/net/InetAddress;I)V"
);
"(Ljava/net/InetAddress;I)V"
);
cls
=
(
*
env
)
->
FindClass
(
env
,
"java/net/Inet4Address"
);
ia_class
=
(
*
env
)
->
NewGlobalRef
(
env
,
cls
);
ia_ctorID
=
(
*
env
)
->
GetMethodID
(
env
,
cls
,
"<init>"
,
"()V"
);
ia_addrID
=
(
*
env
)
->
GetFieldID
(
env
,
cls
,
"address"
,
"I"
);
ia_famID
=
(
*
env
)
->
GetFieldID
(
env
,
cls
,
"family"
,
"I"
);
}
}
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
...
@@ -90,8 +80,9 @@ Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv *env, jobject this,
...
@@ -90,8 +80,9 @@ Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv *env, jobject this,
{
{
jint
ssfd
=
(
*
env
)
->
GetIntField
(
env
,
ssfdo
,
fd_fdID
);
jint
ssfd
=
(
*
env
)
->
GetIntField
(
env
,
ssfdo
,
fd_fdID
);
jint
newfd
;
jint
newfd
;
struct
sockaddr_in
sa
;
SOCKETADDRESS
sa
;
jobject
remote_ia
=
0
;
jobject
remote_ia
;
int
remote_port
;
jobject
isa
;
jobject
isa
;
jobject
ia
;
jobject
ia
;
int
addrlen
=
sizeof
(
sa
);
int
addrlen
=
sizeof
(
sa
);
...
@@ -106,14 +97,13 @@ Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv *env, jobject this,
...
@@ -106,14 +97,13 @@ Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv *env, jobject this,
JNU_ThrowIOExceptionWithLastError
(
env
,
"Accept failed"
);
JNU_ThrowIOExceptionWithLastError
(
env
,
"Accept failed"
);
return
IOS_THROWN
;
return
IOS_THROWN
;
}
}
(
*
env
)
->
SetIntField
(
env
,
newfdo
,
fd_fdID
,
newfd
);
ia
=
(
*
env
)
->
NewObject
(
env
,
ia_class
,
ia_ctorID
);
(
*
env
)
->
SetIntField
(
env
,
newfdo
,
fd_fdID
,
newfd
);
(
*
env
)
->
SetIntField
(
env
,
ia
,
ia_addrID
,
ntohl
(
sa
.
sin_addr
.
s_addr
));
remote_ia
=
NET_SockaddrToInetAddress
(
env
,
(
struct
sockaddr
*
)
&
sa
,
(
int
*
)
&
remote_port
);
(
*
env
)
->
SetIntField
(
env
,
ia
,
ia_famID
,
sa
.
sin_family
);
isa
=
(
*
env
)
->
NewObject
(
env
,
isa_class
,
isa_ctorID
,
ia
,
isa
=
(
*
env
)
->
NewObject
(
env
,
isa_class
,
isa_ctorID
,
ntohs
(
sa
.
sin_port
)
);
remote_ia
,
remote_port
);
(
*
env
)
->
SetObjectArrayElement
(
env
,
isaa
,
0
,
isa
);
(
*
env
)
->
SetObjectArrayElement
(
env
,
isaa
,
0
,
isa
);
return
1
;
return
1
;
}
}
src/windows/native/sun/nio/ch/SocketChannelImpl.c
浏览文件 @
ec347b32
...
@@ -139,12 +139,3 @@ Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this,
...
@@ -139,12 +139,3 @@ Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this,
return
0
;
return
0
;
}
}
JNIEXPORT
void
JNICALL
Java_sun_nio_ch_SocketChannelImpl_shutdown
(
JNIEnv
*
env
,
jclass
cl
,
jobject
fdo
,
jint
how
)
{
if
(
shutdown
(
fdval
(
env
,
fdo
),
how
)
==
SOCKET_ERROR
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"shutdown"
);
}
}
test/java/nio/channels/DatagramChannel/BasicMulticastTests.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 4527345
* @summary Unit test for DatagramChannel's multicast support
* @build BasicMulticastTests NetworkConfiguration
*/
import
java.nio.ByteBuffer
;
import
java.nio.channels.*
;
import
java.net.*
;
import
java.util.*
;
import
java.io.IOException
;
public
class
BasicMulticastTests
{
/**
* Tests that existing membership key is returned by join methods and that
* membership key methods return the expected results
*/
static
void
membershipKeyTests
(
NetworkInterface
nif
,
InetAddress
group
,
InetAddress
source
)
throws
IOException
{
System
.
out
.
format
(
"MembershipKey test using %s @ %s\n"
,
group
.
getHostAddress
(),
nif
.
getName
());
ProtocolFamily
family
=
(
group
instanceof
Inet4Address
)
?
StandardProtocolFamily
.
INET
:
StandardProtocolFamily
.
INET6
;
DatagramChannel
dc
=
DatagramChannel
.
open
(
family
)
.
setOption
(
StandardSocketOption
.
SO_REUSEADDR
,
true
)
.
bind
(
new
InetSocketAddress
(
source
,
0
));
// check existing key is returned
MembershipKey
key
=
dc
.
join
(
group
,
nif
);
MembershipKey
other
=
dc
.
join
(
group
,
nif
);
if
(
other
!=
key
)
{
throw
new
RuntimeException
(
"existing key not returned"
);
}
// check key
if
(!
key
.
isValid
())
throw
new
RuntimeException
(
"key is not valid"
);
if
(!
key
.
getGroup
().
equals
(
group
))
throw
new
RuntimeException
(
"group is incorrect"
);
if
(!
key
.
getNetworkInterface
().
equals
(
nif
))
throw
new
RuntimeException
(
"network interface is incorrect"
);
if
(
key
.
getSourceAddress
()
!=
null
)
throw
new
RuntimeException
(
"key is source specific"
);
// drop membership
key
.
drop
();
if
(
key
.
isValid
())
{
throw
new
RuntimeException
(
"key is still valid"
);
}
// source-specific
try
{
key
=
dc
.
join
(
group
,
nif
,
source
);
other
=
dc
.
join
(
group
,
nif
,
source
);
if
(
other
!=
key
)
{
throw
new
RuntimeException
(
"existing key not returned"
);
}
if
(!
key
.
isValid
())
throw
new
RuntimeException
(
"key is not valid"
);
if
(!
key
.
getGroup
().
equals
(
group
))
throw
new
RuntimeException
(
"group is incorrect"
);
if
(!
key
.
getNetworkInterface
().
equals
(
nif
))
throw
new
RuntimeException
(
"network interface is incorrect"
);
if
(!
key
.
getSourceAddress
().
equals
(
source
))
throw
new
RuntimeException
(
"key's source address incorrect"
);
// drop membership
key
.
drop
();
if
(
key
.
isValid
())
{
throw
new
RuntimeException
(
"key is still valid"
);
}
}
catch
(
UnsupportedOperationException
x
)
{
}
// done
dc
.
close
();
}
/**
* Tests exceptions for invalid arguments or scenarios
*/
static
void
exceptionTests
(
NetworkInterface
nif
)
throws
IOException
{
System
.
out
.
println
(
"Exception Tests"
);
DatagramChannel
dc
=
DatagramChannel
.
open
(
StandardProtocolFamily
.
INET
)
.
setOption
(
StandardSocketOption
.
SO_REUSEADDR
,
true
)
.
bind
(
new
InetSocketAddress
(
0
));
InetAddress
group
=
InetAddress
.
getByName
(
"225.4.5.6"
);
InetAddress
notGroup
=
InetAddress
.
getByName
(
"1.2.3.4"
);
InetAddress
thisHost
=
InetAddress
.
getLocalHost
();
// IllegalStateException
MembershipKey
key
;
key
=
dc
.
join
(
group
,
nif
);
try
{
dc
.
join
(
group
,
nif
,
thisHost
);
throw
new
RuntimeException
(
"IllegalStateException not thrown"
);
}
catch
(
IllegalStateException
x
)
{
}
catch
(
UnsupportedOperationException
x
)
{
}
key
.
drop
();
try
{
key
=
dc
.
join
(
group
,
nif
,
thisHost
);
try
{
dc
.
join
(
group
,
nif
);
throw
new
RuntimeException
(
"IllegalStateException not thrown"
);
}
catch
(
IllegalStateException
x
)
{
}
key
.
drop
();
}
catch
(
UnsupportedOperationException
x
)
{
}
// IllegalArgumentException
try
{
dc
.
join
(
notGroup
,
nif
);
throw
new
RuntimeException
(
"IllegalArgumentException not thrown"
);
}
catch
(
IllegalArgumentException
x
)
{
}
try
{
dc
.
join
(
notGroup
,
nif
,
thisHost
);
throw
new
RuntimeException
(
"IllegalArgumentException not thrown"
);
}
catch
(
IllegalArgumentException
x
)
{
}
catch
(
UnsupportedOperationException
x
)
{
}
// NullPointerException
try
{
dc
.
join
(
null
,
nif
);
throw
new
RuntimeException
(
"NullPointerException not thrown"
);
}
catch
(
NullPointerException
x
)
{
}
try
{
dc
.
join
(
group
,
null
);
throw
new
RuntimeException
(
"NullPointerException not thrown"
);
}
catch
(
NullPointerException
x
)
{
}
try
{
dc
.
join
(
group
,
nif
,
null
);
throw
new
RuntimeException
(
"NullPointerException not thrown"
);
}
catch
(
NullPointerException
x
)
{
}
catch
(
UnsupportedOperationException
x
)
{
}
dc
.
close
();
// ClosedChannelException
try
{
dc
.
join
(
group
,
nif
);
throw
new
RuntimeException
(
"ClosedChannelException not thrown"
);
}
catch
(
ClosedChannelException
x
)
{
}
try
{
dc
.
join
(
group
,
nif
,
thisHost
);
throw
new
RuntimeException
(
"ClosedChannelException not thrown"
);
}
catch
(
ClosedChannelException
x
)
{
}
catch
(
UnsupportedOperationException
x
)
{
}
}
/**
* Probe interfaces to get interfaces that support IPv4 or IPv6 multicasting
* and invoke tests.
*/
public
static
void
main
(
String
[]
args
)
throws
IOException
{
// multicast groups used for the test
InetAddress
ip4Group
=
InetAddress
.
getByName
(
"225.4.5.6"
);
InetAddress
ip6Group
=
InetAddress
.
getByName
(
"ff02::a"
);
NetworkConfiguration
config
=
NetworkConfiguration
.
probe
();
NetworkInterface
nif
=
config
.
ip4Interfaces
().
iterator
().
next
();
InetAddress
anySource
=
config
.
ip4Addresses
(
nif
).
iterator
().
next
();
membershipKeyTests
(
nif
,
ip4Group
,
anySource
);
exceptionTests
(
nif
);
// re-run the membership key tests with IPv6 if available
Iterator
<
NetworkInterface
>
iter
=
config
.
ip6Interfaces
().
iterator
();
if
(
iter
.
hasNext
())
{
nif
=
iter
.
next
();
anySource
=
config
.
ip6Addresses
(
nif
).
iterator
().
next
();
membershipKeyTests
(
nif
,
ip6Group
,
anySource
);
}
}
}
test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 4527345
* @summary Unit test for DatagramChannel's multicast support
* @build MulticastSendReceiveTests NetworkConfiguration
*/
import
java.nio.ByteBuffer
;
import
java.nio.channels.*
;
import
java.net.*
;
import
java.util.*
;
import
java.io.IOException
;
public
class
MulticastSendReceiveTests
{
static
Random
rand
=
new
Random
();
/**
* Send datagram from given local address to given multicast
* group.
*/
static
int
sendDatagram
(
InetAddress
local
,
NetworkInterface
nif
,
InetAddress
group
,
int
port
)
throws
IOException
{
ProtocolFamily
family
=
(
group
instanceof
Inet6Address
)
?
StandardProtocolFamily
.
INET6
:
StandardProtocolFamily
.
INET
;
DatagramChannel
dc
=
DatagramChannel
.
open
(
family
)
.
bind
(
new
InetSocketAddress
(
local
,
0
))
.
setOption
(
StandardSocketOption
.
IP_MULTICAST_IF
,
nif
);
int
id
=
rand
.
nextInt
();
byte
[]
msg
=
Integer
.
toString
(
id
).
getBytes
(
"UTF-8"
);
ByteBuffer
buf
=
ByteBuffer
.
wrap
(
msg
);
System
.
out
.
format
(
"Send message from %s -> group %s (id=0x%x)\n"
,
local
.
getHostAddress
(),
group
.
getHostAddress
(),
id
);
dc
.
send
(
buf
,
new
InetSocketAddress
(
group
,
port
));
dc
.
close
();
return
id
;
}
/**
* Wait (with timeout) for datagram.
*
* @param expectedSender - expected sender address, or
* null if no datagram expected
* @param id - expected id of datagram
*/
static
void
receiveDatagram
(
DatagramChannel
dc
,
InetAddress
expectedSender
,
int
id
)
throws
IOException
{
Selector
sel
=
Selector
.
open
();
dc
.
configureBlocking
(
false
);
dc
.
register
(
sel
,
SelectionKey
.
OP_READ
);
ByteBuffer
buf
=
ByteBuffer
.
allocateDirect
(
100
);
try
{
for
(;;)
{
System
.
out
.
println
(
"Waiting to receive message"
);
sel
.
select
(
5
*
1000
);
SocketAddress
sa
=
dc
.
receive
(
buf
);
// no datagram received
if
(
sa
==
null
)
{
if
(
expectedSender
!=
null
)
{
throw
new
RuntimeException
(
"Expected message not recieved"
);
}
System
.
out
.
println
(
"No message received (correct)"
);
return
;
}
// datagram received
InetAddress
sender
=
((
InetSocketAddress
)
sa
).
getAddress
();
buf
.
flip
();
byte
[]
bytes
=
new
byte
[
buf
.
remaining
()];
buf
.
get
(
bytes
);
int
receivedId
=
Integer
.
parseInt
(
new
String
(
bytes
));
System
.
out
.
format
(
"Received message from %s (id=0x%x)\n"
,
sender
,
receivedId
);
if
(
expectedSender
==
null
)
{
if
(
receivedId
==
id
)
throw
new
RuntimeException
(
"Message not expected"
);
System
.
out
.
println
(
"Message ignored (has wrong id)"
);
}
else
{
if
(
sender
.
equals
(
expectedSender
))
{
System
.
out
.
println
(
"Message expected"
);
return
;
}
System
.
out
.
println
(
"Message ignored (wrong sender)"
);
}
sel
.
selectedKeys
().
clear
();
buf
.
rewind
();
}
}
finally
{
sel
.
close
();
}
}
/**
* Exercise multicast send/receive on given group/interface
*/
static
void
test
(
NetworkInterface
nif
,
InetAddress
group
,
InetAddress
source
)
throws
IOException
{
ProtocolFamily
family
=
(
group
instanceof
Inet6Address
)
?
StandardProtocolFamily
.
INET6
:
StandardProtocolFamily
.
INET
;
System
.
out
.
format
(
"create channel to %s socket\n"
,
family
.
name
());
DatagramChannel
dc
=
DatagramChannel
.
open
(
family
)
.
setOption
(
StandardSocketOption
.
SO_REUSEADDR
,
true
)
.
bind
(
new
InetSocketAddress
(
0
));
// join group
System
.
out
.
format
(
"join %s @ %s\n"
,
group
.
getHostAddress
(),
nif
.
getName
());
MembershipKey
key
=
dc
.
join
(
group
,
nif
);
// send message to group
int
port
=
((
InetSocketAddress
)
dc
.
getLocalAddress
()).
getPort
();
int
id
=
sendDatagram
(
source
,
nif
,
group
,
port
);
// receive message and check id matches
receiveDatagram
(
dc
,
source
,
id
);
// exclude-mode filtering
try
{
System
.
out
.
format
(
"block %s\n"
,
source
.
getHostAddress
());
// may throw UOE
key
.
block
(
source
);
id
=
sendDatagram
(
source
,
nif
,
group
,
port
);
receiveDatagram
(
dc
,
null
,
id
);
// unblock source, send message, message should be received
System
.
out
.
format
(
"unblock %s\n"
,
source
.
getHostAddress
());
key
.
unblock
(
source
);
id
=
sendDatagram
(
source
,
nif
,
group
,
port
);
receiveDatagram
(
dc
,
source
,
id
);
}
catch
(
UnsupportedOperationException
x
)
{
System
.
out
.
println
(
"Exclude-mode filtering not supported!"
);
}
key
.
drop
();
// include-mode filtering
InetAddress
bogus
=
(
group
instanceof
Inet6Address
)
?
InetAddress
.
getByName
(
"fe80::1234"
)
:
InetAddress
.
getByName
(
"1.2.3.4"
);
System
.
out
.
format
(
"join %s @ %s only-source %s\n"
,
group
.
getHostAddress
(),
nif
.
getName
(),
bogus
.
getHostAddress
());
try
{
// may throw UOE
key
=
dc
.
join
(
group
,
nif
,
bogus
);
id
=
sendDatagram
(
source
,
nif
,
group
,
port
);
receiveDatagram
(
dc
,
null
,
id
);
System
.
out
.
format
(
"join %s @ %s only-source %s\n"
,
group
.
getHostAddress
(),
nif
.
getName
(),
source
.
getHostAddress
());
key
=
dc
.
join
(
group
,
nif
,
source
);
id
=
sendDatagram
(
source
,
nif
,
group
,
port
);
receiveDatagram
(
dc
,
source
,
id
);
}
catch
(
UnsupportedOperationException
x
)
{
System
.
out
.
println
(
"Include-mode filtering not supported!"
);
}
// done
dc
.
close
();
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
NetworkConfiguration
config
=
NetworkConfiguration
.
probe
();
// multicast groups used for the test
InetAddress
ip4Group
=
InetAddress
.
getByName
(
"225.4.5.6"
);
InetAddress
ip6Group
=
InetAddress
.
getByName
(
"ff02::a"
);
for
(
NetworkInterface
nif:
config
.
ip4Interfaces
())
{
InetAddress
source
=
config
.
ip4Addresses
(
nif
).
iterator
().
next
();
test
(
nif
,
ip4Group
,
source
);
}
for
(
NetworkInterface
nif:
config
.
ip6Interfaces
())
{
InetAddress
source
=
config
.
ip6Addresses
(
nif
).
iterator
().
next
();
test
(
nif
,
ip6Group
,
source
);
}
}
}
test/java/nio/channels/DatagramChannel/NetworkConfiguration.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import
java.net.*
;
import
java.util.*
;
import
java.io.IOException
;
/**
* Helper class for multicasting tests.
*/
class
NetworkConfiguration
{
private
Map
<
NetworkInterface
,
List
<
InetAddress
>>
ip4Interfaces
;
private
Map
<
NetworkInterface
,
List
<
InetAddress
>>
ip6Interfaces
;
private
NetworkConfiguration
(
Map
<
NetworkInterface
,
List
<
InetAddress
>>
ip4Interfaces
,
Map
<
NetworkInterface
,
List
<
InetAddress
>>
ip6Interfaces
)
{
this
.
ip4Interfaces
=
ip4Interfaces
;
this
.
ip6Interfaces
=
ip6Interfaces
;
}
Iterable
<
NetworkInterface
>
ip4Interfaces
()
{
return
ip4Interfaces
.
keySet
();
}
Iterable
<
NetworkInterface
>
ip6Interfaces
()
{
return
ip6Interfaces
.
keySet
();
}
Iterable
<
InetAddress
>
ip4Addresses
(
NetworkInterface
nif
)
{
return
ip4Interfaces
.
get
(
nif
);
}
Iterable
<
InetAddress
>
ip6Addresses
(
NetworkInterface
nif
)
{
return
ip6Interfaces
.
get
(
nif
);
}
static
NetworkConfiguration
probe
()
throws
IOException
{
Map
<
NetworkInterface
,
List
<
InetAddress
>>
ip4Interfaces
=
new
HashMap
<
NetworkInterface
,
List
<
InetAddress
>>();
Map
<
NetworkInterface
,
List
<
InetAddress
>>
ip6Interfaces
=
new
HashMap
<
NetworkInterface
,
List
<
InetAddress
>>();
// find the interfaces that support IPv4 and IPv6
List
<
NetworkInterface
>
nifs
=
Collections
.
list
(
NetworkInterface
.
getNetworkInterfaces
());
for
(
NetworkInterface
nif:
nifs
)
{
// ignore intertaces that are down or don't support multicast
if
(!
nif
.
isUp
()
||
!
nif
.
supportsMulticast
()
||
nif
.
isLoopback
())
continue
;
List
<
InetAddress
>
addrs
=
Collections
.
list
(
nif
.
getInetAddresses
());
for
(
InetAddress
addr:
addrs
)
{
if
(
addr
instanceof
Inet4Address
)
{
List
<
InetAddress
>
list
=
ip4Interfaces
.
get
(
nif
);
if
(
list
==
null
)
{
list
=
new
LinkedList
<
InetAddress
>();
}
list
.
add
(
addr
);
ip4Interfaces
.
put
(
nif
,
list
);
}
if
(
addr
instanceof
Inet6Address
)
{
List
<
InetAddress
>
list
=
ip6Interfaces
.
get
(
nif
);
if
(
list
==
null
)
{
list
=
new
LinkedList
<
InetAddress
>();
}
list
.
add
(
addr
);
ip6Interfaces
.
put
(
nif
,
list
);
}
}
}
return
new
NetworkConfiguration
(
ip4Interfaces
,
ip6Interfaces
);
}
}
test/java/nio/channels/DatagramChannel/SocketOptionTests.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 4640544
* @summary Unit test for setOption/getOption/options methods
*/
import
java.nio.*
;
import
java.nio.channels.*
;
import
java.net.*
;
import
java.io.IOException
;
import
java.util.*
;
import
static
java
.
net
.
StandardSocketOption
.*;
public
class
SocketOptionTests
{
static
<
T
>
void
checkOption
(
DatagramChannel
dc
,
SocketOption
<
T
>
name
,
T
expectedValue
)
throws
IOException
{
T
value
=
dc
.
getOption
(
name
);
if
(!
value
.
equals
(
expectedValue
))
throw
new
RuntimeException
(
"value not as expected"
);
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
DatagramChannel
dc
=
DatagramChannel
.
open
();
// check supported options
Set
<
SocketOption
<?>>
options
=
dc
.
options
();
List
<?
extends
SocketOption
<?>>
expected
=
Arrays
.
asList
(
SO_SNDBUF
,
SO_RCVBUF
,
SO_REUSEADDR
,
SO_BROADCAST
,
IP_TOS
,
IP_MULTICAST_IF
,
IP_MULTICAST_TTL
,
IP_MULTICAST_LOOP
);
for
(
SocketOption
opt:
expected
)
{
if
(!
options
.
contains
(
opt
))
throw
new
RuntimeException
(
opt
.
name
()
+
" should be supported"
);
}
// check specified defaults
checkOption
(
dc
,
SO_BROADCAST
,
false
);
checkOption
(
dc
,
IP_MULTICAST_TTL
,
1
);
// true on supported platforms
checkOption
(
dc
,
IP_MULTICAST_LOOP
,
true
);
// true on supported platforms
// allowed to change when not bound
dc
.
setOption
(
SO_BROADCAST
,
true
);
checkOption
(
dc
,
SO_BROADCAST
,
true
);
dc
.
setOption
(
SO_BROADCAST
,
false
);
checkOption
(
dc
,
SO_BROADCAST
,
false
);
dc
.
setOption
(
SO_SNDBUF
,
16
*
1024
);
// can't check
dc
.
setOption
(
SO_RCVBUF
,
16
*
1024
);
// can't check
dc
.
setOption
(
SO_REUSEADDR
,
true
);
checkOption
(
dc
,
SO_REUSEADDR
,
true
);
dc
.
setOption
(
SO_REUSEADDR
,
false
);
checkOption
(
dc
,
SO_REUSEADDR
,
false
);
// bind socket
dc
.
bind
(
new
InetSocketAddress
(
0
));
// allow to change when bound
dc
.
setOption
(
SO_BROADCAST
,
true
);
checkOption
(
dc
,
SO_BROADCAST
,
true
);
dc
.
setOption
(
SO_BROADCAST
,
false
);
checkOption
(
dc
,
SO_BROADCAST
,
false
);
dc
.
setOption
(
IP_TOS
,
0x08
);
// can't check
dc
.
setOption
(
IP_MULTICAST_TTL
,
2
);
checkOption
(
dc
,
IP_MULTICAST_TTL
,
2
);
dc
.
setOption
(
IP_MULTICAST_LOOP
,
false
);
checkOption
(
dc
,
IP_MULTICAST_LOOP
,
false
);
dc
.
setOption
(
IP_MULTICAST_LOOP
,
true
);
checkOption
(
dc
,
IP_MULTICAST_LOOP
,
true
);
// NullPointerException
try
{
dc
.
setOption
(
null
,
"value"
);
throw
new
RuntimeException
(
"NullPointerException not thrown"
);
}
catch
(
NullPointerException
x
)
{
}
try
{
dc
.
getOption
(
null
);
throw
new
RuntimeException
(
"NullPointerException not thrown"
);
}
catch
(
NullPointerException
x
)
{
}
// ClosedChannelException
dc
.
close
();
try
{
dc
.
setOption
(
IP_MULTICAST_LOOP
,
true
);
throw
new
RuntimeException
(
"ClosedChannelException not thrown"
);
}
catch
(
ClosedChannelException
x
)
{
}
}
}
test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 4640544
* @summary Unit test for ServerSocketChannel setOption/getOption/options
* methods.
*/
import
java.nio.*
;
import
java.nio.channels.*
;
import
java.net.*
;
import
java.io.IOException
;
import
java.util.*
;
import
static
java
.
net
.
StandardSocketOption
.*;
public
class
SocketOptionTests
{
static
void
checkOption
(
ServerSocketChannel
ssc
,
SocketOption
name
,
Object
expectedValue
)
throws
IOException
{
Object
value
=
ssc
.
getOption
(
name
);
if
(!
value
.
equals
(
expectedValue
))
throw
new
RuntimeException
(
"value not as expected"
);
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
ServerSocketChannel
ssc
=
ServerSocketChannel
.
open
();
// check supported options
Set
<
SocketOption
<?>>
options
=
ssc
.
options
();
if
(!
options
.
contains
(
SO_REUSEADDR
))
throw
new
RuntimeException
(
"SO_REUSEADDR should be supported"
);
if
(!
options
.
contains
(
SO_RCVBUF
))
throw
new
RuntimeException
(
"SO_RCVBUF should be supported"
);
// allowed to change when not bound
ssc
.
setOption
(
SO_RCVBUF
,
256
*
1024
);
// can't check
ssc
.
setOption
(
SO_REUSEADDR
,
true
);
checkOption
(
ssc
,
SO_REUSEADDR
,
true
);
ssc
.
setOption
(
SO_REUSEADDR
,
false
);
checkOption
(
ssc
,
SO_REUSEADDR
,
false
);
// NullPointerException
try
{
ssc
.
setOption
(
null
,
"value"
);
throw
new
RuntimeException
(
"NullPointerException not thrown"
);
}
catch
(
NullPointerException
x
)
{
}
try
{
ssc
.
getOption
(
null
);
throw
new
RuntimeException
(
"NullPointerException not thrown"
);
}
catch
(
NullPointerException
x
)
{
}
// ClosedChannelException
ssc
.
close
();
try
{
ssc
.
setOption
(
SO_REUSEADDR
,
true
);
throw
new
RuntimeException
(
"ClosedChannelException not thrown"
);
}
catch
(
ClosedChannelException
x
)
{
}
}
}
test/java/nio/channels/SocketChannel/SocketOptionTests.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 4640544
* @summary Unit test to check SocketChannel setOption/getOption/options
* methods.
*/
import
java.nio.*
;
import
java.nio.channels.*
;
import
java.net.*
;
import
java.io.IOException
;
import
java.util.*
;
import
static
java
.
net
.
StandardSocketOption
.*;
public
class
SocketOptionTests
{
static
void
checkOption
(
SocketChannel
sc
,
SocketOption
name
,
Object
expectedValue
)
throws
IOException
{
Object
value
=
sc
.
getOption
(
name
);
if
(!
value
.
equals
(
expectedValue
))
throw
new
RuntimeException
(
"value not as expected"
);
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
SocketChannel
sc
=
SocketChannel
.
open
();
// check supported options
Set
<
SocketOption
<?>>
options
=
sc
.
options
();
List
<?
extends
SocketOption
>
expected
=
Arrays
.
asList
(
SO_SNDBUF
,
SO_RCVBUF
,
SO_KEEPALIVE
,
SO_REUSEADDR
,
SO_LINGER
,
TCP_NODELAY
);
for
(
SocketOption
opt:
expected
)
{
if
(!
options
.
contains
(
opt
))
throw
new
RuntimeException
(
opt
.
name
()
+
" should be supported"
);
}
// check specified defaults
int
linger
=
sc
.<
Integer
>
getOption
(
SO_LINGER
);
if
(
linger
>=
0
)
throw
new
RuntimeException
(
"initial value of SO_LINGER should be < 0"
);
checkOption
(
sc
,
SO_KEEPALIVE
,
false
);
checkOption
(
sc
,
TCP_NODELAY
,
false
);
// allowed to change when not bound
sc
.
setOption
(
SO_KEEPALIVE
,
true
);
checkOption
(
sc
,
SO_KEEPALIVE
,
true
);
sc
.
setOption
(
SO_KEEPALIVE
,
false
);
checkOption
(
sc
,
SO_KEEPALIVE
,
false
);
sc
.
setOption
(
SO_SNDBUF
,
128
*
1024
);
// can't check
sc
.
setOption
(
SO_RCVBUF
,
256
*
1024
);
// can't check
sc
.
setOption
(
SO_REUSEADDR
,
true
);
checkOption
(
sc
,
SO_REUSEADDR
,
true
);
sc
.
setOption
(
SO_REUSEADDR
,
false
);
checkOption
(
sc
,
SO_REUSEADDR
,
false
);
sc
.
setOption
(
SO_LINGER
,
10
);
linger
=
sc
.<
Integer
>
getOption
(
SO_LINGER
);
if
(
linger
<
1
)
throw
new
RuntimeException
(
"expected linger to be enabled"
);
sc
.
setOption
(
SO_LINGER
,
-
1
);
linger
=
sc
.<
Integer
>
getOption
(
SO_LINGER
);
if
(
linger
>=
0
)
throw
new
RuntimeException
(
"expected linger to be disabled"
);
sc
.
setOption
(
TCP_NODELAY
,
true
);
checkOption
(
sc
,
TCP_NODELAY
,
true
);
sc
.
setOption
(
TCP_NODELAY
,
false
);
// can't check
// bind socket
sc
.
bind
(
new
InetSocketAddress
(
0
));
// allow to change when bound
sc
.
setOption
(
SO_KEEPALIVE
,
true
);
checkOption
(
sc
,
SO_KEEPALIVE
,
true
);
sc
.
setOption
(
SO_KEEPALIVE
,
false
);
checkOption
(
sc
,
SO_KEEPALIVE
,
false
);
sc
.
setOption
(
SO_LINGER
,
10
);
linger
=
sc
.<
Integer
>
getOption
(
SO_LINGER
);
if
(
linger
<
1
)
throw
new
RuntimeException
(
"expected linger to be enabled"
);
sc
.
setOption
(
SO_LINGER
,
-
1
);
linger
=
sc
.<
Integer
>
getOption
(
SO_LINGER
);
if
(
linger
>=
0
)
throw
new
RuntimeException
(
"expected linger to be disabled"
);
sc
.
setOption
(
TCP_NODELAY
,
true
);
// can't check
sc
.
setOption
(
TCP_NODELAY
,
false
);
// can't check
// NullPointerException
try
{
sc
.
setOption
(
null
,
"value"
);
throw
new
RuntimeException
(
"NullPointerException not thrown"
);
}
catch
(
NullPointerException
x
)
{
}
try
{
sc
.
getOption
(
null
);
throw
new
RuntimeException
(
"NullPointerException not thrown"
);
}
catch
(
NullPointerException
x
)
{
}
// ClosedChannelException
sc
.
close
();
try
{
sc
.
setOption
(
TCP_NODELAY
,
true
);
throw
new
RuntimeException
(
"ClosedChannelException not thrown"
);
}
catch
(
ClosedChannelException
x
)
{
}
}
}
test/java/nio/channels/TestUtil.java
浏览文件 @
ec347b32
...
@@ -38,7 +38,7 @@ public class TestUtil {
...
@@ -38,7 +38,7 @@ public class TestUtil {
// executing in a different network.
// executing in a different network.
public
static
final
String
HOST
=
"javaweb.sfbay.sun.com"
;
public
static
final
String
HOST
=
"javaweb.sfbay.sun.com"
;
public
static
final
String
REFUSING_HOST
=
"jano1.sfbay.sun.com"
;
public
static
final
String
REFUSING_HOST
=
"jano1.sfbay.sun.com"
;
public
static
final
String
FAR_HOST
=
"
theclub
.ireland.sun.com"
;
public
static
final
String
FAR_HOST
=
"
irejano
.ireland.sun.com"
;
public
static
final
String
UNRESOLVABLE_HOST
=
"blah-blah.blah-blah.blah"
;
public
static
final
String
UNRESOLVABLE_HOST
=
"blah-blah.blah-blah.blah"
;
private
TestUtil
()
{
}
private
TestUtil
()
{
}
...
@@ -102,5 +102,4 @@ public class TestUtil {
...
@@ -102,5 +102,4 @@ public class TestUtil {
static
boolean
onWindows
()
{
static
boolean
onWindows
()
{
return
osName
.
startsWith
(
"Windows"
);
return
osName
.
startsWith
(
"Windows"
);
}
}
}
}
test/java/nio/channels/etc/NetworkChannelTests.java
0 → 100644
浏览文件 @
ec347b32
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 4640544
* @summary Unit test for channels that implement NetworkChannel
*/
import
java.nio.*
;
import
java.nio.channels.*
;
import
java.net.*
;
import
java.io.IOException
;
import
java.util.*
;
public
class
NetworkChannelTests
{
static
interface
ChannelFactory
{
NetworkChannel
open
()
throws
IOException
;
}
static
class
BogusSocketAddress
extends
SocketAddress
{
}
/**
* Exercise bind method.
*/
static
void
bindTests
(
ChannelFactory
factory
)
throws
IOException
{
NetworkChannel
ch
;
// AlreadyBoundException
ch
=
factory
.
open
().
bind
(
new
InetSocketAddress
(
0
));
try
{
ch
.
bind
(
new
InetSocketAddress
(
0
));
throw
new
RuntimeException
(
"AlreadyBoundException not thrown"
);
}
catch
(
AlreadyBoundException
x
)
{
}
ch
.
close
();
// bind(null)
ch
=
factory
.
open
().
bind
(
null
);
if
(
ch
.
getLocalAddress
()
==
null
)
throw
new
RuntimeException
(
"socket not found"
);
ch
.
close
();
// UnsupportedAddressTypeException
ch
=
factory
.
open
();
try
{
ch
.
bind
(
new
BogusSocketAddress
());
throw
new
RuntimeException
(
"UnsupportedAddressTypeException not thrown"
);
}
catch
(
UnsupportedAddressTypeException
x
)
{
}
ch
.
close
();
// ClosedChannelException
try
{
ch
.
bind
(
new
InetSocketAddress
(
0
));
throw
new
RuntimeException
(
"ClosedChannelException not thrown"
);
}
catch
(
ClosedChannelException
x
)
{
}
}
/**
* Exercise getLocalAddress method.
*/
static
void
localAddressTests
(
ChannelFactory
factory
)
throws
IOException
{
NetworkChannel
ch
;
// not bound
ch
=
factory
.
open
();
if
(
ch
.
getLocalAddress
()
!=
null
)
{
throw
new
RuntimeException
(
"Local address returned when not bound"
);
}
// bound
InetSocketAddress
local
=
(
InetSocketAddress
)(
ch
.
bind
(
new
InetSocketAddress
(
0
)).
getLocalAddress
());
if
(!
local
.
getAddress
().
isAnyLocalAddress
())
{
if
(
NetworkInterface
.
getByInetAddress
(
local
.
getAddress
())
==
null
)
throw
new
RuntimeException
(
"not bound to local address"
);
}
if
(
local
.
getPort
()
<=
0
)
throw
new
RuntimeException
(
"not bound to local port"
);
// closed
ch
.
close
();
if
(
ch
.
getLocalAddress
()
!=
null
)
{
throw
new
RuntimeException
(
"Local address return when closed"
);
}
}
/**
* Exercise getConnectedAddress method (SocketChannel only)
*/
static
void
connectedAddressTests
()
throws
IOException
{
ServerSocketChannel
ssc
=
ServerSocketChannel
.
open
()
.
bind
(
new
InetSocketAddress
(
0
));
InetSocketAddress
local
=
(
InetSocketAddress
)(
ssc
.
getLocalAddress
());
int
port
=
local
.
getPort
();
InetSocketAddress
server
=
new
InetSocketAddress
(
InetAddress
.
getLocalHost
(),
port
);
SocketChannel
sc
=
SocketChannel
.
open
();
// not connected
if
(
sc
.
getConnectedAddress
()
!=
null
)
throw
new
RuntimeException
(
"getConnectedAddress returned address when not connected"
);
// connected
sc
.
connect
(
server
);
SocketAddress
remote
=
sc
.
getConnectedAddress
();
if
(!
remote
.
equals
(
server
))
throw
new
RuntimeException
(
"getConnectedAddress returned incorrect address"
);
// closed
sc
.
close
();
if
(
sc
.
getConnectedAddress
()
!=
null
)
throw
new
RuntimeException
(
"getConnectedAddress returned address when closed"
);
ssc
.
close
();
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
ChannelFactory
factory
;
// -- SocketChannel --
factory
=
new
ChannelFactory
()
{
public
NetworkChannel
open
()
throws
IOException
{
return
SocketChannel
.
open
();
}
};
bindTests
(
factory
);
localAddressTests
(
factory
);
connectedAddressTests
();
// -- ServerSocketChannel --
factory
=
new
ChannelFactory
()
{
public
NetworkChannel
open
()
throws
IOException
{
return
ServerSocketChannel
.
open
();
}
};
bindTests
(
factory
);
localAddressTests
(
factory
);
// backlog values
ServerSocketChannel
.
open
()
.
bind
(
new
InetSocketAddress
(
0
),
100
).
close
();
ServerSocketChannel
.
open
()
.
bind
(
new
InetSocketAddress
(
0
),
0
).
close
();
ServerSocketChannel
.
open
()
.
bind
(
new
InetSocketAddress
(
0
),
-
1
).
close
();
// -- DatagramChannel --
factory
=
new
ChannelFactory
()
{
public
NetworkChannel
open
()
throws
IOException
{
return
DatagramChannel
.
open
();
}
};
bindTests
(
factory
);
localAddressTests
(
factory
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录