📄 right8_3_13.htm
字号:
<html><head><title>JAVA编程语言</title><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><link rel="stylesheet" href="../../../css/text.css" type="text/css"></head><body bgcolor="#FFFFFF" text="#000000" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" ><table width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF"> <tr> <td valign="top"> <table width="97%" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center"> <tr> <td height="244" valign="top"> <p class="pt9-black"> <span class="zhongdian">1. 客户方程序 QuoteClient.java<a name="01"></a></span><br> <br> import java.io.*;<br> import java.net.*;<br> import java.util.*;<br> public class QuoteClient {<br> public static void main(String[] args) throws IOException <br> {<br> if(args.length!=1) { <br> <font color="339900">//如果启动的时候没有给出Server的名字,那么出错退出</font><br> System.out.println("Usage:java QuoteClient <hostname>"); <br> <font color="339900">//打印出错信息</font><br> return; <font color="339900">//返回</font><br> }</p> <p class="pt9-black"> DatagramSocket socket=new DatagramSocklet(); <br> <font color="339900">//创建数据报套接字</font></p> <p class="pt9-black"> Byte[] buf=new byte[256]; <font color="339900">//创建缓冲区</font><br> InetAddress address=InetAddress.getByName(args [0]); <br> <font color="339900">//由命令行给出的第一个参数默认为Server的名字,通过它得到Server的IP信息</font><br> DatagramPacket packet=new DatagramPacket (buf, buf.length, address, 4445);<br> <font color="339900">//创建DatagramPacket对象</font><br> socket.send(packet); <font color="339900">//发送</font><br> packet=new DatagramPacket(buf,buf.length); <br> <font color="339900">//创建新的DatagramPacket对象,用来接收数据报</font><br> socket.receive(packet); <font color="339900">//接收</font><br> String received=new String(packet.getData()); <br> <font color="339900">//根据接收到的字节数组生成相应的字符串</font><br> System.out.println("Quote of the Moment:"+received ); <br> <font color="339900">//打印生成的字符串</font></p> <p class="pt9-black"> socket.close(); <font color="339900">//关闭套接口</font><br> }<br> }</p> <p class="pt9-black"><span class="zhongdian"> 2. 服务器方程序:QuoteServer.java<a name="02"></a></span><br> <br> public class QuoteServer{<br> public static void main(String args[]) throws java.io.IOException <br> {<br> new QuoteServerThread().start(); <br> <font color="339900">//启动一个QuoteServerThread线程</font><br> }<br> }</p> <p class="pt9-black"> <span class="zhongdian">3. 程序QuoteServerThread.java<a name="03"></a></span><br> <br> import java.io.*;<br> import java.net.*;<br> import java.util.*;<br> <font color="339900">//服务器线程</font><br> public class QuoteServerThread extends Thread<br> {<br> protected DatagramSocket socket=null; <br> <font color="339900">//记录和本对象相关联的DatagramSocket对象</font><br> protected BufferedReader in=null; <br> <font color="339900">//用来读文件的一个Reader</font><br> protected boolean moreQuotes=true; <br> <font color="339900">//标志变量,是否继续操作</font></p> <p class="pt9-black"> public QuoteServerThread() throws IOException { <br> <font color="339900">//无参数的构造函数</font><br> this("QuoteServerThread"); <br> <font color="339900">//以QuoteServerThread为默认值调用带参数的构造函数</font><br> }<br> public QuoteServerThread(String name) throws IOException {<br> super(name); <font color="339900">//调用父类的构造函数</font><br> socket=new DatagramSocket(4445); <br> <font color="339900">//在端口4445创建数据报套接字</font><br> try{<br> in= new BufferedReader(new FileReader(" one-liners.txt"));<br> <font color="339900">//打开一个文件,构造相应的BufferReader对象</font><br> }catch(FileNotFoundException e) { <font color="339900">//异常处理</font><br> System.err.println("Could not open quote file. Serving time instead."); <br> <font color="339900">//打印出错信息</font><br> }<br> }<br> public void run() <font color="339900">//线程主体</font><br> {<br> while(moreQuotes) {<br> try{<br> byte[] buf=new byte[256]; <font color="339900">//创建缓冲区</font><br> DatagramPacket packet=new DatagramPacket(buf,buf.length);<br> <font color="339900">//由缓冲区构造DatagramPacket对象</font><br> socket.receive(packet); <font color="339900">//接收数据报</font><br> String dString=null;<br> if(in= =null) dString=new Date().toString(); <br> <font color="339900">//如果初始化的时候打开文件失败了,<br> //则使用日期作为要传送的字符串</font><br> else dString=getNextQuote(); <br> <font color="339900">//否则调用成员函数从文件中读出字符串</font><br> buf=dString.getByte(); <br> <font color="339900">//把String转换成字节数组,以便传送</font></p> <p class="pt9-black"> InetAddress address=packet.getAddress(); <br> <font color="339900">//从Client端传来的Packet中得到Client地址</font><br> int port=packet.getPort(); <font color="339900">//和端口号</font><br> packet=new DatagramPacket(buf,buf.length,address,port); <br> //根据客户端信息构建DatagramPacket<br> socket.send(packet); <font color="339900">//发送数据报</font><br> }catch(IOException e) { <font color="339900">//异常处理</font><br> e.printStackTrace(); <font color="339900">//打印错误栈</font><br> moreQuotes=false; <font color="339900">//标志变量置false,以结束循环</font><br> }<br> }<br> socket.close(); <font color="339900">//关闭数据报套接字</font><br> }</p> <p><span class="pt9-black"> protected String getNextQuotes(){ <br> <font color="339900">//成员函数,从文件中读数据</font><br> String returnValue=null;<br> try {<br> if((returnValue=in.readLine())= =null) { <br> <font color="339900">//从文件中读一行,如果读到了文件尾</font><br> in.close( ); <font color="339900">//关闭输入流</font><br> moreQuotes=false; <br> <font color="339900">//标志变量置false,以结束循环</font><br> returnValue="No more quotes. Goodbye."; <br> <font color="339900">//置返回值</font><br> } <font color="339900">//否则返回字符串即为从文件读出的字符串</font><br> }catch(IOEception e) { <font color="339900">//异常处理</font><br> returnValue="IOException occurred in server"; <br> <font color="339900">//置异常返回值</font><br> }<br> return returnValue; <font color="339900">//返回字符串</font><br> }<br> }<br> <br> <font color="000099">可以看出使用UDP和使用TCP在程序上还是有很大的区别的。一个比较明显的区别是,UDP的Socket编程是不提供监听功能的,也就是说通信双方更为平等,面对的接口是完全一样的。但是为了用UDP实现C/S结构,在使用UDP时可以使用DatagramSocket.receive()来实现类似于监听的功能。因为receive()是阻塞的函数,当它返回时,缓冲区里已经填满了接受到的一个数据报,并且可以从该数据报得到发送方的各种信息,这一点跟accept()是很相象的,因而可以根据读入的数据报来决定下一步的动作,这就达到了跟网络监听相似的效果。</font></span><br> </p> </td> </tr> </table> </td> </tr></table></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -