【教学课件】第十一章Java的网络功能.ppt
第十一章Java的网络功能,主要内容:1、了解URL的构成,学会利用URL读取网络资源2、熟悉包3、了解TCP/IP协议4、掌握Socket的基本使用方法,学会建立Socket连接,实现客户端和服务器端通信5、掌握利用UDP通信的方法6、了解多客户端通信概念,掌握进行多客户通信的方法,11.1基本知识11.1.1 计算机网络就是利用通信线路连接起来的、相互独立的,计算机集合计算机协议就是针对计算机进行通信时,关于信息交互方式、交互秩序等所作出的规定。常用协议:TCP、IP、UDP、SNMP、SMTP、FTP、HTTP,11.1.3 Java的网络功能,作为一门成功的网络编程语言,Java为用户提供了十分完善的网络功能:,获取网络上的各种资源与服务器建立连接和通信传递本地数据,当一个进程向另一个进程发送数据时,只需将数据写入到相应接口的输出流上,而另一个进程在接口的“另一端”从输入流上读取数据,Java是通过使用流模式来实现网络信息交互的。这种模式下,一个接口同时拥有两个流输入流和输出流。,11.1.4 通信模式,J包提供了低级和高级的网络功能。它包含了大部分用于访问网络资源的类。,11.1.5 J包,一、用于网络定位的类URL类URLConnection类HttpURLConnection类InetAddress类,二、用于建立服务器和客户端通信的类Socket类ServerSocket类,三、基于数据报的通信DatagramSocketDatagramPacket类,11.2网络功能与使用方法,11.2.1 URL这种方法是通过URL的网络资源表达式形式确定数据在网络中的位置,利用URL类中提供的方法,直接读入网络中的数据,或者将本地数据传送到网络的另一端。,网络功能按层次与使用方法分为三类,11.2.2 Socket是指两个程序通过网络进行通信的一种方式。在TCP/IP协议下,客户端和服务器端通常使用socket来进行信息交流。这种方式也是传统中常用的一种方式。,11.2.3 DataGramDatagram方式是三种网络功能中最低级的一种,它是一种面向非连接的、以数据报方式工作的通信。适用于网络状况不稳定下的数据传输和访问,11.3URL,11.3.1 Internet上的寻址,IP是标识连接到Internet上的计算机的唯一的数字地址。,IP地址实际上是用32位二进制数组成,如:202.199.28.6.,人们更熟悉的是它的符号形式,也就是域名,如:。,URL标识了计算机上的所有资源,URL是Unoform Resource Locator的缩写。,URL的基本结构::/:password/,如:http:/,download-windows.html,URL对象是通过定义在J包中的URL类来进行构造的。构造方法有四种:1.Public URL(String spec)spec表示URL的字符串例:URL url1=new/”)2.Public URL(URL context,String spec)用于表示相对URL位置的定义。例:URL url2=new URL(getCodeBase(),”myfile.text”),3.public URL(String protocol,String host,String file)4.public URL(String protocol,String host,int port,String file)String protocol协议String host主机名int port端口String file文件名,二.与URL相关的异常在使用上述构造方法时,会存在某些问题,因此,在类URL的构造方法中都声明抛出非运行时异常MalformedURLException,所以在生成URL对象时要捕获,进行异常处理。,例:URLurl3=newURL(“http”,”,”myfile.txt”)例:URLurl4=newURL(“http”,”,80,”myfile.txt”),三.常用方法String getProtocol()获取传输协议String getHost()获取主机名称String getPort()获取通信端口号String getFile()String toString()获取资源文件名称,TryURLurl3=newURL(“http”,”,”myfile.txt”)catch(MalformedURLException e).,创建URL对象、链接到相应主页的代码:try url1=new URL(s1);catch(MalformedURLException g)(“不正确的 URL:+url1);text1.setText(哈尔滨工业大学);getAppletContext().showDocument(url1);,例:链向另外的Web页UrlEx.java,用于建立流的代码:tryurl=new URL(getCodeBase(),ReadFromUrl.java);dis=new DataInputStream(url.openStream();catch(MalformedURLException q)System.out.println(MalformedURLException:+q);,InputStream openStream()打开输入流 用以读取URL位置的数据,其返回值是一个InputStream数据流,例:读指定文件在屏幕上显示 ReadFromURL.java,从流中读取数据的代码:try while(readstring=dis.readLine()!=null)e.drawString(readstring,10,i);i=i+20;e.drawString(end of the file,10,i);dis.close();catch(IOException g)System.out.println(IOException:+g);,11.4同服务器进行通信,11.4.1 套接字(Socket和ServerSocket),IP地址标识Internet上的计算机端口号标识正在计算机上运行的进程,端口号定义为0-65535之间的一个16位整数,其中01023被一些特定服务器占用如:telnet占用端口23http占用端口80SMTP占用端口25,端口号与IP地址的组合得出一个网络套接字,普通用户端口号只能是1024-65535之间,11.4.2 客户端建立套接字,客户端程序可使用Socket类建立与服务器的套接字连接,Socket类的构造方法是:,例:Socket mysocket=new Socket(“http:/,Socket(String host,int port)host-服务器地址 port-端口号,当 用本地机充当服务器时,host用“localhost”表示,Socket mysocket=new Socket(“localhost”,2880);,建立套接字时可能发生IOException异常,应当捕获,格式如下:try Socket mysocket=new Socket(“http:/”,2880);catch(IOException e).,当套接字连接mysocket建立后可使用getInputStream()方法获得一个输入流,用于接收服务器发来的信息,使用getOutputStream()方法获得一个输出流,用于将信息发送至服务器端,11.4.3 建立服务器套接字,为响应客户端的呼叫,服务器端必须建立一个等待接收客户套接字的服务器套接字,可用ServerSocket类创建服务器套接字,ServerSocket的构造方法是:ServerSocket(int port)port-客户端建立连接时使用的同一端口号,ServerSocket serversocket=new ServerSocket(2880);,Socket mysocket=new Socket(“localhost”,2880);,建立服务器套接字时可能发生IOException异常,应当捕获,格式如下:,try ServerSocket serversocket=new ServerSocket(2880);catch(IOException e).,11.4.4 接收客户端套接字,当服务器端的套接字连接serversocket建立后,可使用ServerSocket类中的accept()方法接收客户端套接字mysocket,格式为:,接收客户端套接字的过程也可能发生IOException异常,应当捕获:try Socket sc=serversocket.accept();catch(IOException e).,Socket sc=serversocket.accept();,收到客户套接字后,放到一个Socket对象sc中,那么服务器套接字sc就是客户端套接字mysocket。服务器端也可以通过服务器套接字sc使用方法 getInputStream()获得一个输出流有,用于向客户端发送信息使用方法 getOutputStream()获得一个输入流,用于接收客户端发来的信息,客户端,服务器端,ServerSocket(port),accept(),OutputStream,InputStream,OutputStream,InputStream,close(),close(),Socket(host,port),建立客户端套接字,建立服务器端套接字,接收客户套接字,获得客户端输入输出流,获得服务器端输入输出流,网络连接模式,至此,就将网络通信转化为IO操作,trymysocket=new Socket(localhost,3456);in=new DataInputStream(mysocket.getInputStream();out=new DataOutputStream(mysocket.getOutputStream();,建立套接字,获得IO对象,out.writeUTF(hello!);,向服务器发送信息,while(true)s=in.readUTF();if(s!=null)break;mysocket.close();,等待接收服务器发送的信息,例:一个简单的通信程序客户端的主要代码,catch(IOException e)System.out.println(not connected);System.out.println(s);,tryserver=new ServerSocket(3456);catch(IOException e1)System.out.println(Error:+e1);,建立服务器端套接字,try client=server.accept();in=new DataInputStream(client.getInputStream();out=new DataOutputStream(client.getOutputStream();,接收客户端套接字,服务器端程序主要代码,while(true)s=in.readUTF();if(s!=null)break;out.writeUTF(Hello,i am server.);you.close();catch(IOException e)System.out.println(Erro:+e);,接收客户端信息并给出应答,五.服务多个客户,如果允许多个客户同时连接到服务器上,可以利用多线程来实现。,s=new ServerSocket(portnub);for(;)Socket incoming=s.accept();.new ThreadHandler(incoming,i).start();i+;,public void run()try DataInputstream in=new DataInputstream(incoming.getInputStream();DataOutputStream out=new DataOutputStream(incoming.getOutputStream();out.println(Hello!Enter BYE to exit.);boolean done=false;while(!done)String str=in.readLine();if(str=null)done=true;。,例:一个聊天程序,11.5基于数据报的通信,数据报是一种无连接的通信服务数据报的特点:速度快 稳定性差,DatagramSocket类实现了一种适用于数据报的socket,用于监听本地主机上的指定端口,DatagramPacket类实现了从指定的缓冲区接收数据,通过DatagramSocket实例调用receive()使其处于堵塞状态,一直到接收到数据为止。,11.5.1 接收数据报,创建一个DatagramSocket实例用来监听本地主机上的指定端口 DatagramSocket socket=new DatagramSocket(9999);,创建一个Datagrampacket实例,用以从指定的缓冲区接收数据DatagramPacket packet=new DatagramPacket(buffer,buffer.length);,用DatagramSocket提供的方法receive()接收数据socket.receive(packet);,例:下面为一接收数据报程序 public class UDPGet extends Frame implements ActionListenerTextArea textArea1=new TextArea();Button button1=new Button();,public static void main(String args)UDPGet get=new UDPGet();get.setLocation(100,100);get.setSize(300,200);get.show();get.waitForData();,public UDPGet()try this.setTitle(接收数据报);textArea1.setText();button1.setLabel(退出);this.add(textArea1,BorderLayout.CENTER);this.add(button1,BorderLayout.SOUTH);button1.addActionListener(this);catch(Exception e)e.printStackTrace(),void waitForData()try byte buffer=new byte1024;DatagramPacket packet=new DatagramPacket(buffer,buffer.length);DatagramSocket socket=new DatagramSocket(9999);,while(true)socket.receive(packet);String s=new String(buffer,0,packet.getLength();textArea1.append(s+n);packet=new DatagramPacket(buffer,buffer.length);catch(Exception e),public void actionPerformed(ActionEvent e)Component com=(Component)e.getSource();if(com.equals(button1)System.exit(0);,二.发送数据报,首先创建一个DatagramPacket实例,用于指定要发送的数据、数据长度、目的地主机名的端口号DatagramPacket packet=new DatagramPacket(message,len,”localhost”,9999);message为一byte型数组,再用DatagramSocket类对象的成员方法send()来发送数据socket.send(packet);,例:下面为一个发送数据的例子,public class UDPSend extends Frame implements ActionListener GridLayout net;TextField textField1=new TextField();Button button1=new Button();Button button2=new Button();,public static void main(String args)UDPSend send=new UDPSend();send.setLocation(100,100);send.setSize(300,150);send.show();,public UDPSend()try this.setTitle(发送数据报);button1.setLabel(发送);button2.setLabel(退出);net=new GridLayout(3,1);setLayout(net);this.add(textField1,null);this.add(button1,null);,this.add(button2,null);textField1.addActionListener(this);button2.addActionListener(this);button1.addActionListener(this);catch(Exception e)e.printStackTrace();,void sendData()try String msg=textField1.getText();if(msg.equals()return;textField1.setText();InetAddress address=InetAddress.getByName(localhost);int len=msg.length();byte message=new bytelen;msg.getBytes(0,len,message,0);DatagramPacket packet=new DatagramPacket(message,len,address,9999);DatagramSocket socket=new DatagramSocket();socket.send(packet);catch(Exception e)public void actionPerformed(ActionEvent e)Component com=(Component)e.getSource();if(com.equals(button1)sendData();else if(com.equals(button2)System.exit(0);else sendData();,void sendData()try String msg=textField1.getText();if(msg.equals()return;textField1.setText();InetAddress address=InetAddress.getByName(localhost);int len=msg.length();,byte message=new bytelen;msg.getBytes(0,len,message,0);DatagramPacket packet=new DatagramPacket(message,len,address,9999);DatagramSocket socket=new DatagramSocket();socket.send(packet);catch(Exception e).,public void actionPerformed(ActionEvent e)Component com=(Component)e.getSource();if(com.equals(button1)sendData();else if(com.equals(button2)System.exit(0);else sendData();,