ServerSocket
java.lang.Object
|—java.net.ServerSocket
public class ServerSocket
extends Object
implements Closeable
此类实现服务器套接字。 服务器套接字等待通过网络进入的请求。 它根据该请求执行一些操作,然后可能将结果返回给请求者。
服务器套接字的实际工作由 SocketImpl 类的实例执行。 应用程序可以更改创建套接字实现的套接字工厂,以将其自身配置为创建适合本地防火墙的套接字。
构造函数摘要
构造函数 | 描述 |
---|---|
ServerSocket() | 创建一个未绑定的服务器套接字。 |
ServerSocket(int port) | 创建一个绑定到指定端口的服务器套接字。 |
ServerSocket(int port, int backlog) | 创建一个服务器套接字并将其绑定到指定的本地端口号,并具有指定的 backlog。 |
ServerSocket(int port, int backlog, InetAddress bindAddr) | 创建具有指定端口、侦听积压和要绑定的本地 IP 地址的服务器。 |
方法总结
修饰符和类型 | 方法 | 描述 |
---|---|---|
Socket | accept() | 侦听要与此套接字建立的连接并接受它。 |
void | bind(SocketAddress endpoint) | 将 ServerSocket 绑定到特定地址(IP 地址和端口号)。 |
void | bind(SocketAddress endpoint, int backlog) | 将 ServerSocket 绑定到特定地址(IP 地址和端口号)。 |
void | close() | 关闭此套接字。 |
ServerSocketChannel | getChannel() | 返回与此套接字关联的唯一 ServerSocketChannel 对象(如果有)。 |
InetAddress | getInetAddress() | 返回此服务器套接字的本地地址。 |
int | getLocalPort() | 返回此套接字正在侦听的端口号。 |
SocketAddress | getLocalSocketAddress() | 返回此套接字绑定到的端点的地址。 |
int | getReceiveBufferSize() | 获取此 ServerSocket 的 SocketOptions#SO_RCVBUF 选项的值,即用于从该 ServerSocket 接受的套接字的建议缓冲区大小。 |
boolean | getReuseAddress() | 测试 SocketOptions#SO_REUSEADDR 是否启用。 |
int | getSoTimeout() | 检索 SocketOptions#SO_TIMEOUT 的设置。 |
protected void | implAccept(Socket s) | ServerSocket 的子类使用此方法覆盖 accept() 以返回它们自己的套接字子类。 |
boolean | isBound() | 返回 ServerSocket 的绑定状态。 |
boolean | isClosed() | 返回 ServerSocket 的关闭状态。 |
void | setPerformancePreferences(int connectionTime, int latency, int bandwidth) | 设置此 ServerSocket 的性能首选项。 |
void | setReceiveBufferSize(int size) | 为从此 ServerSocket 接受的套接字设置 SocketOptions#SO_RCVBUF 选项的默认建议值。 |
void | setReuseAddress(boolean on) | 启用/禁用 SocketOptions#SO_REUSEADDR 套接字选项。 |
static void | setSocketFactory(SocketImplFactory fac) | 为应用程序设置服务器套接字实现工厂。 |
void | setSoTimeout(int timeout) | 使用指定的超时启用/禁用 SocketOptions#SO_TIMEOUT,以毫秒为单位。 |
String | toString() | 以 String 形式返回此套接字的实现地址和实现端口。 |
从类 java.lang.Object 继承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
构造函数详细信息
ServerSocket
public ServerSocket() throws IOException
创建一个未绑定的服务器套接字。
Throws:
Throw名称 | Throw描述 |
---|---|
IOException | 打开套接字时出现 IO 错误。 |
ServerSocket
public ServerSocket(int port) throws IOException
创建一个绑定到指定端口的服务器套接字。 端口号 0 表示端口号是自动分配的,通常来自临时端口范围。 然后可以通过调用 getLocalPort 检索此端口号。
传入连接指示(连接请求)的最大队列长度设置为 50。如果在队列已满时连接指示到达,则拒绝连接。
如果应用程序指定了服务器套接字工厂,则调用该工厂的 createSocketImpl 方法来创建实际的套接字实现。 否则会创建一个“普通”套接字。
如果有安全管理器,则调用其 checkListen 方法,并将端口参数作为其参数,以确保允许该操作。 这可能会导致 SecurityException。
参数:
参数名称 | 参数描述 |
---|---|
port | 端口号,或 0 使用自动分配的端口号。 |
Throws:
Throw名称 | Throw描述 |
---|---|
IOException | 如果在打开套接字时发生 I/O 错误。 |
SecurityException | 如果安全管理器存在并且其 checkListen 方法不允许该操作。 |
IllegalArgumentException | 如果端口参数超出指定的有效端口值范围,即介于 0 和 65535 之间(包括 0 和 65535)。 |
ServerSocket
public ServerSocket(int port, int backlog) throws IOException
创建一个服务器套接字并将其绑定到指定的本地端口号,并具有指定的 backlog。端口号 0 表示端口号是自动分配的,通常来自临时端口范围。然后可以通过调用 getLocalPort 检索此端口号。
传入连接指示(连接请求)的最大队列长度设置为 backlog 参数。如果队列满时有连接指示到达,则拒绝连接。
如果应用程序指定了服务器套接字工厂,则调用该工厂的 createSocketImpl 方法来创建实际的套接字实现。否则会创建一个“普通”套接字。
如果有安全管理器,则调用其 checkListen 方法,并将端口参数作为其参数,以确保允许该操作。这可能会导致 SecurityException。 backlog 参数是套接字上请求的最大挂起连接数。它的确切语义是特定于实现的。特别地,实现可以强加最大长度或者可以选择完全忽略参数。提供的值应大于 0。如果小于或等于 0,则将使用特定于实现的默认值。
参数:
参数名称 | 参数描述 |
---|---|
port | 端口号,或 0 使用自动分配的端口号。 |
backlog | 请求的传入连接队列的最大长度。 |
Throws:
Throw名称 | Throw描述 |
---|---|
IOException | 如果在打开套接字时发生 I/O 错误。 |
SecurityException | 如果安全管理器存在并且其 checkListen 方法不允许该操作。 |
IllegalArgumentException | 如果端口参数超出指定的有效端口值范围,即介于 0 和 65535 之间(包括 0 和 65535)。 |
ServerSocket
public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException
创建具有指定端口、侦听积压和要绑定的本地 IP 地址的服务器。 bindAddr 参数可用于多宿主主机上的 ServerSocket,它只接受对其地址之一的连接请求。如果 bindAddr 为空,它将默认接受任何/所有本地地址上的连接。端口必须介于 0 和 65535 之间(包括 0 和 65535)。端口号 0 表示端口号是自动分配的,通常来自临时端口范围。然后可以通过调用 getLocalPort 检索此端口号。
如果有安全管理器,则此方法调用其 checkListen 方法,并将端口参数作为其参数,以确保允许该操作。这可能会导致 SecurityException。 backlog 参数是套接字上请求的最大挂起连接数。它的确切语义是特定于实现的。特别地,实现可以强加最大长度或者可以选择完全忽略参数。提供的值应大于 0。如果小于或等于 0,则将使用特定于实现的默认值。
参数:
参数名称 | 参数描述 |
---|---|
port | 端口号,或 0 使用自动分配的端口号。 |
backlog | 请求的传入连接队列的最大长度。 |
bindAddr | 服务器将绑定到的本地 InetAddress |
Throws:
Throw名称 | Throw描述 |
---|---|
SecurityException | 如果安全管理器存在并且其 checkListen 方法不允许该操作。 |
IOException | 如果在打开套接字时发生 I/O 错误。 |
IllegalArgumentException | 如果端口参数超出指定的有效端口值范围,即介于 0 和 65535 之间(包括 0 和 65535)。 |
方法详情
bind
public void bind(SocketAddress endpoint) throws IOException
将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
如果地址为空,那么系统将选择一个临时端口和一个有效的本地地址来绑定套接字。
参数:
参数名称 | 参数描述 |
---|---|
endpoint | 要绑定的 IP 地址和端口号。 |
Throws:
Throw名称 | Throw描述 |
---|---|
IOException | 如果绑定操作失败,或者套接字已经绑定。 |
SecurityException | 如果存在 SecurityManager 并且其 checkListen 方法不允许该操作。 |
IllegalArgumentException | 如果端点是此套接字不支持的 SocketAddress 子类 |
bind
public void bind(SocketAddress endpoint, int backlog) throws IOException
将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
如果地址为空,那么系统将选择一个临时端口和一个有效的本地地址来绑定套接字。
backlog 参数是套接字上请求的最大挂起连接数。 它的确切语义是特定于实现的。 特别地,实现可以强加最大长度或者可以选择完全忽略参数。 提供的值应大于 0。如果小于或等于 0,则将使用特定于实现的默认值。
参数:
参数名称 | 参数描述 |
---|---|
endpoint | 要绑定的 IP 地址和端口号。 |
backlog | 请求的传入连接队列的最大长度。 |
Throws:
Throw名称 | Throw描述 |
---|---|
IOException | 如果绑定操作失败,或者套接字已经绑定。 |
SecurityException | 如果存在 SecurityManager 并且其 checkListen 方法不允许该操作。 |
IllegalArgumentException | 如果端点是此套接字不支持的 SocketAddress 子类 |
getInetAddress
public InetAddress getInetAddress()
返回此服务器套接字的本地地址。
如果socket在关闭之前就绑定了,那么这个方法会在socket关闭后继续返回本地地址。
如果设置了安全管理器,则使用本地地址和 -1 作为其参数调用其 checkConnect 方法,以查看是否允许该操作。 如果不允许该操作,则返回 InetAddress#getLoopbackAddress 地址。
返回:
此套接字绑定到的地址,如果安全管理器拒绝,则返回环回地址,如果套接字未绑定,则返回 null。
getLocalPort
public int getLocalPort()
返回此套接字正在侦听的端口号。
如果套接字在关闭之前已绑定,则此方法将在套接字关闭后继续返回端口号。
返回:
此套接字正在侦听的端口号,如果尚未绑定套接字,则为 -1。
getLocalSocketAddress
public SocketAddress getLocalSocketAddress()
返回此套接字绑定到的端点的地址。
如果套接字在关闭之前已绑定,则该方法将在套接字关闭后继续返回端点的地址。
如果设置了安全管理器,则使用本地地址和 -1 作为其参数调用其 checkConnect 方法,以查看是否允许该操作。 如果不允许该操作,则返回代表 InetAddress#getLoopbackAddress 地址和套接字绑定的本地端口的 SocketAddress。
返回:
表示此套接字的本地端点的 SocketAddress,如果安全管理器拒绝,则表示环回地址的 SocketAddress,如果尚未绑定套接字,则返回 null。
accept
public Socket accept() throws IOException
侦听要与此套接字建立的连接并接受它。 该方法阻塞,直到建立连接。
创建一个新的 Socket s,如果有安全管理器,则使用 s.getInetAddress().getHostAddress() 和 s.getPort() 作为其参数调用安全管理器的 checkAccept 方法,以确保允许操作。 这可能会导致 SecurityException。
返回:
新的 Socket
Throws:
Throw名称 | Throw描述 |
---|---|
IOException | 如果在等待连接时发生 I/O 错误。 |
SecurityException | 如果存在安全管理器并且其 checkAccept 方法不允许该操作。 |
SocketTimeoutException | 如果先前使用 setSoTimeout 设置了超时并且已达到超时。 |
IllegalBlockingModeException | 如果此套接字有关联的通道,则通道处于非阻塞模式,并且没有准备好接受的连接 |
implAccept
protected final void implAccept(Socket s) throws IOException
ServerSocket 的子类使用此方法覆盖 accept() 以返回它们自己的套接字子类。 所以 FooServerSocket 通常会给这个方法一个空的 FooSocket。 从 implAccept 返回时,FooSocket 将连接到客户端。
参数:
参数名称 | 参数描述 |
---|---|
s | 套接字 |
Throws:
Throw名称 | Throw描述 |
---|---|
IllegalBlockingModeException | 如果此套接字具有关联的通道,并且该通道处于非阻塞模式 |
IOException | 如果在等待连接时发生 I/O 错误。 |
close
public void close() throws IOException
关闭此套接字。 当前在 accept() 中阻塞的任何线程都会抛出 SocketException。
如果此套接字具有关联的通道,则该通道也将关闭。
指定者:
在接口 AutoCloseable 中关闭
指定者:
在接口Closeable中关闭
Throws:
Throw名称 | Throw描述 |
---|---|
IOException | 如果关闭套接字时发生 I/O 错误。 |
getChannel
public ServerSocketChannel getChannel()
返回与此套接字关联的唯一 ServerSocketChannel 对象(如果有)。
当且仅当通道本身是通过 ServerSocketChannel.open 方法创建时,服务器套接字才会有通道。
返回:
与此套接字关联的服务器套接字通道,如果此套接字不是为通道创建的,则为 null
isBound
public boolean isBound()
返回 ServerSocket 的绑定状态。
返回:
如果 ServerSocket 成功绑定到地址,则为 true
isClosed
public boolean isClosed()
返回 ServerSocket 的关闭状态。
返回:
如果套接字已关闭,则为 true
setSoTimeout
public void setSoTimeout(int timeout) throws SocketException
使用指定的超时启用/禁用 SocketOptions#SO_TIMEOUT,以毫秒为单位。 将此选项设置为非零超时,对此 ServerSocket 的 accept() 调用将仅阻塞此时间量。 如果超时到期,则会引发 java.net.SocketTimeoutException,尽管 ServerSocket 仍然有效。 必须在进入阻塞操作之前启用该选项才能生效。 超时必须 > 0。超时为零被解释为无限超时。
参数:
参数名称 | 参数描述 |
---|---|
timeout | 指定的超时时间,以毫秒为单位 |
Throws:
Throw名称 | Throw描述 |
---|---|
SocketException | 如果底层协议有错误,例如 TCP 错误。 |
getSoTimeout
public int getSoTimeout() throws IOException
检索 SocketOptions#SO_TIMEOUT 的设置。 返回 0 表示该选项被禁用(即无限超时)。
返回:
SocketOptions#SO_TIMEOUT 值
Throws:
Throw名称 | Throw描述 |
---|---|
IOException | 如果发生 I/O 错误 |
setReuseAddress
public void setReuseAddress(boolean on) throws SocketException
启用/禁用 SocketOptions#SO_REUSEADDR 套接字选项。
当 TCP 连接关闭时,连接可能会在连接关闭后的一段时间内保持超时状态(通常称为 TIME_WAIT 状态或 2MSL 等待状态)。 对于使用众所周知的套接字地址或端口的应用程序,如果存在涉及套接字地址或端口的处于超时状态的连接,则可能无法将套接字绑定到所需的 SocketAddress。
在使用 bind(java.net.SocketAddress) 绑定套接字之前启用 SocketOptions#SO_REUSEADDR 允许绑定套接字,即使先前的连接处于超时状态。
创建 ServerSocket 时,未定义 SocketOptions#SO_REUSEADDR 的初始设置。 应用程序可以使用 getReuseAddress() 来确定 SocketOptions#SO_REUSEADDR 的初始设置。
未定义套接字绑定后启用或禁用 SocketOptions#SO_REUSEADDR 时的行为。
参数:
参数名称 | 参数描述 |
---|---|
on | 是否启用或禁用套接字选项 |
Throws:
Throw名称 | Throw描述 |
---|---|
SocketException | 如果启用或禁用 SocketOptions#SO_REUSEADDR 套接字选项发生错误,或者套接字已关闭。 |
getReuseAddress
public boolean getReuseAddress() throws SocketException
测试 SocketOptions#SO_REUSEADDR 是否启用。
返回:
一个布尔值,指示是否启用 SocketOptions#SO_REUSEADDR。
Throws:
Throw名称 | Throw描述 |
---|---|
SocketException | 如果底层协议有错误,例如 TCP 错误。 |
toString
public String toString()
以 String 形式返回此套接字的实现地址和实现端口。
如果设置了安全管理器,则使用本地地址和 -1 作为其参数调用其 checkConnect 方法,以查看是否允许该操作。 如果不允许该操作,则返回一个表示 InetAddress#getLoopbackAddress 地址的 InetAddress 作为实现地址。
覆盖:
类 Object 中的 toString
返回:
此套接字的字符串表示形式。
setSocketFactory
public static void setSocketFactory(SocketImplFactory fac) throws IOException
为应用程序设置服务器套接字实现工厂。 工厂只能指定一次。
当应用程序创建新的服务器套接字时,会调用套接字实现工厂的 createSocketImpl 方法来创建实际的套接字实现。
除非已经设置了工厂,否则将 null 传递给方法是无操作的。
如果有安全管理器,该方法首先调用安全管理器的 checkSetFactory 方法,确保操作被允许。 这可能会导致 SecurityException。
参数:
参数名称 | 参数描述 |
---|---|
fac | 想要的工厂。 |
Throws:
Throw名称 | Throw描述 |
---|---|
IOException | 如果设置套接字工厂时发生 I/O 错误。 |
SocketException | 如果工厂已经定义。 |
SecurityException | 如果存在安全管理器并且其 checkSetFactory 方法不允许该操作。 |
setReceiveBufferSize
public void setReceiveBufferSize(int size) throws SocketException
为从此 ServerSocket 接受的套接字设置 SocketOptions#SO_RCVBUF 选项的默认建议值。在接受的套接字中实际设置的值必须在接受()返回套接字后通过调用Socket#getReceiveBufferSize()来确定。
SocketOptions#SO_RCVBUF 的值既用于设置内部套接字接收缓冲区的大小,也用于设置通告给远程对等方的 TCP 接收窗口的大小。
随后可以通过调用 Socket#setReceiveBufferSize(int) 来更改该值。但是,如果应用程序希望允许大于 64K 字节的接收窗口(如 RFC1323 所定义),则必须在 ServerSocket 中设置建议的值,然后才能将其绑定到本地地址。这意味着,必须使用无参数构造函数创建 ServerSocket,然后必须调用 setReceiveBufferSize(),最后通过调用 bind() 将 ServerSocket 绑定到地址。
不这样做不会导致错误,并且缓冲区大小可能会设置为请求的值,但从该 ServerSocket 接受的套接字中的 TCP 接收窗口将不大于 64K 字节。
参数:
参数名称 | 参数描述 |
---|---|
size | 设置接收缓冲区大小的大小。 该值必须大于 0。 |
Throws:
Throw名称 | Throw描述 |
---|---|
SocketException | 如果底层协议有错误,例如 TCP 错误。 |
IllegalArgumentException | 如果值为 0 或为负数。 |
getReceiveBufferSize
public int getReceiveBufferSize() throws SocketException
获取此 ServerSocket 的 SocketOptions#SO_RCVBUF 选项的值,即用于从该 ServerSocket 接受的套接字的建议缓冲区大小。
注意,在接受的套接字中实际设置的值是通过调用 Socket#getReceiveBufferSize() 确定的。
返回:
此 Socket 的 SocketOptions#SO_RCVBUF 选项的值。
Throws:
Throw名称 | Throw描述 |
---|---|
SocketException | 如果底层协议有错误,例如 TCP 错误。 |
setPerformancePreferences
public void setPerformancePreferences(int connectionTime, int latency, int bandwidth)
设置此 ServerSocket 的性能首选项。
套接字默认使用 TCP/IP 协议。一些实现可能会提供与 TCP/IP 具有不同性能特征的替代协议。此方法允许应用程序表达自己的偏好,即当实现从可用协议中进行选择时应如何进行这些权衡。
性能偏好由三个整数描述,其值表示短连接时间、低延迟和高带宽的相对重要性。整数的绝对值无关紧要;为了选择一个协议,这些值被简单地比较,较大的值表示更强的偏好。例如,如果应用程序更喜欢短连接时间而不是低延迟和高带宽,那么它可以使用值 (1, 0, 0) 调用此方法。如果应用程序更喜欢高带宽而不是低延迟,以及低延迟而不是短连接时间,那么它可以使用值 (0, 1, 2) 调用此方法。
绑定此套接字后调用此方法将无效。这意味着为了使用此功能,需要使用无参数构造函数创建套接字。
参数:
参数名称 | 参数描述 |
---|---|
connectionTime | 表示短连接时间的相对重要性的 int |
latency | 一个表示低延迟相对重要性的 int |
bandwidth | 表示高带宽相对重要性的 int |