与ServerSocket对象相关的信息有两个绑定端口和绑定IP地址绑定端口可以通过getLocalPort方法获得绑定IP地址可以通过getInetAddress方法获得
一getLocalPort方法
getLocalPort方法的返回值可分为以下三种情况
ServerSocket对象未绑定端口getLocalPort方法的返回值为
ServerSocket对象绑定了一个固定的端口getLocalPort方法返回这个固定端口
ServerSocket对象的绑定端口为getLocalPort方法返回一个随机的端口(这类端口被称为匿名端口)
getLocalPort方法的定义如下
publicintgetLocalPort()
getLocalPort方法主要是为这些匿名端口而准备的下面的代码演示了ServerSocket对象产生随机端口的过程
package server;
import*;
publicclassRandomPort
{
publicstaticvoidmain(String[]args)throwsException
{
for(inti=;i<=;i++)
{
Systemoutprint(RandomPort+i+);
Systemoutprintln(newServerSocket()getLocalPort());
}
}
}
运行结果
主动模式
在主动模式中FTP服务器绑定了两个端口和 (这两个端口是默认值可以设成别的端口)其中端口负责客户端和服务器之间的命令传送一开始由客户端主动连接服务端的端口并且向服务器发送相应的FTP命令另外一个端口是负责客户端和服务端的数据传送但要注意并不是客户端主动连接服务端的端口而是在客户端创建一个使用匿名端口的服务端连接(在Java中就是创建一个ServerSocket对象并且绑定端口是)然后客户端通过端口将这个匿名端口通知服务端最后服务端主动连接客户端的这个匿名端口(所以这种模式叫主动模式就是服务器主动连接客户端)图描述主动模式的工作原理
图 主动模式的工作原理
从图可以看出在主动模式中在传送命令和数据时建立连接的过程是相反的也就是说在传送命令时由客户端主动连接服务器的端口而传送数据时由服务器主动连接客户端的匿名端口这种方式是FTP服务器最初的工作模式但这种模式有很大的局限性如客户端通过代理上网而且未做端口映射在这种情况下服务端是无法主动和客户端建立连接的因此这就产生的另一种模式被动模式
被动模式
被动模式和主动模式在传送命令的方式上是一样的它们的区别就在于数据的传输上被动模式在建立命令传输通道后服务端建立一个绑定到匿名端口的ServerSocket对象并通过命令传输通道将这个匿名端口通知客户端然后由客户端主动连接服务端的这个匿名端口这对于服务端就是被动的因此这种模式叫被动模式图描述了被动模式的工作原理
图 被动模式的工作原理
现在的大多数FTP客户端软件的默认工作模式都是被动模式因此这种模式可以克服防火墙等的限制并且客户端不需要有固定IP但这种模式也有它的缺点这就是在服务端要为客户开大量的端口(大多数FTP服务器开的端口范围是 ~ 但有的服务器的范围达到 ~ )这对于服务器来说存在着一定的安全隐患因此如果可能的话最好还是采用主动模式
二getInetAddress方法
getInetAddress可以得到ServerSocket对象绑定的IP地址如果ServerSocket对象未绑定IP地址返回getInetAddress方法的定义如下
publicInetAddressgetInetAddress()
下面的代码演示了getInetAddress的使用方法
ServerSocketserverSocket=newServerSocket();
serverSocketbind(newInetSocketAddress());
Systemoutprintln(serverSocketgetInetAddress()getHostAddress());
运行结果
三getLocalSocketAddress方法
这个方法其实是将getLocalPort和getInetAddress方法的功能集成到了一起也就是说使用getLocalSocketAddress方法可以同时得到绑定端口和绑定IP地址这个方法返回了一个SocketAddress对象SocketAddress类是一个抽象类要想分别得到端口和IP地址必须将SocketAddress对象转换成InetSocketAddress对象(InetSocketAddress类是从SocketAddress类继承的)getLocalSocketAddress方法的定义如下
publicSocketAddressgetLocalSocketAddress()
下面的代码演示了getLocalSocketAddress的使用方法
ServerSocketserverSocket=newServerSocket();
serverSocketbind(newInetSocketAddress());
Systemoutprintln(serverSocketgetLocalSocketAddress());
InetSocketAddressnsa=(InetSocketAddress)serverSocketgetLocalSocketAddress();
Systemoutprintln(nsagetAddress()getHostAddress());
Systemoutprintln(nsagetPort());
运行结果
/: