📄 06-套接字编程(下3).htm
字号:
}A.navigater:hover { COLOR: #cc0000}.g1 { FONT-SIZE: 14px}.g2 { PADDING-LEFT: 21px; PADDING-TOP: 5px}.g3 { FONT-WEIGHT: bold; COLOR: #ab6503}.g4 { COLOR: #ff0000}.img { BORDER-RIGHT: #800000 1px solid; BORDER-TOP: #800000 1px solid; BORDER-LEFT: #800000 1px solid; BORDER-BOTTOM: #800000 1px solid}.img1 { BORDER-RIGHT: #000000 1px solid; BORDER-TOP: #000000 1px solid; BORDER-LEFT: #000000 1px solid; BORDER-BOTTOM: #000000 1px solid}.f14 { FONT-SIZE: 14px; LINE-HEIGHT: 26px}.f20 { FONT-WEIGHT: bold; FONT-SIZE: 20px}.top_red { COLOR: #d70709; TEXT-DECORATION: none}.center01 { COLOR: #000000; LINE-HEIGHT: 20px}.center01 TD { COLOR: #000000; LINE-HEIGHT: 20px}.center01 A:link { COLOR: #000000; TEXT-DECORATION: none}.center01 A:visited { COLOR: #000000; TEXT-DECORATION: none}.center01 A:hover { COLOR: #2b7128; TEXT-DECORATION: underline}.center02 { COLOR: #194e00; LINE-HEIGHT: 20px}.center02 TD { COLOR: #194e00; LINE-HEIGHT: 20px}.center02 A:link { COLOR: #194e00; TEXT-DECORATION: none}.center02 A:visited { COLOR: #194e00; TEXT-DECORATION: none}.center02 A:hover { COLOR: #194e00; TEXT-DECORATION: underline}--></style><TABLE width=760 border=0 align=center cellPadding=0 cellSpacing=0 bgcolor="#F3F3F3" valign="top"> <tr class="center01"> <td width="488" style="padding-left:10px;padding-top:10px"> <a href="index.php">连载</a> > <a href="slist.php?class1=6">程序设计</a> > <a href="slist.php?class2=7">Java</a> > <a href="serialize.php?id=387">Java网络编程专辑</a> </td> <td width="280" style="padding-left:10px;padding-top:10px"> <div align="center"> <font color=#0000FF><a href='chapter.php?id=387&volume=3&chapter=5'>上一页</a></font> <font color=#0000FF><a href="serialize.php?id=387">回书目</a></font> <font color=#0000FF><a href='chapter.php?id=387&volume=3&chapter=7'>下一页</a></font> </div> </td> </tr> <tr class="center01"> <td colspan="2" align="center" style="padding-left:10px;padding-top:10px"> </td> </tr> <TBODY> <TR> <TD colspan="2" align=middle> <BR> <div style="FONT-SIZE: 18pt; COLOR: #990000; FONT-FAMILY: 楷体_GB2312" align=center><B>Socket套接字</b></div><br><div style="COLOR: #990000; font-family: ; font-size: 18px;宋体;" align=center>Java套接字编程(下3)</div> <DIV style="PADDING-RIGHT: 10px; PADDING-LEFT: 10px; FONT-SIZE: 10.5pt; COLOR: black; LINE-HEIGHT: 180%" align=left> <br> <P><STRONG><FONT color=#f70909>多点传送和MulticastSocket类</FONT></STRONG><BR><BR> 前面的例子显示了服务器程序线程发送单一的消息(通过流套接字或自寻址套接字)给唯一的客户端程序,这种行为被称为单点传送(unicasting),多数情况都不适合于单点传送,比如,摇滚歌手举办一场音乐会将通过互联网进行播放,画面和声音的质量依赖于传输速度,服务器程序要传送大约10亿字节的数据给客户端程序,使用单点传送,那么每个客户程序都要要复制一份数据,如果,互联网上有10000个客户端要收看这个音乐会,那么服务器程序通过Internet要传送10000G的数据,这必然导致网络阻塞,降低网络的传输速度。<BR><BR> 如果服务器程序要将同一信息发送给多个客户端,那么服务器程序和客户程序可以利用多点传送(multicasting)方式进行通信。多点传送就是服务程序对专用的多点传送组的IP地址和端口发送一系列自寻址数据包,通过加入操作IP地址被多点传送Socket注册,通过这个点客户程序可以接收发送给组的自寻址包(同样客户程序也可以给这个组发送自寻址包),一旦客户程序读完所有要读的自寻址数据包,那么可以通过离开组操作离开多点传送组。<BR><BR> 注意:IP地址224.0.0.1 到 239.255.255.255(包括)均为保留的多点传送组地址。<BR><BR> 网络API通过MulticastSocket类和MulticastSocket,以及一些辅助类(比如NetworkInterface)支持多点传送,当一个客户程序要加入多点传送组时,就创建一个MulticastSocket对象。MulticastSocket(int port)构造函数允许应用程序指定端口(通过port参数)接收自寻址包,端口必须与服务程序的端口号相匹配,要加入多点传送组,客户程序调用两个joinGroup()方法中的一个,同样要离开传送组,也要调用两个leaveGroup()方法中的一个。<BR><BR> 由于MulticastSocket扩展了DatagramSocket类,一个MulticastSocket对象就有权访问DatagramSocket方法。<BR><BR> List6是MCClient的源代码,这段代码示范了一个客户端加入多点传送组的例子。<BR><BR></P>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>Listing 6: MCClient.java<BR>// MCClient.java<BR><BR>import java.io.*;<BR>import java.net.*;<BR><BR>class MCClient<BR>{<BR> public static void main (String [] args) throws IOException<BR> {<BR> // Create a MulticastSocket bound to local port 10000. All<BR> // multicast packets from the server program are received<BR> // on that port.<BR><BR> MulticastSocket s = new MulticastSocket (10000);<BR><BR> // Obtain an InetAddress object that contains the multicast<BR> // group address 231.0.0.1. The InetAddress object is used by<BR> // DatagramPacket.<BR><BR> InetAddress group = InetAddress.getByName ("231.0.0.1");<BR><BR> // Join the multicast group so that datagram packets can be<BR> // received.<BR><BR> s.joinGroup (group);<BR><BR> // Read several datagram packets from the server program.<BR><BR> for (int i = 0; i < 10; i++)<BR> {<BR> // No line will exceed 256 bytes.<BR><BR> byte [] buffer = new byte [256];<BR><BR> // The DatagramPacket object needs no addressing<BR> // information because the socket contains the address.<BR><BR> DatagramPacket dgp = new DatagramPacket (buffer,<BR> buffer.length);<BR><BR> // Receive a datagram packet.<BR><BR> s.receive (dgp);<BR><BR> // Create a second byte array with a length that matches<BR> // the length of the sent data.<BR><BR> byte [] buffer2 = new byte [dgp.getLength ()];<BR><BR> // Copy the sent data to the second byte array.<BR><BR> System.arraycopy (dgp.getData (),<BR> 0,<BR> buffer2,<BR> 0,<BR> dgp.getLength ());<BR><BR> // Print the contents of the second byte array. (Try<BR> // printing the contents of buffer. You will soon see why<BR> // buffer2 is used.)<BR><BR> System.out.println (new String (buffer2));<BR> }<BR><BR> // Leave the multicast group.<BR><BR> s.leaveGroup (group);<BR><BR> // Close the socket.<BR><BR> s.close ();<BR> }<BR>}</TD></TR></TBODY></TABLE><BR> MCClient创建了一个绑定端口号10000的MulticastSocket对象,接下来他获得了一个InetAddress子类对象,该子类对象包含多点传送组的IP地址231.0.0.0,然后通过joinGroup(InetAddress addr)方法加入多点传送组中,接下来MCClient接收10个自寻址包,同时输出他们的内容,然后使用leaveGroup(InetAddress addr)方法离开传送组,最后关闭套接字。<BR><BR> 也许你对使用两个字节数组buffer 和 buffer2感到奇怪,当接收到一个自寻址包后,getData()方法返回一个引用,自寻址包的长度是256个字节,如果要输出所有数据,在输出完实际数据后会有很多空格,这显然是不合理的,所以我们必须去掉这些空格,因此我们创建一个小的字节数组buffer2,buffer2的实际长度就是数据的实际长度,通过调用DatagramPacket's getLength()方法来得到这个长度。从buffer 到 buffer2快速复制getLength()的长度的方法是调用System.arraycopy()方法。<BR><BR> List7 MCServer的源代码显示了服务程序是怎样工作的。<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>Listing 7: MCServer.java<BR>// MCServer.java<BR><BR>import java.io.*;<BR>import java.net.*;<BR><BR>class MCServer<BR>{<BR> public static void main (String[] args) throws IOException<BR> {<BR> System.out.println ("Server starting...\n"); <BR><BR> // Create a MulticastSocket not bound to any port.<BR><BR> MulticastSocket s = new MulticastSocket ();<BR><BR> // Because MulticastSocket subclasses DatagramSocket, it is<BR> // legal to replace MulticastSocket s = new MulticastSocket ();<BR> // with the following line.<BR><BR>
<SCRIPT language=Javascript>document.write("<img src='http://counter.yesky.com/servlet/counter.counter?CID=72348977504190464&AID=1601474&refer="+escape(document.referrer)+"&cur="+escape(document.URL)+"' border='0' alt='' width='0' height='0'>");</SCRIPT>
<IMG height=0 alt="" src="http://counter.yesky.com/servlet/counter.counter?CID=72348977504190464&AID=1601474&refer=http%3A//www.yesky.com/SoftChannel/72342371961929728/20030110/1647918_1.shtml&cur=http%3A//www.yesky.com/SoftChannel/72342371961929728/20030110/1647918_2.shtml" width=0 border=0> // DatagramSocket s = new DatagramSocket ();<BR><BR> // Obtain an InetAddress object that contains the multicast<BR> // group address 231.0.0.1. The InetAddress object is used by<BR> // DatagramPacket.<BR><BR> InetAddress group = InetAddress.getByName ("231.0.0.1");<BR><BR> // Create a DatagramPacket object that encapsulates a reference<BR> // to a byte array (later) and destination address<BR> // information. The destination address consists of the<BR> // multicast group address (as stored in the InetAddress object)<BR> // and port number 10000 -- the port to which multicast datagram<BR> // packets are sent. (Note: The dummy array is used to prevent a<BR> // NullPointerException object being thrown from the<BR> // DatagramPacket constructor.)<BR><BR> byte [] dummy = new byte [0];<BR><BR> DatagramPacket dgp = new DatagramPacket (dummy,<BR> 0,<BR> group,<BR> 10000);<BR><BR> // Send 30000 Strings to the port.<BR><BR> for (int i = 0; i < 30000; i++)<BR> {<BR> // Create an array of bytes from a String. The platform's<BR> // default character set is used to convert from Unicode<BR> // characters to bytes.<BR><BR> byte [] buffer = ("Video line " + i).getBytes ();<BR><BR> // Establish the byte array as the datagram packet's<BR> // buffer.<BR><BR> dgp.setData (buffer);<BR><BR> // Establish the byte array's length as the length of the<BR> // datagram packet's buffer.<BR><BR> dgp.setLength (buffer.length);<BR><BR> // Send the datagram to all members of the multicast group<BR> // that listen on port 10000.<BR><BR> s.send (dgp);<BR> }<BR><BR> // Close the socket.<BR><BR> s.close ();<BR> }<BR>} </TD></TR></TBODY></TABLE><BR> MCServer创建了一个MulticastSocket对象,由于他是DatagramPacket对象的一部分,所以他没有绑定端口号,DatagramPacket有多点传送组的IP地址(231.0.0.0),一旦创建DatagramPacket对象,MCServer就进入一个发送30000条的文本的循环中,对文本的每一行均要创建一个字节数组,他们的引用均存储在前面创建的DatagramPacket对象中,通过send()方法,自寻址包发送给所有的组成员。<BR><BR> 在编译了MCServer 和 MCClient后,通过输入java MCServer开始运行MCServer,最后再运行一个或多个MCClient。<BR><BR> <B><FONT color=#ac000>结论</FONT></B><BR><BR> 本文通过研究套接字揭示了Java的网络API的应用方法,我们介绍了套接自的慨念和套接字的组成,以及流套接字和自寻址套接字,以及如何使用InetAddress, Socket, ServerSocket, DatagramPacket, DatagramSocket和MulticastSocket类。在完成本文后就可以编写基本的底层通讯程序。<br><br> </DIV> </TD> </TR> <TR> <TD class=center01> <div align="center">来源:天极网 作者:<div> </TD> <TD width="280" class=center01> <div align="center"> <font color=#0000FF><a href='chapter.php?id=387&volume=3&chapter=5'>上一页</a></font> <font color=#0000FF><a href="serialize.php?id=387">回书目</a></font> <font color=#0000FF><a href='chapter.php?id=387&volume=3&chapter=7'>下一页</a></font> </div> </TD> </TR> </TBODY></TABLE><table><tr><td width="760"> <table width="760" height="10" border="0" cellpadding="0" cellspacing="0"> <tr> <td></td> </tr> </table> <!------------ 评论 ----------------> <table width="760" border="0" cellpadding="0" cellspacing="0"> <tr> <td><iframe width="100%" id=vs frameborder=0 scrolling=no src="comment_list1.php?id=387"></iframe> </td> </tr> </table><br><script language=javascript>function CheckNetwordForm(theForm){ if("" == theForm.content.value) { alert("写两句吧~~"); theForm.content.focus(); return false; } var index; for(index=0;index<theForm.content.value.length;index++) { if(" " != theForm.content.value.charAt(index)) break; } if(index == theForm.content.value.length) { alert("写两句吧~~"); theForm.content.focus(); return false; } if (theForm.content.value.length>100){ alert("评论字数不能超过100哦"); theForm.content.focus(); return false; } return true;}</script> <!------------------ 评论 ---------------> <form name=netword method=post action="insertnetword.php" onsubmit="javascript: return CheckNetwordForm(this);"> <table width="760" border="0" cellpadding="0" cellspacing="0"> <tr> <td height="25" class="text6"> 给此书打分:<a name="1"></a> <select name="score"> <option value=5 selected>非常好</option> <option value=4>还凑合</option> <option value=3>一般吧</option> <option value=2>不太行</option> <option value=1>太差了</option> </select> 用户名: <input name="id" value=387 type="hidden" id="id"> <input name="backurl" value=/book/chapter.php?id=387&volume=3&chapter=6 type="hidden"> <input name="username" type="text" id="username" size="20" maxlength="20"> <font color="#666666">*评论字数请控制在一百字以内</font> </td> </tr> </table> <br> <textarea name="content" cols="80" rows="4" wrap="OFF" id="description"></textarea> <input type="submit" name="Submit" value="提交"> </form> </td> </tr></table></td></tr></table> <TABLE cellSpacing=0 cellPadding=0 width=760 border=0> <TBODY> <TR> <TD width="1003" height=9 background=images/t_bj01.gif><IMG height=1 src="images/ccc.gif" width=1></TD> </TR> </TBODY></TABLE><TABLE cellSpacing=0 cellPadding=0 width=760 bgColor=#ffffff border=0> <TBODY> <TR> <TD><HR width=760 noShade SIZE=1> </TD> </TR> <TR> <TD align=middle><A class=black href="http://www.chinaren.com/" target=_blank>ChinaRen</A> - <A class=black href="http://big5.www.sohu.com/" target=_blank>繁体版</A> - <A class=black href="http://hr.sohu.com/hrm.html" target=_blank>搜狐招聘</A> - <A class=black href="http://add.sohu.com/" target=_blank>网站登录</A> - <A class=black href="http://help.sohu.com/" target=_blank>帮助中心</A> - <A class=black href="http://book.news.sohu.com/onClick=this.style.behavior='url(#default#homepage)';this.setHomePage('http://www.sohu.com');return" target=_blank false;>设置首页</A> - <A class=black href="http://adinfo.sohu.com/" target=_blank>广告服务</A> - <A class=black href="http://www.sohu.com/about/lianxi.htm" target=_blank>联系方式</A> - <A class=black href="http://www.sohu.com/about/privacy.html" target=_blank>保护隐私权</A> - <A class=black href="http://www.sohu.com/about/" target=_blank>About SOHU</A> - <A class=black href="http://www.sohu.com/about/" target=_blank>公司介绍</A><BR> <SPAN class=eng>Copyright © 2004 Sohu.com Inc. All rights reserved. 搜狐公司 版权所有</SPAN> </TD> </TR> </TBODY></TABLE></center></body></html><script language="JavaScript" src="http://nielsen.js.sohu.com/nnselect.js"></script><noscript><img src='http://ping.nnselect.com/ping.gif?c=119' height='1' width='1'></noscript>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -