设为首页 收藏本站
查看: 1938|回复: 0

[经验分享] Java网络编程从入门到精通(28):获取ServerSocket信息的方法及FTP原理

[复制链接]

尚未签到

发表于 2016-6-11 07:21:01 | 显示全部楼层 |阅读模式
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4</xml><![endif]--><!--[if gte mso 9]><![endif]--><!--[if !mso]><style>st1":*{behavior:url(#ieooui) }</style><![endif]--><style><!--/* Font Definitions */&#64;font-face{font-family:Wingdings;panose-1:5 0 0 0 0 0 0 0 0 0;}&#64;font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;}&#64;font-face{font-family:""&#64;宋体";panose-1:2 1 6 0 3 1 1 1 1 1;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;font-size:10.5pt;font-family:"Times New Roman";}/* Page Definitions */&#64;page{}&#64;page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;}div.Section1{page:Section1;}/* List Definitions */&#64;list l0{}&#64;list l0:level1{margin-left:21.0pt;text-indent:-21.0pt;font-family:Wingdings;}&#64;list l0:level2{margin-left:39.75pt;text-indent:-18.75pt;}ol{margin-bottom:0cm;}ul{margin-bottom:0cm;}--></style><!--[if gte mso 10]><style>/* Style Definitions */table.MsoNormalTable{mso-style-parent:"";font-size:10.0pt;font-family:"Times New Roman";}</style><![endif]-->本文为原创,如需转载,请注明作者和出处,谢谢!
  上一篇:Java网络编程从入门到精通(27):关闭服务端连接
  
与ServerSocket对象相关的信息有两个:绑定端口和绑定IP地址。绑定端口可以通过getLocalPort方法获得。绑定IP地址可以通过getInetAddress方法获得。
  一、getLocalPort方法
getLocalPort方法的返回值可分为以下三种情况:
1.ServerSocket对象未绑定端口,getLocalPort方法的返回值为-1。
2.ServerSocket对象绑定了一个固定的端口,getLocalPort方法返回这个固定端口。
3.ServerSocket对象的绑定端口为0,getLocalPort方法返回一个随机的端口(这类端口被称为匿名端口)。
getLocalPort方法的定义如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->publicintgetLocalPort()

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4</xml><![endif]--><!--[if gte mso 9]><![endif]--><style><!--/* Font Definitions */&#64;font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;}&#64;font-face{font-family:""&#64;宋体";panose-1:2 1 6 0 3 1 1 1 1 1;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;font-size:10.5pt;font-family:"Times New Roman";}/* Page Definitions */&#64;page{}&#64;page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;}div.Section1{page:Section1;}--></style><!--[if gte mso 10]><style>/* Style Definitions */table.MsoNormalTable{mso-style-parent:"";font-size:10.0pt;font-family:"Times New Roman";}</style><![endif]-->getLocalPort方法主要是为这些匿名端口而准备的。下面的代码演示了ServerSocket对象产生随机端口的过程:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->package server;

importjava.net.*;

publicclassRandomPort
{
publicstaticvoidmain(String[]args)throwsException
{
for(inti=1;i<=5;i++)
{
System.out.print(
"RandomPort"+i+"");
System.out.println(
newServerSocket(0).getLocalPort());
}
}
}

运行结果:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4</xml><![endif]--><!--[if gte mso 9]><![endif]--><style><!--{cps..13}</style>
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->RandomPort1:1397
RandomPort2:
1398
RandomPort3:
1399
RandomPort4:
1400
RandomPort5:
1401

