友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第236章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




// clients; each of which sends datagrams。  

import java。lang。Thread;  

import java。*;  

import java。io。*;  

  

public class ChatterClient extends Thread {  

  // Can listen & send on the same socket:  

  private DatagramSocket s;  

  private InetAddress hostAddress;  

  private byte'' buf = new byte'1000';  

  private DatagramPacket dp =   

    new DatagramPacket(buf; buf。length);  

  private int id;  

  

  public ChatterClient(int identifier) {  

    id = identifier;  

    try {  

      // Auto…assign port number:  

      s = new DatagramSocket();  

      hostAddress =   

        InetAddress。getByName(〃localhost〃);  

    } catch(UnknownHostException e) {  

      System。err。println(〃Cannot find host〃);  

      System。exit(1);  

    } catch(SocketException e) {  

      System。err。println(〃Can't open socket〃);  

      e。printStackTrace();  

      System。exit(1);  

    }   

    System。out。println(〃ChatterClient starting〃);  

  }  

  public void run() {  

    try {  

      for(int i = 0; i 《 25; i++) {  

        String outMessage = 〃Client #〃 +  

          id + 〃; message #〃 + i;  



                                                                                          550 


…………………………………………………………Page 552……………………………………………………………

        // Make and send a datagram:  

        s。send(Dgram。toDatagram(outMessage;  

          hostAddress;   

          ChatterServer。INPORT));  

        // Block until it echoes back:  

        s。receive(dp);  

        // Print out the echoed contents:  

        String rcvd = 〃Client #〃 + id +  

          〃; rcvd from 〃 +   

          dp。getAddress() + 〃; 〃 +   

          dp。getPort() + 〃: 〃 +  

          Dgram。toString(dp);  

        System。out。println(rcvd);  

      }  

    } catch(IOException e) {  

      e。printStackTrace();  

      System。exit(1);  

    }  

  }  

  public static void main(String'' args) {  

    for(int i = 0; i 《 10; i++)  

      new ChatterClient(i)。start();  

  }  

} ///:~  

  

ChatterClient 被创建成一个线程(Thread),所以可以用多个客户来“骚扰”服务器。从中可以看到,用 

于接收的DatagramPacket 和用于 ChatterServer 的那个是相似的。在构建器中,创建DatagramPacket 时没 

有附带任何参数(自变量),因为它不需要明确指出自己位于哪个特定编号的端口里。用于这个套接字的因 

特网地址将成为“这台机器”(比如 localhost),而且会自动分配端口编号,这从输出结果即可看出。同 

用于服务器的那个一样,这个 DatagramPacket 将同时用于发送和接收。  

hostAddress 是我们想与之通信的那台机器的因特网地址。在程序中,如果需要创建一个准备传出去的 

DatagramPacket,那么必须知道一个准确的因特网地址和端口号。可以肯定的是,主机必须位于一个已知的 

地址和端口号上,使客户能启动与主机的“会话”。  

每个线程都有自己独一无二的标识号(尽管自动分配给线程的端口号是也会提供一个唯一的标识符)。在 

run()中,我们创建了一个String 消息,其中包含了线程的标识编号以及该线程准备发送的消息编号。我们 

用这个字串创建一个数据报,发到主机上的指定地址;端口编号则直接从 ChatterServer 内的一个常数取 

得。一旦消息发出,receive()就会暂时被“堵塞”起来,直到服务器回复了这条消息。与消息附在一起的所 

有信息使我们知道回到这个特定线程的东西正是从始发消息中投递出去的。在这个例子中,尽管是一种“不 

可靠”协议,但仍然能够检查数据报是否到去过了它们该去的地方(这在 localhost 和LAN 环境中是成立 

的,但在非本地连接中却可能出现一些错误)。  

运行该程序时,大家会发现每个线程都会结束。这意味着发送到服务器的每个数据报包都会回转,并反馈回 

正确的接收者。如果不是这样,一个或更多的线程就会挂起并进入“堵塞”状态,直到它们的输入被显露出 

来。  

大家或许认为将文件从一台机器传到另一台的唯一正确方式是通过TCP 套接字,因为它们是“可靠”的。然 

而,由于数据报的速度非常快,所以它才是一种更好的选择。我们只需将文件分割成多个数据报,并为每个 

包编号。接收机器会取得这些数据包,并重新“组装”它们;一个“标题包”会告诉机器应该接收多少个 

包,以及组装所需的另一些重要信息。如果一个包在半路“走丢”了,接收机器会返回一个数据报,告诉发 

送者重传。  



15。5 一个 Web 应用  



现在让我们想想如何创建一个应用,令其在真实的 Web 环境中运行,它将把Java 的优势表现得淋漓尽致。这 

个应用的一部分是在Web 服务器上运行的一个 Java 程序,另一部分则是一个“程序片”或“小应用程序” 



                                                                                  551 


…………………………………………………………Page 553……………………………………………………………

 (Applet),从服务器下载至浏览器(即“客户”)。这个程序片从用户那里收集信息,并将其传回Web 服 

务器上运行的应用程序。程序的任务非常简单:程序片会询问用户的 E…mail 地址,并在验证这个地址合格后 

 (没有包含空格,而且有一个@符号),将该 E…mail 发送给 Web 服务器。服务器上运行的程序则会捕获传回 

的数据,检查一个包含了所有E…mail 地址的数据文件。如果那个地址已包含在文件里,则向浏览器反馈一条 

消息,说明这一情况。该消息由程序片负责显示。若是一个新地址,则将其置入列表,并通知程序片已成功 

添加了电子函件地址。  

若采用传统方式来解决这个问题,我们要创建一个包含了文本字段及一个“提交”(Submit)按钮的HTML 

页。用户可在文本字段里键入自己喜欢的任何内容,并毫无阻碍地提交给服务器(在客户端不进行任何检 

查)。提交数据的同时,Web 页也会告诉服务器应对数据采取什么样的操作——知会“通用网关接口” 

 (CGI)程序,收到这些数据后立即运行服务器。这种CGI 程序通常是用 Perl 或C 写的(有时也用C++,但 

要求服务器支持),而且必须能控制一切可能出现的情况。它首先会检查数据,判断是否采用了正确的格 

式。若答案是否定的,则CGI 程序必须创建一个 HTML 页,对遇到的问题进行描述。这个页会转交给服务器, 

再由服务器反馈回用户。用户看到出错提示后,必须再试一遍提交,直到通过为止。若数据正确,CGI 程序 

会打开数据文件,要么把电子函件地址加入文件,要么指出该地址已在数据文件里了。无论哪种情况,都必 

须格式化一个恰当的HTML 页,以便服务器返回给用户。  

作为Java 程序员,上述解决问题的方法显得非常笨拙。而且很自然地,我们希望一切工作都用Java 完成。 

首先,我们会用一个Java 程序片负责客户端的数据有效性校验,避免数据在服务器和客户之间传来传去,浪 

费时间和带宽,同时减轻服务器额外构建HTML 页的负担。然后跳过Perl CGI 脚本,换成在服务器上运行一 

个Java 应用。事实上,我们在这儿已完全跳过了 Web 服务器,仅仅需要从程
返回目录 上一页 下一页 回到顶部 赞(1) 踩(1)
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!