Java语言编程基础(转)4
广告投放★自助友情CMS落伍广告联盟晒乐广告联盟脉动广告联盟品味广告联盟
广告位可自定样式联系QQ:4285248个文字广告月20元广告联系QQ:428524广告位可自定样式
8个文字广告月20元黄金广告位每月20元广告位可自定样式联系QQ:428524广告位可自定样式
左旋肉碱、全国包邮
买二送一、无效退款

文章浏览→编程相关.Net编程→Java语言编程基础(转)4

Java语言编程基础(转)4
Java语言编程基础(转)4

  六.AWT绘图
  Grphics类是java.awt包的中一个类,可以输出文本,还可以绘图,例如直线、圆、椭圆、矩形、不规则图形等,看看它的方法就知道了。
  1.Grphics类的方法
  ⑴图形坐标体系
  Java语言与其他计算机语言的图形系统所采用的二维平面坐标体系是一样的,它的图形系统的坐标原点(0.0)在屏幕的左上角,水平向右为X轴的正方向,竖直向下为Y轴的正方向,每个坐标点的值表示屏幕上的一个像素点的位置,因此,要显示内容的X坐标越大,内容在屏幕上越靠右,Y坐标越大,内容在屏幕上越靠下。
  ⑵画线
  Graphics类中提供画线的功能是drawLine()方法。
  调用方法的格式:
  drawLine(int x1,int y1,int x2,int y2);
  说明:
  drawLine()方法需要设置四个参数,其中x1,y1表示线段的一个坐标点,x2, y2表示线段的另一个坐标点。
  如果想画点那么将线段的两个点的坐标设置为相同时,则为在该处画一个点。
  ⑶画矩形
  ①画普通矩形需调用drawRect()或fillRect()方法。
  调用方法的格式:
  drawRect(int x,int y,int width,int height); //边框型风格
  fillRect(int x,int y,int width,int height); //填充型风格
  说明:
  其两个方法的前两个参数分别表示矩形左上角的x坐标和y坐标,后两个参数分别表示矩形的宽度和高度。
  ②画圆角矩形,就是

将矩形的四个角画成圆弧状,每个圆弧其实是由四分之一的椭圆弧所构成。
  调用方法的格式:
  drawRoundRect(int x,int y,int width,int height,int arcWidth,intarcHeight);
  fillRoundRect(int x,int y,int width,int height,int arcWidth,intarcHeight);
  说明:
  它们除了具有和普通矩形含义相同的前四个参数外,还多了两个用来描述圆角性质的参数。其中arcWidth代表了圆角弧的横向直径;
arcHeight代表了圆角弧的纵向直径,当它们分别与圆角矩形的宽和高的参数值相等时,该圆角矩形实际上变成了一个椭圆。
  ③画立体矩形即为画三维矩形。
  在Java语言中的立体矩形并非真正的三维图形而是在矩形的边框上增加一点阴影,使矩形看上去相对表平面好像有凸出或凹下的效果。
  调用方法的格式:
  draw3DRect(int x,int y,int width,int height,booleanraised);
  fill3DRect(int x,int y,int width,int height,booleanraised);
  说明:
  两个方法中的前四个参数与drawRect()方法中所用的参数含义是一样的,第五个参数raised便是定义该立体矩形是具有凸出(值为
true)还是凹下(值为false)的效果。由于是假三维,所以其立体效果不是很明显的。
  ⑷画多边形
  在Graphics类提供了两个方法来画多边形,即边框型drawPolygon()方法和填充型fillPolygon()方法,并且每一种方法都有两种不
同的参数类型。多边形的画法通常是给一组坐标点,再用直线段将这些点依次连接起来。
  ①第一种参数类型
  调用方法的格式:
  drawPolygon(int xPoints[],int yPoints[],int nPoints);
  fillPolygon(int xPoints[],int yPoints[],int nPoints);
  说明:
  其中xPoints参数是一个整数数组,用以存放多边形坐标点的X坐标值,yPoints参数存放相应的一组Y坐标值,nPoints则表示共有几个坐标点。
  ②第二种参数类型的
  调用方法的格式:
  drawPolygon(Polygon p);
  fillPolygon(Polygon p);
  说明:其中Polygon是定义在java.awt中的一个类,它的构造方法也有两种不同的参数传递形式,一种与drawPolygon()方法的第一种调用格式一样:
  Polygon(int xPoints[],int yPoints[],int nPoints);
  另一种调用格式则是:Polygon();创建一个空的多边形(无参数)由Polygon类中的addPoint()方法将多边形的坐标点动态地增加到Polygon对象中。
  ⑸画椭圆
  在Java语言中绘制椭圆的方法是给出该椭圆的外接矩形作为参数。
  调用方法的格式:
  drawOval(int x,int y,int width,int height); //边框型风格
  fillOval(int x,int y,int width,int height); //填充型风格
  说明:
  其调用格式与画普通矩形的方法相似。需要注意的是:x和y是该椭圆外接矩形的左上角,千万不要认为是椭圆的圆心坐标。要因此,画椭圆时,把它先看作是一个矩形将有助于在坐标系统中定位。
  另外,如果想画圆只需将宽和高参数置成相等就是画圆。
  ⑹画弧
  画弧是椭圆的一部分,因而画弧的方法就相当于先画一个椭圆,而后取该椭圆中所需要的一部分。
  调用方法的格式:
  drawAre(int x,int y,int width,int height,int startAngle,intareangle);
  fillArc(int x,int y,int width,int height,int startAngle,intareAngle);
  说明:
  ①两个方法中前四个参数的含义与画椭圆一样,即以矩形的观点来确定弧在坐标系统中的位置。后两个参数是用来定义椭圆的一部分,startAngle参数表示该弧从什么角度开始,arcAngle参数表示从startAngle开始转了多少度。
  ②为弧度坐标体系,水平向右表示0度,逆时钟方向为正角度值,顺时钟方向为负角度值。如果startAngle和arcAngle两个参数中有
任一值大于360度的话,就会被自动转换为0到360度之间的数值。因此若要想画整个椭圆,areAngle需设为360的整数倍,若设为420度刚
相当于只画了60度。
  ③fillArc()方法的效果是填充弧的两端点与圆心连线所围的扇形区域。
  第9章 多线程
  本章教学提要
  教学重点:线程与多线程
  创建线程
  线程的启动
  线程的调度
  线程的基本控制
  多线程同步机制
  教学难点:线程的基本控制与多线程同步机制
  本章教学内容
  一.线程与多线程
  1.线程的概念
  线程是存在于程序中的一个单独的顺序执行流程。它类似于一个顺序执行的程序,即一个单独的线程也只有一个起始点、一个执行序
列和一个结尾,在线程运行的某一特定时刻也只有一个执行点。但是,一个线程只是一个程序的一部分,它本身并不能构成一个完整的程
序,换言之,程序可以独立运行,也可以拥有多个相互独立的线程,而线程则不然,它不能独立运行,也能不独立存在,而必须“寄生”
于一个程序之中。
  只包含一个线程的程序就是我们所熟悉的顺序执行程序,这时线程这一概念并未给我们带来什么新意。而Java使用线程的神奇之处在
于它使得一个程序可以使用多个线程,这些线程同时运行,而每个线程则完成不同的功能。
  作为一个顺序执行流程,线程也必须拥有自己的运行资源,例如:它必须拥有自己的执行堆栈和程序计数器,线程的代码只能在该上
下文中运行。因此,有人也把线程称为“执行上下文”。
  2.线程的结构
  线程的基本结构如图9-l所示。它包含三个主要部分,第一是虚拟CPU本身,二是CPU执行的代码即Code,第三是代码操作的数据即
Data。在Java中虚拟CPU体现于Thread类中。当一个线程被构造时;它由构造方法参数、执行代码、操作数据来初始化。应该特别注意的
是,这三方面是各自独立的。一个线程所执行的代码与其它线程可以相同也可以不同,一个线程访问的数据与其它线程可以相同也可以不
同。
  图9-l线程的基本结构
  二.创建线程
  1.创建线程的方法之一──继承Thread类
  java.1ang.Thread是Java中用来表示进程的类,其中所定义的许多方法为完成线程的处理工作提供了比较完整的功能。如果将一个类
定义为Thread的子类,那么这个类也就可以用来表示线程。
  2.创建线程的方法之二──实现Runnable接口
  Runnable是Java中用以实现线程的接口,从根本上讲,任何实现线程功能的类都必须实现该接口。前面所用到的Thread类实际上就是