在大多数时候ServerSocket对象都会绑定一个固定的端口。但有时客户端只需要和服务端进行短暂的连接,这时就可以使用匿名端口。如我们经常用的FTP服务就是如此。
FTP服务器一般分为两种工作模式:主动模式(Port模式)和被动模式(PASV模式)。在这里主动和被动都是指FTP服务器。
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4</xml><![endif]--><!--[if gte mso 9]><![endif]--><style><!--/* Font Definitions */&#64;font-face{font-family:Wingdings;panose-1:5 0 0 0 0 0 0 0 0 0;}&#64;font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;}&#64;font-face{font-family:""&#64;宋体";panose-1:2 1 6 0 3 1 1 1 1 1;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;font-size:10.5pt;font-family:"Times New Roman";}/* Page Definitions */&#64;page{}&#64;page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;}div.Section1{page:Section1;}/* List Definitions */&#64;list l0{}&#64;list l0:level1{margin-left:21.0pt;text-indent:-21.0pt;font-family:Wingdings;}ol{margin-bottom:0cm;}ul{margin-bottom:0cm;}--></style><!--[if gte mso 10]><style>/* Style Definitions */table.MsoNormalTable{mso-style-parent:"";font-size:10.0pt;font-family:"Times New Roman";}</style><![endif]-->
1. 主动模式
在主动模式中,FTP服务器绑定了两个端口:21和20 (这两个端口是默认值,可以设成别的端口)。其中21端口负责客户端和服务器之间的命令传送。一开始,由客户端主动连接服务端的21端口,并且向服务器发送相应的FTP命令。另外一个端口20是负责客户端和服务端的数据传送。但要注意,并不是客户端主动连接服务端的20端口,而是在客户端创建一个使用匿名端口的服务端连接(在Java中就是创建一个ServerSocket对象,并且绑定端口是0)。然后客户端通过21端口将这个匿名端口通知服务端。最后,服务端主动连接客户端的这个匿名端口(所以这种模式叫主动模式,就是服务器主动连接客户端)。图1描述主动模式的工作原理。
http://seara.iyunv.com/images/blogjava_net/nokiaguy/ftp_1.jpg

图1 主动模式的工作原理



<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4</xml><![endif]--><!--[if gte mso 9]><![endif]--><style><!--/* Font Definitions */&#64;font-face{font-family:Wingdings;panose-1:5 0 0 0 0 0 0 0 0 0;}&#64;font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;}&#64;font-face{font-family:""&#64;宋体";panose-1:2 1 6 0 3 1 1 1 1 1;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;font-size:10.5pt;font-family:"Times New Roman";}/* Page Definitions */&#64;page{}&#64;page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;}div.Section1{page:Section1;}/* List Definitions */&#64;list l0{}&#64;list l0:level1{margin-left:21.0pt;text-indent:-21.0pt;font-family:Wingdings;}ol{margin-bottom:0cm;}ul{margin-bottom:0cm;}--></style><!--[if gte mso 10]><style>/* Style Definitions */table.MsoNormalTable{mso-style-parent:"";font-size:10.0pt;font-family:"Times New Roman";}</style><![endif]-->从图1可以看出,在主动模式中,在传送命令和数据时,建立连接的过程是相反的。也就是说,在传送命令时,由客户端主动连接服务器的21端口。而传送数据时,由服务器主动连接客户端的匿名端口。这种方式是FTP服务器最初的工作模式,但这种模式有很大的局限性。如客户端通过代理上网,而且未做端口映射。在这种情况下,服务端是无法主动和客户端建立连接的。因此,这就产生的另一种模式:被动模式。
2. 被动模式
被动模式和主动模式在传送命令的方式上是一样的。它们的区别就在于数据的传输上。被动模式在建立命令传输通道后,服务端建立一个绑定到匿名端口的ServerSocket对象。并通过命令传输通道将这个匿名端口通知客户端,然后由客户端主动连接服务端的这个匿名端口。这对于服务端就是被动的,因此,这种模式叫被动模式。图2描述了被动模式的工作原理。

http://seara.iyunv.com/images/blogjava_net/nokiaguy/ftp_2.jpg

图2 被动模式的工作原理

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4</xml><![endif]--><!--[if gte mso 9]><![endif]--><!--[if !mso]><style>st1":*{behavior:url(#ieooui) }</style><![endif]--><style><!--/* Font Definitions */&#64;font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;}&#64;font-face{font-family:""&#64;宋体";panose-1:2 1 6 0 3 1 1 1 1 1;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;font-size:10.5pt;font-family:"Times New Roman";}/* Page Definitions */&#64;page{}&#64;page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;}div.Section1{page:Section1;}--></style><!--[if gte mso 10]><style>/* Style Definitions */table.MsoNormalTable{mso-style-parent:"";font-size:10.0pt;font-family:"Times New Roman";}</style><![endif]-->现在的大多数FTP客户端软件的默认工作模式都是被动模式。因此,这种模式可以克服防火墙等的限制,并且客户端不需要有固定IP。但这种模式也有它的缺点,这就是在服务端要为客户开大量的端口(大多数FTP服务器开的端口范围是1024 ~ 5000,但有的服务器的范围达到1024 ~ 65535)。这对于服务器来说存在着一定的安全隐患。因此,如果可能的话,最好还是采用主动模式。
  二、getInetAddress方法
