《Socket(TCP,UDP)编程教材.ppt》由会员分享,可在线阅读,更多相关《Socket(TCP,UDP)编程教材.ppt(67页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、基于URL的高层次Java网络编程 URL(Uniform Resource Locator)是一致资源定位器的简称,它表示Internet上某一资源的地址。通过URL我们可以访问Internet上的各种网络资源,比如最常见的WWW,FTP站点。浏览器通过解析给定的URL可以在网络上查找相应的文件或其他资源。URL是最为直观的一种网络定位方法。使用URL符合人们的语言习惯,容易记忆,所以应用十分广泛。而且在目前使用最为广泛的TCP/IP中对于URL中主机名的解析也是协议的一个标准,即所谓的域名解析服务。使用URL进行网络编程,不需要对协议本身有太多的了解,功能也比较弱,相对而言是比较简单的,所
2、以在这里我们先介绍在Java中如何使用URL进行网络编程来引导读者入门。URL的组成 protocol:/resourceName协议名(protocol)指明获取资源所使用的传输协议,如http、ftp、gopher、file等,资源名(resourceName)则应该是资源的完整地址,包括主机名、端口号、文件名或文件内部的一个引用。例如:http:/ 协议名:/机器名文件名http:/:80/Gamelan/network.html#BOTTOM 协议名:/机器名端口号文件名内部引用 端口号是和Socket编程相关的一个概念,初学者不必在此深究,在后面会有详细讲解。内部引用是HTML中的标
3、记,有兴趣的读者可以参考有关HTML的书籍。创建一个URL 为了表示URL,中实现了类URL。我们可以通过下面的构造方法来初始化一个URL对象:(1)public URL(String spec);通过一个表示URL地址的字符串可以构造一个URL对象。URL urlBase=new URL(“http:/ URL(URL context,String spec);通过基URL和相对URL构造一个URL对象。URL net263=new URL(“http:/ index263=new URL(net263,“index.html”)(3)public URL(String protocol,S
4、tring host,String file);new URL(“http”,“”,“/pages/G.html”);(4)public URL(String protocol,String host,int port,String file);URL gamelan=new URL(http,80,Pages/Gwork.html);注意:注意:类URL的构造方法都声明抛弃非运行时例外(MalformedURLException),因此生成URL对象时,我们必须要对这一例外进行处理,通常是用try-catch语句进行捕获。格式如下:tryURL myURL=new URL()catch(Ma
5、lformedURLException e)/exception handler code here 一个URL对象生成后,其属性是不能被改变的,但是我们 可以通过类URL所提供的方法来获取这些属性:public String getProtocol()获取该URL的协议名。public String getHost()获取该URL的主机名。public int getPort()获取该URL的端口号,如果没 有设置端口,返回-1。public String getFile()获取该URL的文件名。public String getRef()获取该URL在文件中的相对 位置。public St
6、ring getQuery()获取该URL的查询信息。public String getPath()获取该URL的路径public String getAuthority()获取该URL的权限信息public String getUserInfo()获得使用者的信息public String getRef()获得该URL的锚 下面的例子中,我们生成一个URL对象,并获取它的各个属性。import .*;import java.io.*;public class ParseURLpublic static void main(String args)throws ExceptionURL Aur
7、l=new URL(http:/:80/docs/books/);URL tuto=new URL(Aurl,tutorial.intro.html#DOWNLOADING);System.out.println(protocol=+tuto.getProtocol();System.out.println(host=+tuto.getHost();System.out.println(filename=+tuto.getFile();System.out.println(port=+tuto.getPort();System.out.println(ref=+tuto.getRef();Sy
8、stem.out.println(query=+tuto.getQuery();System.out.println(path=+tuto.getPath();System.out.println(UserInfo=+tuto.getUserInfo();System.out.println(Authority=+tuto.getAuthority();当我们得到一个URL对象后,就可以通过它读取指定的WWW资源。这时我们将使用URL的方法openStream(),其定义为:InputStream openStream();方法openSteam()与指定的URL建立连接并返回InputStr
9、eam类的对象以从这一连接中读取数据。public class URLReader public static void main(String args)throws Exception /声明抛出所有例外URL tirc=new URL(“http:/ in=new BufferedReader(new InputStreamReader(tirc.openStream();/使用openStream得到一输入流并由此构造一个BufferedReader对象String inputLine;while(inputLine=in.readLine()!=null)/从输入流不断的读数据,直到
10、读完为止System.out.println(inputLine);/把读入的数据打印到屏幕上in.close();/关闭输入流 通过URL的方法openStream(),我们只能从网络上读取数据,如果我们同时还想输出数据,例如向服务器端的CGI程序发送一些数据,我们必须先与URL建立连接,然后才能对其进行读写,这时就要用到类URLConnection了。CGI是公共网关接口(Common Gateway Interface)的简称,它是用户浏览器和服务器端的应用程序进行连接的接口,有关CGI程序设计,请读者参考有关书籍。类URLConnection也在包中定义,它表示Java程序和URL在网
11、络上的通信连接。当与一个URL建立连接时,首先要在一个URL对象上通过方法openConnection()生成对应的URLConnection对象。例如下面的程序段首先生成一个指向地址http:/ netchinaren=new URL(http:/ tc=netchinaren.openConnection();catch(MalformedURLException e)/创建URL()对象失败catch(IOException e)/openConnection()失败 类URLConnection提供了很多方法来设置或获取连接参数,程序设计时最常使用的是getInputStream()和
12、getOutputStream(),其定义为:InputSteram getInputSteram();OutputSteram getOutputStream();通过返回的输入/输出流我们可以与远程对象进行通信。看下面的例子:URL url=new URL(http:/ con=url.openConnection();/由URL对象获取URLConnection对象DataInputStream dis=new DataInputStream(con.getInputSteam();/由URLConnection获取输入流,并构造DataInputStream对象PrintStream
13、ps=new PrintSteam(con.getOutupSteam();/由URLConnection获取输出流,并构造PrintStream对象String line=dis.readLine();/从服务器读入一行ps.println(client);/向服务器写出字符串 client其中backwards为服务器端的CGI程序。实际上,类URL的方法openSteam()是通过URLConnection来实现的。它等价于openConnection().getInputStream();基于URL的网络编程在底层其实还是基于下面要讲的Socket接口的。WWW,FTP等标准化的网络服
14、务都是基于TCP协议的,所以本质上讲URL编程也是基于TCP的一种应用。选择1、URL url=new URL(http:/);那么url.getFile()得到的结果是:A 263 B net C null D 二、多项选择二、多项选择 1、关于TCP/IP协议下面哪几点是错误的?A TCP/IP协议由TCP协议和IP协议组成 B TCP和UDP都是TCP/IP协议传输层的子协议 C Socket是TCP/IP协议的一部分 D 主机名的解析是TCP/IP的一部分2、下面哪些URL是合法的 A http:/166.111.136.3/index.html B ftp:/166.111.136.
15、3/incoming C ftp:/166.111.136.3:-1/D http:/166.111.136.3.3 3、下面哪几种方法是表示本机的 A localhost B 255.255.255.255 C 127.0.0.1 D 123.456.0.0 基于Socket(套接字)的低层次Java网络编程 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。在传统的UNIX环境下可以操作TCP/
16、IP协议的接口不止Socket一个,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。说Socket编程是低层次网络编程并不等于它功能不强大,恰恰相反,正因为层次低,Socket编程比基于URL的网络编程提供了更强大的功能和更灵活的控制,但是却要更复杂一些。由于Java本身的特殊性,Socket编程在Java中可能已经是层次最低的网络编程接口,在Java中要直接操作协议中更低的层次,需要使用Java的本地方法调用(JNI),在这里就不予讨论了。使用Socket进行Client/Server
17、程序设计的一般连接过程是这样的:Server端Listen(监听)某个端口是否有连接请求,Client端向Server端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client端都可以通过Send,Write等方法与对方通信。对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:(1)创建Socket;(2)打开连接到Socket的输入/出流 (3)按照一定的协议对Socket进行读/写操作;(4)关闭Socket.第三步是程序员用来调用Socket和实现程序功能的关键步骤,
18、其他三步在各种程序中基本相同。以上4个步骤是针对TCP传输而言的,使用UDP进行传输时略有不同,在后面会有具体讲解。创建Socket java在包中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用很方便。其构造方法如下:Socket(InetAddress address,int port);Socket(InetAddress address,int port,boolean stream);Socket(String host,int prot);Socket(String host,int prot,boolean
19、stream);Socket(SocketImpl impl)Socket(String host,int port,InetAddress localAddr,int localPort)Socket(InetAddress address,int port,InetAddress localAddr,int localPort)ServerSocket(int port);ServerSocket(int port,int backlog);ServerSocket(int port,int backlog,InetAddress bindAddr);其中address、host和port
20、分别是双向连接中另一方的IP地址、主机名和端口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可以用来创建Socket。count则表示服务端所能支持的最大连接数。例如:Socket client=new Socket(127.0.01.,80);ServerSocket server=new ServerSocket(80);注意,在选择端口时,必须小心。每一个端口提供
21、一种特定的服务,只有给出正确的端口,才能获得相应的服务。01023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23,所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。下面是一个典型的创建客户端Socket的过程。trySocket socket=new Socket(127.0.0.1,4700);/127.0.0.1是TCP/IP协议中默认的本机地址cat
22、ch(IOException e)System.out.println(Error:+e);这是最简单的在客户端创建一个Socket的一个小程序段,也是使用Socket进行网络通讯的第一步,程序相当简单,在这里不作过多解释了。在后面的程序中会用到该小程序段。下面是一个典型的创建Server端ServerSocket的过程。ServerSocket server=null;try server=new ServerSocket(4700);/创建一个ServerSocket在端口4700监听客户请求catch(IOException e)System.out.println(“can not l
23、isten to:”+e);Socket socket=null;try socket=server.accept();/accept()是一个阻塞的方法,一旦有客户请求,它就会返回一个Socket对象用于同客户进行交互catch(IOException e)System.out.println(Error:+e);以上的程序是Server的典型工作模式,只不过在这里Server只能接收一个请求,接受完后Server就退出了。实际的应用中总是让它不停的循环接收,一旦有客户请求,Server总是会创建一个服务线程来服务新来的客户,而自己继续监听。程序中accept()是一个阻塞函数,所谓阻塞性方
24、法就是说该方法被调用后,将等待客户的请求,直到有一个客户启动并请求连接到相同的端口,然后accept()返回一个对应于客户的socket。这时,客户方和服务方都建立了用于通信的socket,接下来就是由各个socket分别打开各自的输入/输出流。打开输入/出流 类Socket提供了方法getInputStream()和getOutStream()来得到对应的输入/输出流以进行读/写操作,这两个方法分别返回InputStream和OutputSteam类对象。为了便于读/写数据,我们可以在返回的输入/输出流对象上建立过滤流,如DataInputStream、DataOutputStream或Pr
25、intStream类对象,对于文本方式流对象,可以采用InputStreamReader和OutputStreamWriter、PrintWirter等处理。例如:PrintStream os=new PrintStream(new BufferedOutputStreem(socket.getOutputStream();DataInputStream is=new DataInputStream(socket.getInputStream();PrintWriter out=new PrintWriter(socket.getOutStream(),true);BufferedReader
26、 in=new ButfferedReader(new InputSteramReader(Socket.getInputStream();输入输出流是网络编程的实质性部分,具体如何构造所需要的过滤流,要根据需要而定,能否运用自如主要看读者对Java中输入输出部分掌握如何。每一个Socket存在时,都将占用一定的资源,在Socket对象使用完毕时,要其关闭。关闭Socket可以调用Socket的Close()方法。在关闭Socket之前,应将与Socket相关的所有的输入/输出流全部关闭,以释放所有的资源。而且要注意关闭的顺序,与Socket相关的所有的输入/输出该首先关闭,然后再关闭Sock
27、et。os.close();is.close();socket.close();尽管Java有自动回收机制,网络资源最终是会被释放的。但是为了有效的利用资源,建议读者按照合理的顺序主动释放资源。简单的Client/Server程序设计 下面我们给出一个用Socket实现的客户和服务器交互的典型的C/S结构的演示程序,读者通过仔细阅读该程序,会对前面所讨论的各个概念有更深刻的认识。程序的意义请参考注释。1.客户端程序 import java.io.*;import .*;public class TalkClient public static void main(String args)try
28、Socket socket=new Socket(“127.0.0.1”,4700);/向本机的4700端口发出客户请求BufferedReader sin=new BufferedReader(new InputStreamReader(System.in);/由系统标准输入设备构造BufferedReader对象PrintWriter os=new PrintWriter(socket.getOutputStream();/由Socket对象得到输出流,并构造PrintWriter对象BufferedReader is=new BufferedReader(new InputStreamR
29、eader(socket.getInputStream();/由Socket对象得到输入流,并构造相应的BufferedReader对象String readline;readline=sin.readLine();/从系统标准输入读入一字符串从系统标准输入读入一字符串while(!readline.equals(“bye”)/若从标准输入读入的字符串为若从标准输入读入的字符串为“bye”则停止循环则停止循环os.println(readline);/将从系统标准输入读入的字符串输出到将从系统标准输入读入的字符串输出到Server os.flush();/刷新输出流,使刷新输出流,使Serve
30、r马上收到该字符串马上收到该字符串 System.out.println(“Client:”+readline);/在系统标准输出上打印读入的字符串在系统标准输出上打印读入的字符串System.out.println(“Server:”+is.readLine();/从从Server读入一字符串,并打印到标准输出上读入一字符串,并打印到标准输出上 readline=sin.readLine();/从系统标准输入读入一字符串从系统标准输入读入一字符串/继续循环继续循环os.close();/关闭关闭Socket输出流输出流is.close();/关闭关闭Socket输入流输入流socket.cl
31、ose();/关闭关闭Socketcatch(Exception e)System.out.println(Error+e);/出错,则打印出错信息出错,则打印出错信息 2.服务器端程序 import java.io.*;import .*;import java.applet.Applet;public class TalkServerpublic static void main(String args)tryServerSocket server=null;try server=new ServerSocket(4700);/创建一个ServerSocket在端口4700监听客户请求ca
32、tch(Exception e)System.out.println(can not listen to:+e);/出错,打印出错信息 Socket socket=null;trysocket=server.accept();/使用accept()阻塞等待客户请求,有客户/请求到来则产生一个Socket对象,并继续执行catch(Exception e)System.out.println(“Error.”+e);/出错,打印出错信息String line;BufferedReader is=new BufferedReader(new InputStreamReader(socket.get
33、InputStream();/由Socket对象得到输入流,并构造相应的BufferedReader对象PrintWriter os=newPrintWriter(socket.getOutputStream();/由Socket对象得到输出流,并构造PrintWriter对象BufferedReader sin=new BufferedReader(new InputStreamReader(System.in);/由系统标准输入设备构造BufferedReader对象 System.out.println(Client:+is.readLine();/在标准输出上打印从客户端读入的字符串l
34、ine=sin.readLine();/从标准输入读入一字符串while(!line.equals(bye)/如果该字符串为 bye,则停止循环os.println(line);/向客户端输出该字符串os.flush();/刷新输出流,使Client马上收到该字符串System.out.println(Server:+line);/在系统标准输出上打印读入的字符串System.out.println(Client:+is.readLine();/从Client读入一字符串,并打印到标准输出上line=sin.readLine();/从系统标准输入读入一字符串/继续循环 os.close();/
35、关闭Socket输出流is.close();/关闭Socket输入流socket.close();/关闭Socketserver.close();/关闭ServerSocketcatch(Exception e)System.out.println(Error:+e);/出错,打印出错信息 从上面的两个程序中我们可以看到,socket四个步骤的使用过程。读者可以分别将Socket使用的四个步骤的对应程序段选择出来,这样便于读者对socket的使用有进一步的了解。读者可以在单机上试验该程序,最好是能在真正的网络环境下试验该程序,这样更容易分辨输出的内容和客户机,服务器的对应关系。同时也可以修改该
36、程序,提供更为强大的功能,或更加满足读者的意图。多选题1。下面正确的创建Socket的语句有?A Socket a=new Socket(80);B Socket b=new Socket(130.3.4.5,80);C ServerSocket c=new Socket(80)D ServerSocket d=new Socket(130.3.4.5,80)下面关于阻塞函数的论述,正确的有?A 阻塞函数是指无法返回的函数 B 阻塞函数是指网络过于繁忙,函数必须等待 C 阻塞函数是指有外部事件发生才会返回 的函数。D 阻塞函数如果不能马上返回,就会进入等待状态,把系统资源让给其他线程 单选欲构
37、造ArrayList类的一个实例,此类继承了List接口,下列哪个方法是正确的?A ArrayList myList=new Object();B List myList=new ArrayList();C ArrayList myList=new List();D List myList=new List();支持多客户的client/server程序设计 前面提供的Client/Server程序只能实现Server和一个客户的对话。在实际应用中,往往是在服务器上运行一个永久的程序,它可以接收来自其他多个客户端的请求,提供相应的服务。为了实现在服务器方给多个客户提供服务的功能,需要对上面的程
38、序进行改造,利用多线程实现多客户机制。服务器总是在指定的端口上监听是否有客户请求,一旦监听到客户请求,服务器就会启动一个专门的服务线程来响应该客户的请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的到来。线程简介 随着计算机的飞速发展,个人计算机上的操作系统也纷纷采用多任务和分时设计,将早期只有大型计算机才具有的系统特性带到了个人计算机系统中。一般可以在同一时间内执行多个程序的操作系统都有进程的概念。一个进程就是一个执行中的程序,而每一个进程都有自己独立的一块内存空间、一组系统资源。在进程概念中,每一个进程的内部数据和状态都是完全独立的。Java程序通过流控制来执行程序流,
39、程序中单个顺序的流控制称为线程,多线程则指的是在单个程序中可以同时运行多个不同的线程,执行不同的任务。多线程意味着一个程序的多行语句可以看上去几乎在同一时间内同时运行。线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制;但与进程不同的是,同类的多个线程是共享一块内存空间和一组系统资源,而线程本身的数据通常只有微处理器的寄存器数据,以及一个供程序执行时使用的堆栈。所以系统在产生一个线程,或者在各个线程之间切换时,负担要比进程小的多,正因如此,线程被称为轻负荷进程(light-weight process)。一个进程中可以包含多个线程。一个线程是一个程序内部的顺序控制流。1.进
40、程:每个进程都有独立的代码和数据空间(进程上下文),进程切换的开销大。2.线程:轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。3.多进程:在操作系统中,能同时运行多个任务程序。4.多线程:在同一应用程序中,有多个顺序流同时执行。Java内在支持多线程,它的所有类都是在多线程下定义的,Java利用多线程使整个系统成为异步系统。Java中的线程由三部分组成。1.虚拟的CPU,封装在java.lang.Thread类中。2.CPU所执行的代码,传递给Thread类。3.CPU所处理的数据,传递给Thread类。线程体(1)Java的线程是通过
41、java.lang.Thread类来实现的。当我们生成一个Thread类的对象之后,一个新的线程就产生了。此线程实例表示Java解释器中的真正的线程,通过它可以启动线程、终止线程、线程挂起等,每个线程都是通过类Thread在Java的软件包Java.lang中定义,它的构造方法为:public Thread(ThreadGroup group,Runnable target,String name);其中,group 指明该线程所属的线程组;target实际执行线程体的目标对象,它必须实现接口Runnable;name为线程名。Java中的每个线程都有自己的名称,Java提供了不同Thread
42、类构造器,允许给线程指定名称。如果name为null时,则Java自动提供唯一的名称。当上述构造方法的某个参数为null时,我们可得到下面的几个构造方法:public Thread();public Thread(Runnable target);public Thread(Runnable target,String name);public Thread(String name);public Thread(ThreadGroup group,Runnable target);public Thread(ThreadGroup group,String name);一个类声明实现Runna
43、ble接口就可以充当线程体,在接口Runnable中只定义了一个方法 run():public void run();任何实现接口Runnable的对象都可以作为一个线程的目标对象,类Thread本身也实现了接口Runnable,因此我们可以通过两种方法实现线程体。(一)定义一个线程类,它继承线程类Thread并重写其中的方法 run(),这时在初始化这个类的实例时,目标target可为null,表示由这个实例对来执行线程体。由于Java只支持单重继承,用这种方法定义的类不能再继承其它父类。(二)提供一个实现接口Runnable的类作为一个线程的目标对象,在初始化一个Thread类或者Thre
44、ad子类的线程对象时,把目标对象传递给这个线程实例,由该目标对象提供线程体 run()。这时,实现接口Runnable的类仍然可以继承其它父类。每个线程都是通过某个特定Thread对象的方法run()来完成其操作的,方法run()称为线程体。下图表示了java线程的不同状态以及状态之间转换所调用的方法。new Thread()New ThreadRunnableNotRunnableStart()Yield()DeadStop()Stop()orRun()Stop()1.创建状态创建状态(new Thread)执行下列语句时,线程就处于创建状态:Thread myThread=new MyTh
45、readClass();当一个线程处于创建状态时,它仅仅是一个空的线程对象,系统不为它分配资源。2.可运行状态可运行状态(Runnable)Thread myThread=new MyThreadClass();myThread.start();当一个线程处于可运行状态时,系统为这个线程分配了它需的系统资源,安排其运行并调用线程运行方法,这样就使得该线程处于可运行(Runnable)状态。需要注意的是这一状态并不是运行中状态(Running),因为线程也许实际上并未真正运行。由于很多计算机都是单处理器的,所以要在同一时刻运行所有的处于可运行状态的线程是不可能的,Java的运行系统必须实现调度来
46、保证这些线程共享处理器。3.不可运行状态(不可运行状态(Not Runnable)进入不可运行状态的原因有如下几条:1)调用了sleep()方法;2)调用了suspend()方法;3)为等候一个条件变量,线程调用wait()方法;4)输入输出流中发生线程阻塞;不可运行状态也称为阻塞状态(Blocked)。因为某种原因(输入/输出、等待消息或其它阻塞情况),系统不能执行线程的状态。这时即使处理器空闲,也不能执行该线程。4.死亡状态(死亡状态(Dead)线程的终止一般可通过两种方法实现:自然撤消(线程执行完)或是被停止(调用stop()方法)。目前不推荐通过调用stop()来终止线程的执行,而是让
47、线程执行完。线程体的构造线程体的构造 任何实现接口Runnable的对象都可以作为一个线程的目标对象,上面已讲过构造线程体有两种方法,下面通过实例来说明如何构造线程体的。(1)通过继承类Thread构造线程体 (2)通过接口构造线程体通过继承类Thread构造线程体class SimpleThread extends Thread public SimpleThread(String str)super(str);/调用其父类的构造方法public void run()/重写run方法for(int i=0;i 10;i+)System.out.println(i+getName();/打印次
48、数和线程的名字try sleep(int)(Math.random()*1000);/线程睡眠,把控制权交出去 catch(InterruptedException e)System.out.println(DONE!+getName();/线程执行结束public class TwoThreadsTest public static void main(String args)new SimpleThread(First).start();/第一个线程的名字为Firstnew SimpleThread(Second).start();/第二个线程的名字为Second 通过接口构造线程体 pu
49、blic class Clock extends java.applet.Applet implements Runnable /实现接口Thread clockThread;public void start()/该方法是Applet的方法,不是线程的方法if(clockThread=null)clockThread=new Thread(this,Clock);/*线程体是Clock对象本身,线程名字为Clock*/clockThread.start();/启动线程 public void run()/run()方法中是线程执行的内容while(clockThread!=null)repaint();/刷新显示画面try clockThread.sleep(1000);/睡眠1秒,即每隔1秒执行一次 catch(InterruptedException e)public void paint(Graphics g)Date now=new Date();/获得当前的时间对象g.drawString(now.getHours()+:+now.getMinutes()+:+now.getSeconds(),5,10);/显示当前时间public void stop()/该方法是Applet的方法,不是线程的方法clockThread.stop();clockThread=null
限制150内