因为实现了Runnable接口,所以它的子类才相应具有线程功能的。Runnable接口中只定义了一个方法就是run()方法,也就是线程体。
  Thread第二种构造方法中包含有一个Runnable实例的参数,这就是说,必须定义一个实现Runnable接口的类并产生一个该类的实例,
对该实例的引用就是适合于这个构造方法的参数。
  3.关于两种创建线程方法的讨论
  ⑴适用于采用实现Runnable接口方法的情况
  因为Java只允许单继承,如果一个类已经继承了Thread,就不能再继承其它类。在一些情况下,这就被迫采用实现Runnable接口的方
法。比如对于Applet程序,由于必须继承java.applet.Applet,因此就只能采取这种实现接口的方法。再有,由于上面的原因而几次被迫
采用实现Runnable接口的方法,可能会出于保持程序风格的一贯性而继续使用这种方法。
  ⑵适用于采用继承Thread方法的情况
  当一个run()方法置于Thread类的子类中时,this实际上引用的是控制当前运行系统的Thread实例,所以,代码不必写得像下面这样
繁琐:
  Thread.currentThread().suspend();
  而可简单地写为:
  suspend();
  因为代码稍微简洁一些,所以许多Java程序员愿意使用继承Thread的方法。但是应该知道,如果采取这种简单的继承模式,在以后的
继承中可能会出现麻烦。
  三.线程的启动
  虽然一个线程已经被创建,但它实际上并没有立刻运行。要使线程真正在Java环境中运行,必须通过方法start()来启动,start()方
法也在Thread类中。例如只要执行:
  Thread1.start();
  此时,线程中的虚拟CPU已经就绪,所以也可以把这一过程想象为打开虚拟CPU的开关。
  四.线程的调度
  虽然就绪线程已经可以运行,但它并不意味着这个线程一定能够立刻运行。显然,在一台实际上只具有一个CPU的机器上,CPU在同一
时间只能分配给一个线程做一件事。那么现在就必须考虑,当有多于一个的线程工作时,CPU是如何分配的。
  在Java中,线程调度通常是抢占式,而不是时间片式。抢占式调度是指可能有多个线程准备运行,但只有一个在真正运行。一个线程
获得执行权,这个线程将持续运行下去,直到它运行结束或因为某种原因而阻塞,再或者有另一个高优先级线程就绪。最后一种情况称为
低优先级线程被高优先级线程所抢占。
  一个线程被阻塞的原因是多种多样的,可能是因为执行了Thread.sleep()调用,故意让它暂停一段时间;也可能是因为需要等待一个
较慢的外部设备,例如磁盘或用户。所有被阻塞的线程按次序排列,组成一个阻塞队列。而所有就绪但没有运行的线程则根据其优先级排
入一个就绪队列。当CPU空闲时,如果就绪队列不空,就绪队列中第一个具有最高优先级的线程将运行。当一个线程被抢占而停止运行时
,它的运行态被改变并放到就绪队列的队尾;同样,一个被阻塞(可能因为睡眠或等待I/O设备)的线程就绪后通常也放到就绪队列的队尾

  由于Java线程调度不是时间片式,所以在程序设计时要合理安排不同线程之间的运行顺序,以保证给其他线程留有执行的机会。为此
,可以通过间隔地调用sleep( )做到这一点。
  五.线程的基本控制
  1.结束线程
  结束一个线程有两种情况,第一种情况是当一个线程从run()方法的结尾处返回时它自动消亡并不能再被运行,可以将其理解为自然
死亡;另一种情况是利用stop( )方法强制停止,可以将其理解为强迫死亡,这种方法必须用于Thread类的特定实例中。
  2.检查线程
  有时候可能不知道一个线程的运行状态(当程序代码没有直接控制该线程时,会发生此种情况),这时可以利用方法isAlive()来获取
一个线程是否还在活动状态。活动状态不意味着这个线程正在执行,而只说明这个线程已被启动,并且既没有运行stop(),也尚未运行
完方法run( )。
  3.挂起线程
  有几种方法可以用来暂停一个线程的运行。在挂起之后,必须重新唤醒线程进入运行,这从外表看来好像什么也没发生,只是线程执