getInetAddress可以得到ServerSocket对象绑定的IP地址。如果ServerSocket对象未绑定IP地址,返回0.0.0.0。getInetAddress方法的定义如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->publicInetAddressgetInetAddress()
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4</xml><![endif]--><!--[if gte mso 9]><![endif]--><style><!--/* Font Definitions */&#64;font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;}&#64;font-face{font-family:""&#64;宋体";panose-1:2 1 6 0 3 1 1 1 1 1;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;font-size:10.5pt;font-family:"Times New Roman";}/* Page Definitions */&#64;page{}&#64;page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;}div.Section1{page:Section1;}--></style><!--[if gte mso 10]><style>/* Style Definitions */table.MsoNormalTable{mso-style-parent:"";font-size:10.0pt;font-family:"Times New Roman";}</style><![endif]-->
下面的代码演示了getInetAddress的使用方法:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->ServerSocketserverSocket=newServerSocket();
serverSocket.bind(
newInetSocketAddress("192.168.18.100",0));
System.out.println(serverSocket.getInetAddress().getHostAddress());


运行结果:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->192.168.18.100

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4</xml><![endif]--><!--[if gte mso 9]><![endif]--><!--[if !mso]><style>st1":*{behavior:url(#ieooui) }</style><![endif]--><style><!--/* Font Definitions */&#64;font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;}&#64;font-face{font-family:""&#64;宋体";panose-1:2 1 6 0 3 1 1 1 1 1;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;font-size:10.5pt;font-family:"Times New Roman";}/* Page Definitions */&#64;page{}&#64;page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;}div.Section1{page:Section1;}--></style><!--[if gte mso 10]><style>/* Style Definitions */table.MsoNormalTable{mso-style-parent:"";font-size:10.0pt;font-family:"Times New Roman";}</style><![endif]-->  三、getLocalSocketAddress方法
这个方法其实是将getLocalPort和getInetAddress方法的功能集成到了一起。也就是说,使用getLocalSocketAddress方法可以同时得到绑定端口和绑定IP地址。这个方法返回了一个SocketAddress对象。SocketAddress类是一个抽象类,要想分别得到端口和IP地址,必须将SocketAddress对象转换成InetSocketAddress对象(InetSocketAddress类是从SocketAddress类继承的)。getLocalSocketAddress方法的定义如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->publicSocketAddressgetLocalSocketAddress()

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4</xml><![endif]--><!--[if gte mso 9]><![endif]--><style><!--/* Font Definitions */&#64;font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;}&#64;font-face{font-family:""&#64;宋体";panose-1:2 1 6 0 3 1 1 1 1 1;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;font-size:10.5pt;font-family:"Times New Roman";}/* Page Definitions */&#64;page{}&#64;page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;}div.Section1{page:Section1;}--></style><!--[if gte mso 10]><style>/* Style Definitions */table.MsoNormalTable{mso-style-parent:"";font-size:10.0pt;font-family:"Times New Roman";}</style><![endif]-->下面的代码演示了getLocalSocketAddress的使用方法。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> ServerSocketserverSocket=newServerSocket();
serverSocket.bind(
newInetSocketAddress("192.168.18.100",1234));
System.out.println(serverSocket.getLocalSocketAddress());
InetSocketAddressnsa
=(InetSocketAddress)serverSocket.getLocalSocketAddress();
System.out.println(nsa.getAddress().getHostAddress());
System.out.println(nsa.getPort());

运行结果:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->/192.168.18.100:1234
192.168.18.100
1234


下一篇:Java网络编程从入门到精通(29):服务端Socket的选项


国内最棒的Google Android技术社区(eoeandroid),欢迎访问!

《银河系列原创教程》发布

《Java Web开发速学宝典》出版,欢迎定购

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-228821-1-1.html 上篇帖子: 万能Url正则表达式[http,ftp,news,telnet.....]——史上最全Url正则表达式(基于RFC1738‏ 下篇帖子: 阿里云服务器环境配置(挂载数据盘、swap分区、FTP服务器、JDK、Tomcat7)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表