楼主: lastwinner

[转载] JAVA应用程序设计开发

[复制链接]
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
41#
 楼主| 发表于 2006-6-28 04:29 | 只看该作者
10.2 java.applet包

10.2.1 Applet类
  Applet类是所有Applet类的父类。它有一个缺省的无参构造函数,但一般不用。

  Applet类所提供的方法有22个。

  (1)有关运行环境和Applet状态的方法 

原型 注释
public AppletContext getAppletContext() 用以得到与Applet有关的上下文(AppletContext)对象。此方法与访问Applet的执行环境有关。
public void resize(int width,int height) 重新设置Applet所在区域的大小。该方法重写了Component类的resize()方法。它还有一个重载方法。
public void resize(Demesion d)  
public void showStatus(String msg) 用Applet的上下文(如执行它的浏览器)来显示Applet的状态信息
public final void setStub(Applet Stub) 用来设置与Applet相关的“存根”AppletStub。除非你要构造自己的Applet浏览器,否则不要使用它。由final修饰符可知这个方法是不可重写的。
public Locale getLocale() Local是 java.util包中的一个类,封装与国家、语言等相等的地域信息。这个方法用于获取与Appet相关的Locale对象。  
public boolean isActive() 判断Applet是否处于被激活的状态

  (2)用于操作声音、图像资源的方法

原型 注释
public Image getImage(URL url) 从给定的URL获取Image对象,用以处理图像。
public Image getImage(URL url,String name)  获取指定URL和名字的Image对象。
public AudioClip getAudioClip(URL url)  
public AudioClip getAudioClip(URL url,String name) 用以获取AudioClip对象。这两个方法用以处理声音
public void play(URL url)   
public void play(URL url,String name)  用于演奏指定的AudioClip对象。  

  (3)与生命周期有关的方法

原型 注释
public void init() 做初始化工作,在Applet被装入时调用。
public void start() 启动Applet的运行。
public void stop() 停止Applet运行时被自动调用
public void destroy() 当Applet消亡时被自动调用,一般用来做回收资源等收尾工作

  (4)与Applet所在页面有关的方法

原型 注释
public URL getCodeBase() 返回Applet所在的文档的URL。
public URL getDocumentBase() 返回Applet所在的HTML文档的URL。
public String getAppletInfo() 返回一个String对象,其中包含Applet的版本,拷贝权、作者等信息
public String[][]getParameterInfo() 描述Applet参数的名字、类型和描述
public String getParameter(String) 得到在HTML文档中传给Applet的参数

  Applet类的继承关系:

  java.lang.Object

    └java.awt.Component

      └java.awt.Container

        └java.awt.Panel

          └java.applet.Applet

10.2.2 java.applet包中的接口
  Applet包中的三个接口分别是AppletContext、AppletStub和AutioClip,它们均由java.lang.Object类继承而来。

  Appletcontext接口顾名思义是指Applet所在的“上下文”。所谓Applet的上下文是指装入、执行Applet的浏览器或appletviewer。Applet类中的getAppletContext()方法可以访问这一接口的对象。本接口提供七个与Applet上下文有关的方法:

原型 注释
public abstract Applet getApplet(String name)  按名字得到相应的Appet对象。
public abstract Enumeration getApplets()  得到与当前AppletContext对象相关的所有Applet。返值为一个Enumeration对象。Enumeration是java.util中的一个接口类,其中封装了枚举数据集合的方法
public abstract AudioClip getAudioClip(URL) 根据URL得到相应的AudioClip对象
public abstract Image getImage(URL) 根据URL得到相应的Image对象
public ablstract void showDocument(URL) 让浏览器显示特定URL的页面
public ablstract void showDocument(URL,String) 根据URL和文档名显示指定页面
public abstract void showStatus(String) 用浏览器显示状态信息
public abstract boolean isActive()   
public abstract URL getDocumentBase()   
public abstract URL getCodeBase()   
public abstract String getParamenter(String)   
public abstract Appletcontext getAppletContext()   
public abstract void appletResize(int,int)   
   

  AppletClip接口是用来处理声音的。它定义了三个无参的方法play(),stop(),loop(),分别用来开始演奏、停止演奏AppletClip对象。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
42#
 楼主| 发表于 2006-6-28 04:30 | 只看该作者