行命令的速度非常慢。挂起线程的方法有以下几种:
  ⑴sleep( )
  方法sleep()用于暂时停止一个线程的执行。通常,线程不是休眠期满后就立刻被唤醒,因为此时其它线程可能正在执行,重新调度
只在以下几种情况下才会发生:
  ①被唤醒的线程具有更高的优先级。
  ②正在执行的线程因为其它原因被阻塞。
  ③程序处于支持时间片的系统中。
  大多数情况下,后两种条件不会立刻发生。
  ⑵suspend( )和resume( )
  有时更好的办法是强制挂起线程,而不指定休眠时间,这种情况下由其它线程负责唤醒其继续执行。线程中有一对方法用于完成此功
能,这就是suspend( )和resume( )
  ⑶join( )
  方法join( )将引起现行线程等待,直至方法join( )所调用的线程结束。
  六.多线程同步机制
  1.wait( )等待和notify( )通知方法
  在Object类中wait( )和notify( )的定义为:
  public class java.lan g.Object{
  public Object();
  ┄┄ //其他
  public final void notify(); //通知方法
  public final void notifyAll(); //通知所有的等待
  public String toString();
  public final void wait(); //等待方法
  public final void wait(long timeout);
  public final void wait(long timeout,int nanos);
  }
  说明:wait( )和notify( )方法都属于基础类Object的一部分,不像sleep( )、suspend()以及resume( )那样属于Thread类的一部
分。
  Wait( )和notify( )方法是与对象的锁相关联的,即这两个方法操纵对象的锁。可以将一个wait()方法置入任何同步方法内部,无
论在类中是否准备进行涉及线程的处理。事实上,能调用wait()方法的惟一地方是在一个同步的方法或代码块内部。若在一个不同步的
方法内调用wait( )或者notify()方法,Java语言程序会通过编译,但是在运行程序时,就会出现一个“非法监视器状态”异常(
IllegalMonitorStateException),而且输出一条错误消息“current thread notowner”。在线程类中,许多方法例如sleep( )、
suspend( )以及resume( )等都可以在不同步的的方法内部调用,因为它们不需要对对象进行锁定操作。
  2.线程监视器
  临视器一次只允许一个线程对该对象执行synchronized方法。当某个synchronized方法被调用时,就锁定该对对象,这也就是所谓的
“获得该对象的锁”。如果在一个对象中存在几个synchronized方法,那么一次只能有一个synchronized方法执行活动的,所有其他要调
用synchronized方法的线程都需要等待。当一个synchronized方法执行结束时,该对象上的锁就被打开,临控器会让打算调用
synchronized方法的线程中优先级最高的那个线程继续执行。
  Jave语言的临视器实际上是完成线程调度工作的,它是将所有的等待进入临视器执行synchronized方法的线程进行排队。如果一个线
程要调用某个对象的一个synchronized方法,而此时另一个线程已经在执行该对象的synchronized方法了,那么该线程将进入队列,等待
执行。如果一个线程在对象中进行操作时调用了wait()方法,那么该线程也要进入队列。然而,把由于临视器忙而阻塞的等待线程与由
于在临视器中显式地调用wait()方法而等待的线程区分开是很重要的。当一个synchronized方法执行完后,由于临视器忙而阻塞的外部
线程就可以执行了。而那些显式地调用了wait( )方法的线程则只能在其他线程用ontify( )或notifyAll()方法将其唤醒时才能继续执行
。当一个进入队列的线程具有了继续执行的资格时,调节器度程序就选择优先级最高的线程来执行。
  3.一个线程的生命周期
  一个线程的生命周期分为生成、运行、等待、终止四个阶段,如图9-6所示。
  图9-6
  一个线程可以处于以下五种状态:
  ⑴ 创建新线程:线程对象已经创建,但尚未启动,所以不可运行。
  ⑵可运行线程:它意味着一旦时间分片机制有空闲的CPU周期提供给一个线程,则该线程便可立即开始运行。因此,线程可能在、也
可能不在运行当中,但一旦条件许可,没有什么能阻止它的运行,除非该线程已经终止或被“堵塞”。
  ⑶ 终止线程:线程从自己的run( )方法中返回后,一个线程便终止了。也可以调用stop( )方法令其终止。
  ⑷ 线程堵塞:线程可以运行,但有某种东西阻碍了它。若线程处于堵塞状态调
  度机制可以简单地跳过它,不给它分配任何CPU时间。除非线程再次进入“可运行”状态否则不会采取任何操作。
  ⑸ 线程死锁:线程之间相互等待获得对方的锁。
  4.线程堵塞
  造成线程被堵塞可能是由以下几个方面的原因所造成的。
  ⑴ 调用sleep( )方法,使线程进入“睡眠”状态。在规定的时间内,这个线程是不会运行的
  ⑵ 用suspend( )方法暂停了线程的执行。除非线程收到resume( )方法的消息,
  否则不会返回“可运行”状态。
  ⑶ 用wait( )方法暂停了线程的执行。除非线程收到nofify( )或者notifyAll()方法的消息,否则不会变成“可运行”。
  ⑷ 线程正在等候一些I/O(输入输出)操作的完成,即若一个数据流需要等候一些I/O活动时,它便会自动进入“堵塞”状态。
  ⑸ 线程试图调用另一个对象的“同步”方法,但那个对象正处于锁定状态,暂时无法使用。即在调用对象的synchronized方法时,
该对象的另一个synchronized方法正执行。
  可调用yield( )方法自动放弃CPU,以便其他线程能够运行。
  5.线程死锁
  在简单的程序中,死锁通常并不是非常可怕,但是,死锁的致命程度与线程和共享资源的数量是成正比的。
  如果Java语言程序使用了大量的线程,死锁很容易就会发生。但是Java语言并没有提供一种机制以自动检测和解决死锁,如果采取以
下防备措施的话,便可以大大降低这种条件发生的可能性:
  ⑴避免从另一个synchronized方法或代码块中调用一个synchronized方法。如果需要嵌套synchronized方法的话,总是按照相同的
顺序调用它们。
  ⑵ 在设计类时,尽量减少对共享资源的访问。
  ⑶ 在创建多线程程序的时候,当出现一个线程需要等待直到另一线程改变了一个 对象或变量的状态情况时,可以使用一种简单的线
程协同(可以人为地协调)技术来处理这些情况。
  6.线程的优先级
  线程在创建时,继承了父类的优先级。线程创建后,你可以在任何时刻调setPriority方法改变线程的优先级。优先级为1~10,
Thread定义了其中3个常数:
  (1) MAX_PRIORITY 最大优先级(值为10)
  (2) MIN_PRIORITY 最小优先级(值为1)
  (3) NORM_PRIORITY 默认优先级(值为5)
  7.线程同步
  Java提供了同步设定功能。共享对象可将自己的成员方法定义为同步化(synchronized)方法,通过调用同步化方法来执行单一线程,
其他线程则不能同时调用同一个对象的同步化方法。
  8.多线程的弊端
  ⑴对于程序员来说,必须加倍注意自己的多线程程序。由于多线程实际上是多个程序段同时运行于内存中,所以一定要理清它们的关
系,不要让它们搅乱了你的头脑。如果真的出现这种情况,那么最好还是少用几个线程。其实,并不是线程越多程序就执行得越快,还有
很多其他因素决定着程序的执行速度。
  ⑵对多线程程序本身来说,它会对系统产生以下影响:
  ①线程需要占用内存。
  ②线程过多,会消耗大量CPU时间来跟踪线程。
  ③必须考虑多线程同时访问共享资源的问题,如果没有协调好,就会产生令人意想不到的问题,例如可怕的死锁和资源竞争。
  ④因为同一个任务的所有线程都共享相同的地址空间,并共享任务的全局变量,所以程序也必须考虑多线程同时访问全局变量的问题

  第10章 多媒体编程
  本章教学提要
  教学重点:图象处理
  动画效果
  声音处理
  教学难点:图象处理、动画效果、声音处理
  本章教学内容
  一.图象处理
  1.图像的显示
  Java语言通过java.awt包提供的Image类来管理与图像有关的信息,在处理图像之前,我们先用java.awt.Image定义一个图像类的对