10.3 HTML语言与Applet
10.3.1 概述
10.3.2 HTML标记简介
10.3.3 用javadoc生成HTML文档

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
43#
 楼主| 发表于 2006-6-28 04:31 | 只看该作者
10.4 开发实例
//点击此处请看效果

//calculator.java
import java.lang.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class calculator extends Applet

{
  TextField text = new TextField();
  Label label=new Label("Calculator";
  public Button buttons[]=new Button[15];
  //初始化
  public void init()
  {
    setBackground(Color.gray);
    GridBagLayout gridbag = new GridBagLayout();
    setLayout(gridbag);
    for(int i=0;i<10;i++)
    {
      buttons=new Button(""+i+"";
    }
    buttons[10] = new Button("-";
    buttons[11] = new Button("*";
    buttons[12] = new Button("CLR";
    buttons[13] = new Button("+";
    buttons[14] = new Button("=";
    int px[] = {0,0,4,7,0,4,7,0,4,7,0,4,7,0,4,7,0};
    int py[] = {0,3,3,3,5,5,5,7,7,7,9,9,9,11,11,11,2};
    int pwidth[]={10,4,3,3,4,3,3,4,3,3,4,3,3,4,3,3,10};
    int pheight[] = {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
    GridBagConstraints cons[] = new GridBagConstraints[17];
    for(int i=0;i<17;i++)
    {
      cons = new GridBagConstraints();
      cons.fill = new GridBagConstraints().BOTH;
      cons.gridx = px;
      cons.gridwidth=pwidth;
      cons.gridheight = pheight;
      if(i==0)
      {
        gridbag.setConstraints(text,cons[0]);
        add(text);
      }
      else if(i==16)
      {
        gridbag.setConstraints(label,cons[16]);
        add(label);
      }
      else
      {
        gridbag.setConstraints(buttons[i-1],cons);
        add(buttons[i-1]);
      }
    }
    //以上摆放各个零件
    text.setText("";
    text.setEditable(false);
    text.setFont(new Font("TimesRoman",Font.BOLD,14));
    text.setBackground(Color.cyan);
    label.setBackground(Color.lightGray);
    //以上作一些初始化工作
    for(int i=0;i<15;i++)
    {
      buttons.addActionListener(new MyActionListener(this));
      //登记每个按钮的事件监听者
    }
  }
  //绘制屏幕
  public void paint(Graphics g)
  {
    g.draw3DRect(35,1,130,189,true);
    g.fill3DRect(35,1,130,189,true);
  }
}
//自定义的监听者类监听各个按钮的动作并处理相应事件
class MyActionListener implements ActionListener
{
  calculator clr;
  static long number,num1;
  static char opr;
  public MyActionListener(calculator cl)
  {
    super();
    clr=cl;
  }
  public void actionPerformed(ActionEvent e)
  {
    String screen;
    Button eSrc = (Button)e.getSource();
    String cmd = eSrc.getActionCommand().trim();
    int i;
    if(cmd.equals("CLR")//按钮"CLR"被按动
    {
      clr.text.setText("0";
    }
    else if("+".equals(cmd)||"-".equals(cmd)||"*".equals(cmd))//运算键被按动
    {
      clr.text.setText("0");
      num1=number;
      opr=cmd.charAt(0);
    }
    else if("=".equals(cmd))//被按动
    {
      int sign;
      if(number>0) sign=1;
      else sign=-1;
      if(sign*num1>0) sign=1;
      else sign=-1;
      switch(opr)
      {
        case '+':number=number+num1;break;
        case '*':number=number*num1; break;
        case '-':number=num1-number; break;
      }
      if(number>999999999||number<-999999999)
      {
        clr.text.setText("Overflow");
      }
      else
        clr.text.setText(""+number+"");
      opr = ' ';
    }
    else if((i=Integer.parseInt(cmd))>=0&&i<=9)//按了数字键
    {
      screen = clr.text.getText();
      if(screen.length()<9) //Limit the width of input
      {
        if(screen.trim().equals("0"))

          clr.text.setText(cmd);
        else
          clr.text.setText(screen+cmd);
        number=Integer.parseInt(clr.text.getText());
      }
    }
  }
}

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
44#
 楼主| 发表于 2006-6-28 04:32 | 只看该作者
10.5 通用网关接口
(原文空)

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
45#
 楼主| 发表于 2006-6-28 04:39 | 只看该作者
第十一章 网络类库java.ne(上)
  本章将介绍有关网络编程的基本程序和Java对网络提供的类库支持,并以实例演示类库的使用。学习了本章之后,读者应能独立开发简单的网络应用程序,并为今后设计较为复杂的网络应用程序打下基础。

11.1 概述
  11.1.1 TCP/IP协议族
  Java的风靡与Internet的繁荣是密不可分的。Internet这个名词正逐渐变得家喻户晓,客观上促进了Java的发展。第一章中我们曾简单介绍过Internet,这里结合我们可能的应用,进一步介绍它的一些基础知识。
  Internet是一个互联网。它可以把各种不同种类的网联接在一起。无论是局域网、广域网,无论在网内部遵循什么协议,都可以纳入Internet。这就使世界各地的各种计算机能够互相联系,彼此通信。处在网络中的计算机称为主机(host)。无论是在什么样的网络中,计算机与计算机都通过通信线路相连结,构成一个纵横交错的网。在这个复杂的网中,各台主机像各个点,通过线(通信线路)彼此相联,因此,网络中的主机又可称为节点。
  单有了机器和通信线路还不够,通信线路上传输的归根到底都是二进制数字串,或者说得更“低级”一些是高低电平。这些“0”或“1”如何能与我们屏幕上看到的丰富的图像、文本联系起来呢?这是一项艰巨的工作。网络软件必须能够完成从机器可识别的信息到人可识别的信息的转换。但人能识别的信息是多种多样的,总不能够每处理一种信息都从最底层“0”“1”开始转换。于是,网络的层次结构这个概念就应运而生了。网络的实现人员把网络划分为几个层次,每一层完成相对独立的工作。较高的层便用较低层提供的功能(或称“服务”)对较低层的转换结果进行转换,而不必关心较低的层的实现细节。每一层向比它更高的层提供一些接口,为高层提供服务。
  网络究竟分成几层?这个问题很难回答。而且,网络产生之初并未经过协调和统一,因而不同的网络就有不同的设计。
  国际标准化组织(ISO)制订了开放系统互连(Open Systems Interconnection)参考模型,它将网络分成七层,这可以说是较具“标准”性的一个模型(见图11.1-a)。

    ┌─────┐  ┌──────────┬─┬
    │ 应用层 │  │各种应用层协议   │ │
    ├─────┤  │(Telnet,  │ │
    │ 表示层 │  │FTP,SMTP等)│ ↓
    ├─────┤  ├──────────┤TCP/IP位置
    │ 会话层 │  │   TCP    │ ↑
    ├─────┤  ├──────────┤ │
    │ 传输层 │  │   IP     │ │
    ├─────┤  ├──────────┼─┼
    │ 网络层 │  │   数据链路层  │ ↓
    ├─────┤  ├ ─ ─ ─ ─ ─┤不属于TCP/IP
    │数据链路层│  │    物理层   │ ↑
    ├─────┤  └──────────┴─┴
    │ 物理层 │
    └─────┘
    a OSI七层模型    b TCP/IP 协议模型
      图11.1 两种模型的对比

  OSI模型确实使网络结构变得很清楚,但它却不够实用。原因之一是它与现在的网络模型有不少差异:当它产生时,不少计算机网络已颇具规模,相应的协议也已成型,要求它们转而遵循OSI模型当然不现实。原因之二是它分层过细,各个层的工作量分配又不均衡,实现起来比较复杂,不如现实的系统有效率。在Internet网上使用的TCP/IP的网络体系结构则是网络工业标准的杰出代表,是一个应用广泛的模型。它的分层与OSI模型有一定的差异,但又互相对应,各层次功能互相渗透。图11.1-b是TCP/IP网络体系结构的示意图。由图可见,它与OSI模型的大致对应关系。应当指出,这种对应关系不是绝对的,因为各层的功能很可能有一些交错。
  OSI七层模型是一个理论模型,而TCP/IP协议模型更具实用价值。我们主要介绍后者。有兴趣的读者可参阅网络方面的书籍以了解其它内容。
  如图11.1-b所示,TCP/IP模型将网络划分为四个层次。网络的最终用户不必了解各层的实现。比如,使用浏览器的用户只需连至需要的网址,不必知道文本传送协议HTTP的内容。但作为网络应用的设计者就不同了,需要多了解一引起协议的细节内容。下面我们来看一看TCP/IP协议族。
  什么是协议?协议就是约定,就是双方为了协调地做一件事情而共同遵循的规则。打个比方来说,中国古代演义小说中常有设下酒宴骗来敌人,然后“摔杯为号,群起攻之”的故事。“摔杯为号”就是一一个协议。甲方发出请求——摔杯,乙方做出响应——进攻。网络中名繁多的协议,适用于网络层次模型中的不同层次,其实质是相同的,即约定计算机之间相互交换信息的方式、顺序,双方如何发出请求,如何作出响应。以大家所熟悉的FTP为例,客户发生一个“GET”请求,对方(服务器)发送相应文件作为响应。这些动作的规程就是在协议中加以约定的。
  Internet中常用协议有很多,常被统称为TCP/IP协议族。
  图11.2中以英文缩写形式写的协议都属于TCP/IP协议族,它们居于不同的层次,完成不同的工作。对它们的简单解释见表11.1。
  我们在编写网络应用时,若想与标准的商业软件连接,就必须遵循协议的要求。协议的细节必须参考相应的国际标准。当然,也可以自己制订协议,让你的应用遵循自定义的协议来工作。
    ┌──────┬───┬────┬────┬──┬──
    │Telent│FTP│HTTP│SMTP│┉┉│ ↑
    ├──────┴───┴────┴────┴──┤应用层
    │      套接字(Socket)      │ ↓
    ├───────────────────────┼──
    │        TCP/UDP        │传输层
    ├───────────────────────┼──
    │        IP/ICMP        │网络互联层
    ├───────────────────────┼──
    │       数据链路层与物理层       │低层
    └───────────────────────┴──
         图11.2 TCP/IP协议族层次图

                 表11.1 TCP/IP协议族主要成员
协 议 简 称 功 能
文件传输协议 FTP(File Transfer Protocol) 处理网络上文件的传送
超文本传送协议 HTTP(Hypertext Transport Protocol) 传送超文本文档及多媒体信息
简单邮件传输协议 SMTP(Simple Mail Transmission Protocol) 简单的网络邮件传输
传输控制协议 TCP(Transport Control Protocol) 实现传输层面向连接的数据交换(在IP层的基础上实现)
用户数据报协议 UCP(User Datagram Protocol) 用于实现无连接的数据报通信(参见11.4)
网络互联协议 IP(Internet Protocol) 实现网络互联层的信息传递。该层通信是面向无连接的
互联网络控制报文协议 ICMP(Internet Control Message Protocol) 用以交换互联网络的状态信息或异常信息

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
46#
 楼主| 发表于 2006-6-28 04:40 | 只看该作者
  11.12 Java的网络类库支持
  Java提供了如下几方面的类来帮助用户完成网络操作:
  ■网络地址转换。完成域名与IP地址的转换。
  ■面向连接的通信。为服务器方与客户机方程序提供类库支持。
  ■面向无连接的通信。提供数据报方式通信所需的类库支持。
  ■Web连接。为浏览器——服务器模式的较高层次的连接提供类库支持。

  11.1.3 软硬件要求
  这一章涉及网络编程,因此对计算机的软件硬件要求较前几章更高。这个要求就是机器应能上网。本章中的大部分例子要求机器拥有IP地址。例11.8(ContentHandlerDemo,见11.6健保?突С绦蛴敕?衿鞒绦蚪崾??br>   例11.2 ServerDemo.java
  1: import java.io.*;
  2: import java.net.*;
  3: public class ServerDemo{
  4:  public static void main(String[] args){
  5:   try{
     //建立服务器套接字
  6:    ServerSocket server=new ServerSocket(2000);
     //本地端口
  7:    int localPort = server.getLocalPort();
  8:    System.out.println("Server is listening...";
  9:    System.out.println("Client should connect to port "+localPort);
     //监听并接受请求
  10:   Socket client=server.accept();
     //打印被接受的客户机的主机名
  11:   System.out.println("Client "+client.getInetAddress().getHostName()+" is accepted.";
     //建立输入输出,以务数据交换
     BufferedReader bufReader=new BufferedReader(new
      InputStreamReader(client.getInputStream()));
     PrintWriter prtWriter=new PrintWriter(client.getOutputStream());
     System.out.println("Client port "+client.getPort());
     //发出欢迎信息
     prtWriter.println(" Welcome! You can say a line of words before disconnect.";
     prtWriter.flush();
     System.out.println("Greeting message has been sent.";
     System.out.println("Client says:";
     //读取客户机发来的信息并显示
     System.out.println(bufReader.readLine());
     prtWriter.println("Bye.";
     prtWriter.flush();
     bufReader.close();
     prtWriter.close();
    }catch(IOException ex){
     System.out.println("IO exception occured!";
    }
   }
  }

  在这个例子中客户机一端的程序是这样的(例11.3)。
  例11.3 ClientDemo.java


  import java.net.*;
  import java.io.*;
  public class ClientDemo{
   public static void main(String[] args){
    //判断命令行参数是否符合要求
    if(args.length != 2){
     System.out.println("Usage:java ClientDemo <hostname> <port>";
     return;
    }
    try{
     //建立套接字
     Socket client=new Socket(args[0],Integer.valueOf(args[1]).intValue());
     //输出远程主机的名字
     System.out.println(" Destination - " + client.getInetAddress().getHostName());
     //输出本地端口
     System.out.println("Local port - "+client.getLocalPort());
     //创建输入输出流
     BufferedReader bufReader=
      new BufferedReader(new InputStreamReader(client.getInputStream()));
     BufferedReader kbdReader=
      new BufferedReader(new InputStreamReader(System.in));
     PrintWriter prtWriter=new PrintWriter(client.getOutputStream());
     //输出从服务器发业的信息
     System.out.println(bufReader.readLine());
     //向套接字写入从键盘得到的信息
     prtWriter.println(kbdReader.readLine());
     prtWriter.flush();
     //输出从服务器发来的信息
     System.out.println("Server Says: "+ bufReader.readLine());
     System.out.println("Disconnect";
     //关闭连接
     client.close();
    }catch(UnknownHostException ex){
     System.out.println("Cannot connect destination host.";
    }catch(IOException ex){
     System.out.println("IO exception occured.");
    }
   }
  }
  3.程序分析
  通过注释,读者可能已经明白了程序的结构和功能。下面我们结合例子的输出再解释一下。
  服务器程序是首先被运行的。ServerDemo.java的第6行创建一个服务器套接字。第7行的getLocalPort()返回ServerSocket对象所监听的端口号。
  第8、9行输出提示信息。至此(客户程序尚未运行),屏幕显示如后面给出的例11.3输出结果所示。
  Server is listening...
  Client should connect to port 2000
  然后程序进行等待状态。
  在另一个DOS窗口中启动程序ClientDemo。命令行参数有两上,一个是服务器程序所在主机名,一个是目的端口号。如果有条件,客户与服务程序可分置于两台机器上运行。但如果没有这样条件,用两个DOS窗口也是一样的。演示本例所用的机器,域名为huang.nju.edu.cn,IP地址为202.119.32.17。因此第一个命令行参数使用202.119.32.17。在服务器程序中,我们设定监听端号为2000,因此第二个参数使用2000。
  程序启动后,根据命令行参数建立一个客户套接字:
  Socket client=new Socket(args[0],Integer.valueOf(args[1]).intValue());
  客户套接字创建之后,不妨回过头来看看服务器程序。ServerDemo.java的第10行接受连接请求,返回一个套接字对象client。
  有了client对象,我们可以了解一下客户的情况。在现实中服务器程序中监控功能是很重要的,我们这里也实施简单的监督,看看到底接受了谁的连接请求。于是,服务器方的屏幕上显示:
  Clinet huang.nju.edu.cn is accepted.
  第15行又用了Socket的方法getPort()获取远程端口号。因此服务器又显示:
  Client Port 1065
  客户一方也进行了类似的工作,显示了服务器方主机的名字和客户机自己的端号:
  Destination——huang
  Local port——1065
  读者可能对主机名打出了202.119.32.17有所疑问。这里“202.119.32.17”是一个字符串,与域名同样对待。读者可以用域名来代替IP地址运行客户程序,则这里就显示域名了。如若用
  java ClientDemo huang.nju.edu.cn 2000
运行程序,会显示
  Destination——huang.nju.edu.cn
  ClientDemo的第13~17行与ServerDemo的第12~15行类似,都创建了相应的I/O流,以便交换数据。为了操作方便,程序中又分别给这两个流加了过滤器。
  使用I/O流时要弄清楚哪个是进的,哪个是出的。不要看到client.getInputStream(),就以为是在创建客户机的输入流从而认为服务器该向其中写数据。无论从哪一方看来,getInputStream()所得的都是输入流,是用来读数据的,getOutputStream()所得的流都是用来写数据的。
  下面就是客户机与服务器的“对话”过程。服务器先向连接口写一行欢迎信息,再在标准输出显示“Greeting message has been sent“。而客户端读到欢迎信息并显示在屏幕上。然后,客户端程序接收键盘输入并将它发给服务器(下面的运行结果中带下划线的为键入内容)。服务器接收并在屏幕上显示,然后发送一个“Bye”信息,程序结束。客户端接收到服务器“Bye”之后显示“Disconnect”并结束。
  两个程序的完整输出如下。为了清楚起见,键盘输入的信息加了下划线(本文是用的斜体)。
  服务器方运行结果:
  E:\java01>java ServerDemo
  Server is listening...
  Client should connect to port 2000
  Client 127.0.0.1 is accepted.
  Client port 1477
  Greeting message has been sent.
  Client says:
  Hello. This is my second coming.

  E:\java01>

  客户机方运行结果:
  E:\java01>java ClientDemo 127.0.0.1 2000
  Destination - 127.0.0.1
  Local port - 1477
  Welcome! You can say a line of words before disconnect.
  Hello. This is my second coming.
  Server Says: Bye.
  Disconnect

  E:\java01>

  上面的例子中,服务程序与客户程序的工作也是有协议的,即服务程序与客户程序按确定程相互通信,服务器先发欢迎信息,客户发信息,然后服务器再发信息......等等。FTP等应用协议中也是对端口、操作等进行规定,但内容更为详尽。
  当今被广泛使用的服务器程序是较为复杂的。它们可在后台运行,同时受理多个客户的访问,可循环接受多次请求。但基本的过程是与示例中相似的。复杂的编程中我们可以利用Java的多线程机制来实现后台运行和多客户访问,读者有兴趣不妨一试。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
47#
 楼主| 发表于 2006-6-28 04:40 | 只看该作者
  11.3.4 SocketImpl类与SocketImplFactory接口
  SocketImpl是一个抽象类。通过定义它其中的方法,可以定制自己需要的Socket。如果程序员觉得Java提供的套接字的操作与自己所要求的不太符合,可以通过实现SocketImpl来定义套接字的实现。一旦实现了SocketImpl,如何引用呢?这又自然引出了SocketImplFactory接口。
  SocketImplFactory接口中只有一个方法createSocketImpl()。返值为SocketImpl对象。我们用它来使自己定义的Socket实现发生作用。
  自定义套接字实现需要经过以下步骤:
  (1)实现抽象类SocketImpl。
  (2)实现接口SocketImplFactory。
  (3)用ServerSocket/Socket类中的setSocketFactory()方法设置所实现的SocketImplFactory。
  (4)SocketImplFactory的createSocketImpl()方法创建所定义的SocketImpl对象。
  (5)使用SocketImplt对象。
  上面这个过程与11.6和11.7中创建自定义的内容处理器的过程很相似。读者可以参照11.6和11.7中的例子。
  SocketImpl类中封装了一些低级的操作,如监听(listen())、接受连接(accept())、连接(connect())等。具体的方法请参见API文档。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
48#
 楼主| 发表于 2006-6-28 04:41 | 只看该作者
11.4 数据报的实现:DatagramSocket与DatagramPacket
  11.4.1 数据报
  节11.3中介绍了面向连接的通信,下面我们来介绍面向无连接的通信(Connectionless Oriented Communiation)。
  无连接的通信中,通信双方不需要先建立好连接。发送数据时,每包数据上附有完整的目的地址。如果一次发送多包数据,它们的传输是彼此独立的,未必先发的先到,后发的后到,因而是无序的。数据在传输中的丢失、颠倒和重复无法避免,因而是不可靠的。无连接服务适于传送零散的数据。
  无连接服务类似现实生活中的信函往来。甲写信给乙时,乙是不必知道的。每封信上附有乙的明确地址。如果要发多封信,各封信的邮寄互不相干。由于邮路上的一些情况,很可能出现信件次序颠倒、信件的丢失。如果乙长期未收到甲的一封信,发觉后要求甲重发,而被延误的信最终又送到了,这就出现了数据的重复。
  无连接服务也有着广泛的应用。为了增强可靠性,也有一些弥补的措施,如接到数据后发送一个“已收到”的确认信息等。
  数据报是较为纯粹的一种无连接通信。发送方一旦发数据,就假定接收方已经收到了。这样通信开销较小,但可靠性差。不过,我们可以基于数据报,通过附加一些错误检测措施来完成较为可靠的服务。本节我们讨论纯粹的数据报通信。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
49#
 楼主| 发表于 2006-6-28 04:55 | 只看该作者
  11.4.2 Java对数据报的支持
  1.DatagramPacket类和DatagramSocket类
  通过前面所讲的原理可以发现,在通信时,交换数据双方均在打包的数据(数据报)上附目的地址;双方使用同样的套接字,通信时向对方的套接字写入数据。因此,Java为数据报通信提供了两个类:数据报类DatagramPacket和数据报套接字类DatagramSocket。顾名思义,DatagramPacket封闭了被发送数据的有关信息和操作,而DatagramSocket封闭了套接字的有关信息和操作。
  DatagramPacket的构造函数有:
  ■public DatagramPacket(byte ibuf[],int ilength)
  创建一个数据报对象,以便接收长为ilength的数据报。其中,ibuf是存放收到数据的缓冲区。ilength必须小于或等于ibuf的长度。
  ■public DatagramPacket(byte ibuf[],int ilength,InetAddress iaddr,int iport)
  创建一个数据报对象,以便送长为ilength的数据报。其中,ibuf是发送缓冲区,iaddr是目的地址,iport是目的端口号。ilength必须小于或等于ibuf的长度。
  数据报类的常用方法有:
  ■public synchronized InetAddress getAddress()
  返回收到的数据报的来源地址或发出的数据报的目的地址。
  ■public synchronized int getPort()
  返回收到的数据报的来源端口或发出的数据报的目的端口。
  ■public synchronized byte[] getData()
  取数据报中的数据。
  ■public synchronized int getLength()
  取得数据报的数据长度。
  相应于上述get方法,还有一组set方法,分别用来设置地址、端口、数据、长度。下面是它们的原型:
  ■public synchronized void setAddress(InetAddress iaddr)
  ■public synchronized void setPort(int iport)
  ■public synchronized void setData(byte ibuf[])
  ■public synchronized void setLength(int ilength)
  数据报套接字类的构造函数有三个:
  ■public DatagramSocket() throws SocketException
  构造一个数据报套接字对象,任意关联本地主机的一个端口。
  ■public DatagramSocket(int port) throws SocketException
  构造一个数据报套接字对象,关联到本地主机的指定端口。
  ■public DatagramSocketint port,InetAddress laddr) throws SocketException
  创建一个数据报套接字对象,关联到指定的本地主机地址和指定的端。
  数据报套接字的方法与面向连接通信使用的套接字类的方法有些类似。常用的有下面一些,对于含义很明显的方法不再解释。
  ■public void close()
  关闭该套接字。
  ■public InetAddress getLocalAddress()
  ■public int getLocalPort()
  ■public synchronized int getSoTimeout() throws SocketException
  取SO_TIMEOUT的值。
  ■public synchronized void receive(DatagramPacket p)throws IOException
  接收一个数据报。没有收到数据报时该方法阻塞。如果收到的数据长度大于缓冲区长度,超出缓冲区的部分数据将被截去。
  ■public void send(DatagramPacket p) throws IOException
  发送一个数据报。
  ■public synchronized void setSoTimeout(int timeout) throws SocketException
  设置SO_TIMEOUT的值(毫秒)。这是receive()方法阻塞的时间上限。超时将抛出java.io.InterruptedIOException。
  2.程序示例
  下面我们用一个具体的例子来看它们如何工作(例11.4、例11.5)。
  这个例子的功能是传送。运行仍然采用两个DOS窗口分别进行的形式,选启动接收者运行。Sender接收键盘输入的信息,并将其以数据报的形式发送出去。Receiver接收这个数据报并在屏幕上显示其内容。
  读者可以自行分析这个简单的例子,设想一下它的运行结果。在节11.4.2将例,读者可以对照一下自己的设想是否正确。
  例11.4 是发送方程序。
  例11.4 Sender.java。
  1: import java.net.*;
  2: import java.io.*;
  3: public class Sender{
  4:  public static void main(String[] args) throws IOException{
    //判断命令行参数是否符合要求
  5:   if(args.length!=2){
  6:    System.out.println("Useg:java Sender <dest hostname> <port>";
  7:    return;
  8:   }
    //发送缓冲区
  9:   byte sBuf[]=new byte[100];
  10:  System.out.println("Give the message you'll send, "+
  11:   "up to 100 bytes,ending with #";
  12:  DataInputStream dataIn=new DataInputStream(System.in);
  13:  int i;
    //读取键盘输入,存入缓冲区
  14:  for(i=0;i<100;i++){
  15:   byte inByte=dataIn.readByte();
  16:   if((char)inByte=='#') break;
  17:    sBuf=inByte;
  18:  }
    //创建数据报套接字
  19:  DatagramSocket sendSocket=new DatagramSocket();
    //创建一个数据报
  20:  DatagramPacket packet=new
  21:   DatagramPacket(sBuf,i,InetAddress.getByName(args[0]),
  22:   Integer.valueOf(args[1]).intValue());
    //发送
  23:  sendSocket.send(packet);
    //关闭
  24:  sendSocket.close();
  25: }
  26:}

  例11.5 是接收方程序。
  例11.5 Receiver.java。
  1: import java.net.*;
  2: import java.io.*;
  3:
  4: public class Receiver{
  5:  public static void main(String[] args) throws IOException{
  6:   if(args.length!=1){
  7:    System.out.println("Usage:java Receiver <port>";
  8:    return;
  9:   }
    //接收缓冲区
  10:  byte rBuf[]=new byte[100];
    //创建一个用于接收数据的数据报
  11:  DatagramPacket packet=new DatagramPacket(rBuf,rBuf.length);
    //创建套接字
  12:  DatagramSocket receiveSocket=
  13:   new DatagramSocket(Integer.valueOf(args[0]).intValue());
    //等待并接收数据报
  14:  receiveSocket.receive(packet);
    //取数据报中的数据并打印
  15:  System.out.println(new String(packet.getData()));
    //关闭套接字
  16:  receiveSocket.close();
  17: }
  18:}

  3.程序分析
  让我们按照双方的动作顺序来分析它们的行为。
  接收方(Receiver)先于发送方被启动运行,然后做一些接收数据的准备工作。请读者区分这些工作与面向连接的通信的区别。这里接收方的等待与面向连接通信中服务器的等待连接是不同的。这里的准备工作相当于设置了一个可以向其中投递信息的信箱。至于信件按什么途径和次序被投递是不关心的。
  第11行创建了一个用于接收的数据报对象packet。第12行创建接收方套接字。然后(第14行),接收方调用接收方法,等待接收数据报。
  现在看发送方(Sender)做了些什么。发送方先准备了一个发送缓冲区sBuf。这是一个包含100个字节的数组。然后根据键盘输入为数组赋值。
  从第14行至第18行是为发送缓冲区赋值的过程。如果键盘输入不足100个字符,则以“#”结束。否则,读前100个字符,余下的舍弃。
  第19行创建一个数据报套接字sendSocket。这里采用了没有参数的构造函数,因为数据报中会说明目的端口号。在接收方则使用有参数的形式。
  接下来就是创建数据报对象了。Sender程序的第一个命令行参数为目的主机名,目的主机的地址根据它用InetAddress类的类方法getByName()得到。第二个命令行参数是端口号,程序中用了一个转换,从字符串得到相应的整型值。
  Sender程序最后的工作是发送数据报,然后关闭套接字,结束运行。
  当Sender发出数据报后,Receiver结束了receive()的阻塞状态,从套接字读到了数据报的内容。第15行打印输出数据报的内容,方法是先根据接收缓冲区中的内容创建一个字符串对象,然后输出这一字符串。接着,减压套接字,程序结束。
  下面是这个例子一次运行的完整输出,其中带下划线(本例中是斜体)的部分为键入信息。
  E:\java01>java Receiver 2000
  Notice--
  The Receiver should be executed before Sender's sending message.

  E:\java01>

  E:\java01>java Sender 127.0.0.1 2000
  Give the message you'll send, up to 100 bytes,ending with #
  Notice--
  The Receiver should be executed before Sender's sending message.#

  E:\java01>

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
50#
 楼主| 发表于 2006-6-28 04:57 | 只看该作者
第十二章 脚本语言JavaScript
12.1 认识JavaScript
  12.1.1 简介


  12.1.2 JavaScript和Java


  12.1.3 JavaScript和HTML页面


12.2 JavaScript资源
12.3 尝试使用对象
12.4 利用定时器
12.5 一个较复杂的例子

_______________________________________________________
汗,原文就是这个样子

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表