象,如:
  Image image1;
  ⑴加载图像
  在java.applet.Applet类中提供一个方法,返回关于图像的有关信息
  Image getImage(URL url)
  从网址url加载图形
  Image getImage(URL url,String name)
  从网址url加载名称为name的图形
  url是URL类的一个对象,代表一个网络地址,例如加载一幅sun公司Web服务器指定位置的一幅图片:
  getImage(new URL(
http://java.sun.com/graphics/people.gif));
  上述方法是加载网络上的图像,若不熟悉网站的图片的网址,则加载起来就非常麻烦,所以Java语言还包含了显示本地图像的方法:
  getCodeBase()
  返回Applet文件所在的地址,及该文件所在的目录,图形文件和Applet文件放在同一个目录下,就能保证程序找到该图像文件。另外
使用getDocumentBase()方法也可以达到同样目的。
  例如:加载本地一幅图像
  getImage(getCodeBase(),"样品.jpg");
  ⑵显示图像
  显示图像可以使用Graphics类的方法drawImage,它可以将所加载图像显示在指定位置。格式如下:
  boolean drawImage(Image img,int x,int y,ImageObserverobserver)
  boolean drawImage(Image img,int x,int y,Colorbgcolor,ImageObserver observer)
  其中参数img代表的是加载的图像;参数x,y代表的是图像显示位置的坐标,x,y可取负值,表示一部分图像移出显示区;bgcolor代
表图像显示区域的背景色;observer是图像加载跟踪器。通常指定为this,即由Applet负责跟踪图像的加载情况。
  ⑶缩放图像
  boolean drawImage(Image img,int x,int y,int width,int height,ImageObserver observer)
  boolean drawImage(Image img,int x,int y,int width,intheight,Color bgcolor,ImageObserver observer)
  同样是使用drawImage方法,增加两个参数width,height表示图像实际显示的宽度和高度,通过改变width,height这两个参数,就
可以放大和缩小加载的图像。若为了不使图像因放大和缩小而失真,可调用Image的两个方法就可以得到原图的宽度和高度。
  getWidth():获得图像的宽度
  getHeight():获得图像的高度
  二.动画效果
  1.用多线程实现动画文字
  在Java中实现多线程有两种方法,一种是继承Thread类;另外一种是实现Runnable接口,对于Applet小程序,我们一般是实现
Runnable接口。实现动画文字与实现动画的方法是一样的,可以通过实现Runnable接口来实现多线程绘出动画文字,使文字向打字一样一
个文字一个文字的跳出来,然后全部隐去,再重复显示文字,实现打字效果。
  2.双缓冲技术
  双缓冲技术是当需要在屏幕上显示的图像文件又大又多时,利用该技术在屏幕外面创建一个虚拟的备用屏幕,计算机系统直接在备用
屏幕上作画,等画完以后将备用屏幕中的点阵内容直接切换给当前屏幕。直接切换准备好的画面页的速度比在屏幕上当场作画(刷新画面
)的速度快得多。
  三.声音处理
  Java语言提供了播放声音的方法,这些方法被定义在java.applet包中的AudioClip接口中。在Java2之前的版本只支持一种音频格式
,即8位、8千赫兹、单通道、u律的“.au”文件,其他格式的音频文件必须转换为“.au”格式文件,现在版本可支持更多的声音格式,
如“.au”,“.aif”,“.midi”,“.wav”,“.rfm”等共五种格式的音频文件。音质可为8位或16位的单声道和立体声,采样频率从8
kHz到48kHz。
  1.加载声音文件
  在Applet中播放声音十分简单,Applet类中的play()方法可以将声音文件的加载于播放一并完成,格式如下:
  void play(URL url)
  void play(URL url,String name)
  URL是一个网络地址,可以从某网络地址中播放声音文件。如果想从本地机上播放同目录下的声音文件,可采用下面格式:
  play(getCodeBase(),”音频文件名”);
  使用play()播放文件,一旦加载就立即播放,如果找不到指定的声音文件,也不会产生异常,只是没有声音而已。然而,这种播放是
一次性的,如需重播必须重新加载声音文件。如果想把一个声音文件作为背景音乐连续播放,可使用功能更强的AudioClip接口,它包含
在java.applet包中。使用时需在程序中引入:
  import java.applet.AudioClip;
  在AudioClip接口中提供了各种处理声音数据的方法,如:播放play()、循环播放loop()、停止播放stop()等方法。在完成声音播放
之前,首先创建AudioClip对象,使用getAudioClip()方法加载声音文件,格式如下:
  AudioClip getAudioClip(URL url)
  AudioClip getAudioClip(URL url,String name)
  创建AudioClip对象后,声音文件就被加载,即可调用其他方法处理声音文件。如果该方法没有找到指定的声音文件,将返回null值
,不能创建AudioClip对象。
  第11章 网络编程
  本章教学提要
  教学重点:基本概念与协议
  利用URL获取Internet资源、套接字
  教学难点:利用URL获取Internet资源、套接字
  本章教学内容
  一.基本概念与协议
  1.IP地址
  IP地址在计算机内部的表现形式是一个32位的二进制数,实际表现为一四点格式的数据,由点号(.)将数据分为4个数字。
  用四点格式来表示一个IP地址,记忆起来很不方便而且很容易记错,为了便于记忆,Internet提供了一种域名服务,将IP地址与某个
域名对应起来,这种域名就是通常所说的网址。
  2.端口
  表11-1是一些常见的Internet服务/协议以及默认的端口。
  表11-1 常见的服务/协议及端口
  服务/协议
  端 口
  对 应 协 议
  HTTP
  80
  HTTP协议,用于WWW服务
  FTP
  21
  FTP协议,用于文件传输
  TELNET
  23
  TELNET协议,用于远程登陆
  SMTP
  25
  SMTP协议,用于邮件发送
  POP3
  110
  POP3协议,从主机发送邮件到客户机
  3.客户机与服务器
  在网络中,将信息的提供者叫做服务器,将信息接收者叫做客户机。客户机连接到服务器,向服务器发送信息请求,服务器则侦听客
户的请求,并对请求进行处理,将请求结果返回给客户机,这样,便完成了客户机与服务器之间的交流。
  4.连接与无连接
  ⑴面向连接的通讯需要等客户机与服务器的连接建立成功后,才能开始通讯,它是一种可靠的通讯方式,比较适合大量的数据传输以
及即时信息交流,就像打电话一样,需要等到电话接通后才能开始通话,假如对方不在,则通话没法进行。
  ⑵面向无连接的通讯并不需要连接的建立,好比我们发信一样,将信写好后投递到邮局就不管了,不管对方是否收到,。这种通讯方
式将需要发送的数据打包成数据报,数据报中包括目标地址和原地址,好比信封上的收信人和发信人,只需要将这些数据报发送出去就可
以了。面向无连接的通讯是一种不可靠的通讯方式。
  5.协议
  TCP/IP协议可以分为4层:网络接口层、网络层、传输层和应用层。如图11-1所示
  应用层
  各种应用层协议
  HTTP、FTP、TELNET、SMTP等
  传输层
  TCP
  UDP
  网络层
  IP
  网络接口层
  设备驱动及接口卡
  图11-1 TCP/IP协议体系结构
  二.利用URL获取Internet资源
  URL是用来标识Internet上的资源的,采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。
  URL一般由3部分组成:协议、主机域名或IP地址(有时也包括端口号)以及主机资源的具体地址。
  常用的协议有以下几种:http、ftp、mailto、file等。
  一个完整的URL如下:
  
http://java.sun.com:80/j2se/1.3/docs/api/java/lang/String.html#trim();
  其中http是协议,java.sun.com是主机域名,80是端口号,/j2se/1.3/docs/api/java
  lang/String.html是文件名,trim()是HTML参考点。协议与主机名之间用://隔开,主机名与端口号之间用:隔开,文件名与参考
点之间用#隔开。实际上,一个URL并不需要将以上信息全部写上,可以将一些信息省略掉。
  1.URL类
  URL类封装在java.net包中,提供许多访问远程站点信息的操作,大大降低了编程的复杂性。
  URL类提供了多种形式的构建器来创建一个URL对象,以下为其中几种:
  URL(String spec)——通过指定的地址创建URL对象;
  URL(String protocol,String host,int port,StringFile)──通过协议、主机名、端口号以及文件名创建URL对象;
  URL(String protocol,String host,Stringfile)—通过协议、主机名以及文件名创建URL对象;
  URL(URLcontext,String spec)──通过向对位置和具体位置创建URL对象。
  URL类的常用方法如表11-2所示。
  方 法
  简 要 说 明
  boolean equals(Object obj)
  比较两个URL对象是否相等
  Object getContent()
  获得该URL所对应的内容
  String getFile()
  获得该URL的文件名
  String getHost()
  获得该URL的主机名
  String getPath()
  获得该URL的路径
  int getPort()
  获得该URL的端口
  String getProtocol()
  获得该URL的协议
  String getQuery()
  获得该URL的查询部分(URL中?后面的内容)
  String getRef()
  获得该URL的参考点
  URLConnection openConnection()
  与该URL对应的远程对象建立一个连接,并返回代表该连接的URLConnection
  InputStream OpenStream()
  打开与该URL对应的连接并返回一输入流对象
  boolean sameFile(URL other)
  判断两个URL是否指向同一网络资源(忽略参考点)
  String toString()
  返回一代表该URL的字符串
  表11-2 URL类的常用方法
  2.获取URl的信息
  通过URL类提供的方法,可以很方便地获取URL的相关信息。
  3.获取网络图片
  通过URL可以获得多种类型的网络资源,除了HTML文件外,还有多媒体文件、图片等资源。
  三.套接字
  1.Socket和ServerSocket
  Java中的套接字分为客户机套接字和服务器套接字,分别通过java.net包中的Socket和ServerSocket类来实现。
  创建一个客户机套接字对象可以通过以下构造器来创建:
  Socket(InetAddress address,intport)──创建一个流套接字连接到指定IP地址的指定端口。
  Socket(InetAddress address,int port,InetAddress localAddr ,intlocalPort)──创建一个套接字连接到指定主机的指定远
程端口。
  Socket(String host,int port)──创建一个流套接字连接到指定主机名的指定端口。
  Socket(String host,int port,InetAddress localAddr,intlocalPort)──创建一个套接字连接到指定主机的指定远程端口。
  其中address是一个InetAddress类型对象,该对象代表一个IP地址,可以通过以下方式来创建一个InetAddress的实例:
  InetAddress address=InetAddress.getByName(String host);
  InetAddress address=InetAddress.getLocalHost ();
  创建一个服务器套接字有以下几种方式:
  ServerSocket(intpon)——在指定的端口上创建一个服务器套接字。
  可以通过以下方
  ServerSocket(intpon,intbacklog)——在指定的端口上创建一个服务器套接字,并指定
  最大连接队列的长度。
  ServerSocket(intpon,intbacklog,hetAddresshndAddr)——在指定的端口上创建
  务器套接字,指定最大连接队列的长度,并绑定到指定的本地IP地址。
  Socket类中的常用方法如表11-3。
  表11-3 Socket类中的常用方法
  方 法
  简 要 说 明
  voidclose()
  关闭套接字
  InetAddress getInetAddress()
  获得套接字连接的主机地址
  InetAddressgetLocalAddress()
  获得套接字绑定的本地IP地址
  InputStream getInputStream()
  获得该套接字的输入流
  int getLocalPort()
  获得套接字绑定的本地端口
  int getPort()
  获得套接字连接的远程端口
  OutputStream getOutputStream()
  获得该套接字的输出流
  int getSoTimeout()
  获得该套接字的最多等待时间
  void setSoTimeout(int timeout)
  设置该套接字的最多等待时间
  void shutdownInput()
  将该套接字的输入流置为流的末尾
  void shutdownOutput()
  禁止该套接字的输出流
  String toString()
  返回套接字的字符串形式
  ServerSocket类中的常用方法如表11-4。
  表11-4 ServerSocket类中的常用方法
  方 法
  简 要 说 明
  Socket accept()
  侦听一个将要创建Socket的连接并接受连接
  void close()
  关闭套接字
  InetAddress getInetAddress()
  获得服务器套接字的本地地址
  int getLocalPort()
  获得该套接字侦听的端口
  int getSoTimeout()
  获得该套接字的最多等待时间
  void setSoTimeout(int timeout)
  设置该套接字的最多等待时间
  String toString()
  返回代表该套接字的字符串
  2.Socket的通讯步骤
  进行一个Socket通讯,大致可以分为以下几个步骤:
  ⑴打开Socket连接
  要打开一个Socket连接,首先需要在服务器上创建

所属分类:编程相关.Net编程    作者:新浪博客    时间:2010-11-20 0:00:00

文章导航