java(教学0)韩建雷java-网络编程.ppt
第10章 网络编程,HTTP概述 URL URLConnection读写 InetAddres类 Socket 数据报,本章内容,HTTP概述,1.统一资源定位器URL URL-Uniform Resource Locator,表示Internet上某一资源的地址。浏览器通过解析给定的URL可以在网络上查找相应的文件或其他资源。,2URL的组成protocol:/:port_number/file_name其中:协议名(protocol):指明获取资源所使用的传输协议,如http、ftp、gopher、file等。Host_name:资源名(resourceName)所在的主机。Port_nubmer:连接时所使用的通信端口号File_name:该资源在主机的完整文件名。,HTTP概述,例1:,协议名称,主机名,例2:http:/:80/Gamelan/network.html,-协议名:/主机名端口号文件名,文件,HTTP概述,3基于TCP/IP编程的两个协议目前在Internet上使用最为广泛的协议是TCP/IP协议 1)TCP 是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方在进行数据传输前必须进行连接(成对的两个socket之间必须建立连接)。,HTTP概述,2)UDPUDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址。它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。,HTTP概述,在Java语言中,可以使用三种方式实现网络编程:(1)URL编程(获取URL属性信息)(2)Socket编程(基于TCP 的C/S)(3)Datagram编程(UDP),HTTP概述,包-URL类-URLconnection类-Socket类-ServerSocket类-DatagramPacket类-DatagramSocket类-MulticastSocket类,TCP实现网络通信,UDP实现网络通信,HTTP概述,URL,本节主要内容:URL构造方法URL类的其他方法URL相关的异常从URL读取WWW网络数据,1)public URL(String spec);使用URL对象的字符串spec来构造一个URL对象。例1:URL url=new URL(http:/www.),构造方法,2)public URL(URL baseurl,String spec);通过基地址URL和表示相对路径的字符串构造一个URL对象。例2:URL net263=new URL(http:/URL index263=new URL(net263,index.html),基地址,构造方法,3)public URL(String protocol,String host,String file);通过协议名、主机名和文件名构造一个URL对象。例3:URL u1=new URL(http,/pages/G.html);,构造方法,4)public URL(String protocol,String host,int port,String file);通过协议名、主机名、端口号和文件名构造一个URL对象。例4:URL g1=new URL(http,“,80,“07/1208/16/3v2007j.html);,构造方法,URL类的其他方法,获取URL对象属性的方法:public String getProtocol():获取该URL的协议名 public String getHost():获取该URL的主机名 public String getPort():获取该URL的端口号 public String getPath():获取该URL的文件路径,public String getFile():获取该URL的文件名 public String getRef():获取该URL在文件中的相对位置 public String getQuery():获取该URL的查询名,也可使用下列方法将URL对象的内容以字符串的形式来表示:String toString();String toExternalForm();,URL类的其他方法,与URL相关的异常,URL类的每个构造方法在URL地址残缺或无法解释时,都将抛出MalformedURLException异常。一般将相关语句放入trycatch语句块中。格式如下:try URL myURL=new URL()catch(MalformedURLException e)/exception handler code here,URL编程步骤:1)导入包;2)创建URL对象(URL构造方法)3)获取URL对象属性 或利用URL对象读入数据,例5:URL url1,url2,url3;try url1=new URL(“file:/D:/image/example.gif”);url2=new URL(“http:/url3=new URL(url2,“test.gif”);catch(MalformedURLException e)DisplayErrorMessage();.,例6:获取URL对象属性,try/创建URL对象URL ur1=new URL(http:/输出URL对象的有关信息System.out.println(URL对象字符串:+ur1.toString();System.out.println(URL对象文件:+ur1.getFile();,System.out.println(URL对象地址:+ur1.getHost();System.out.println(URL对象端口:+ur1.getPort();System.out.println(URL对象协议:+ur1.getProtocol();catch(MalformedURLException e)System.out.println(错误的URL对象。);,获取URL对象属性的运行结果,从URL读取WWW网络数据,URL类定义了openStream()方法用以读取URL地址的数据,其定义为:public final InputStream openStream()thorws IOException;,例7:从URL中读取数据,URL google=new URL(“http:/);BufferedReader in=new BufferedReader(new InputStreamReader(google.openStream();String inputLine;while(inputLine=in.readLine()!=null)System.out.println(inputLine);in.close();.,从URL中读取数据的运行结果,基于URLConnection的读写,1.URLConnection类 URL的方法openStream()只能从网络上读取数据,而不能写。URLConnection是封装访问远程网络资源一般方法类,通过它可以建立与远程服务器的连接,检查远程资源的一些属性。,URL类中的方法openConnection()可以对URL指向的网络资源进行读写。public URLConnetion openConnection();作用:尝试连接URL指向的网络资源,然后返回封装了操作该连接的类的一个实例。,基于URLConnection的读写,例8:try/先创建一个URL对象url1 URL url1=new URL(http:/);/创建到url1的一个连接对象con URLConnection con=url1.openConnection();catch(MalformedURLException)catch(IOException),2URLConnetion类中的常用方法 public InputStream getInputStream();public OutputStream getOutputStrem();public URl getURL();,基于URLConnection的读写,3.URLConnection读/写编程步骤 1)创建一个URL对象u1;2)使用URLConnection类中的openConnection()方法创建到URL的一个连接对象:URLConnection u1.openConnection()成功,返回一个URLConnection对象不成功,抛出IOException异常 3)进行数据的读或写操作;4)关闭流,基于URLConnection的读写,4从URLConnection读,URLConnection类的读写渠道 getInputStream(),基于URLConnection的读写,例9:采用URLConection 从URL读取数据 String inputLine;System.out.println(gl.getContentLength();System.out.println(gl.getDate();System.out.println(gl.getLastModified();System.out.println(gl.getURL();System.out.println(gl.toString();,基于URLConnection的读写,URL google=new URL(http:/localhost:8080/examples/jsp/datatreat.jsp);BufferedReader in=new BufferedReader(new InputStreamReader(google.openStream();String inputLine;while(inputLine=in.readLine()!=null)System.out.println(inputLine);in.close();,基于URLConnection的读写,从URLConection读取数据的运行结果,4.对RLConnection写,setDoOutput(true),getOutputStream(),什么情况下有必要向URL写信息呢?-表单(Form)与CGI有交互的网页-使用POST方式向CGI传送信息,基于URLConnection的读写,例10:向一个RLConnection写 URL url=new URL(http:/);URLConnection connection=url.openConnection();connection.setDoOutput(true);PrintWriter out=new PrintWriter(connection.getOutputStream();out.println(string);out.close();,InetAddres类,类表示一个 Internet Protocol(IP)地址。应用程序必须使用方法 getLocalHost,getByName,或 getAllByName 来创建新的 InetAddress 实例。例11:InetAddress ia=new InetAddress();,其他方法 1)public byte getAddress()返回这个 InetAddress 对象的原始 IP 地址。2)public static InetAddress getAllByName(String)throws UnknownHostException 给定主机名,确定该主机的所有 IP 地址。3)public static InetAddress getByName(String host)throws UnknownHostException 给定主机名,确定该主机的所有 IP 地址。4)public String getHostAddress()返回IP 地址串%d.%d.%d.%d,InetAddres类,5)public String getHostName()返回此地址的全限定主机名。6)public static InetAddress getLocalHost()返回本地主机。7)public String toString()把此IP 地址转换为 String 类型。上述1)-4)方法均要抛出UnknownHostException 异常。,InetAddres类,例12:InetAddress 获取 IP地址import.*;public class getip public static void main(String args)throws UnknownHostException InetAddress ad=InetAddress.getByName(localhost);System.out.println(主机名:+ad.getHostName();System.out.println(主机地址:+ad.getHostAddress();System.out.println(ad.getCanonicalHostName();System.out.println(本地地址:+ad.getAddress();System.out.println(本地主机名:+ad.getLocalHost();,netAddress类获取IP地址,socket,Socket是网络程序中最常用的方式,用于建立两个不同程序之间通过网络进行通信的信道。Java语言提供了两种Socket通信方式:TCP SocketUDP Socket,套接字是IP与端口的组合,可以分辨在internet上运行的程序,socket通信一般过程,Socket通常用来实现客户/服务器程序。为了让客户机知道如何与相应的服务进程建立通信联系,一般系统为一些常用的服务类型分配了默认端口号:,Socket进行C/S程序设计的一般连接过程:Server端监听某个端口是否有连接请求;Client端向Server端发出连接请求;Server端向Client端发回accpet消息。这样一个连接就建立起来,Server端和Client端都可以通过send、write等方法与对方通信。,socket通信一般过程,Server,ServerSocket(port#),Socket socket=ServerSocket.accept(),接收连接,OutputStream,InputStream,Close Socket,Client,Socket(host,port#),与服务器建立连接,OutputStream,InputStream,Close Socket,socket,TCP协议 Socket通信,socket通信一般过程,例13:显示服务器与客户机间的通信(服务器端),PrintStream ps=null;DataInputStream dis=null;String username;ServerSocket serverSocket=null;Socket clientSocket=null;,try serverSocket=new ServerSocket(1111);catch(IOException e)System.out.println(“Error”+e);System.exit(1);,try clientSocket=serverSocket.accept();catch(IOException e)System.out.println(Accept failed.);System.exit(1);,创建服务器(端口号),定义数据成员,服务器等待网络连接,Socket编程步骤 应用Socket进行网络编程,基本结构都是包括下面4个步骤:(1)创建Socket;(2)打开连接到Socket的输入/出流;(3)按照一定的协议对Socket进行读/写操作;(4)关闭Socket。,socket通信一般过程,java在包中提供了Socket类,表示客户端创建对象来建立与服务器的连接。1.socket构造方法 Socket(InetAddress address,int port);Socket(String host,int port);Socket(String host,int port,InetAddress localAddr,int localPort);Socket(InetAddress address,int port,InetAddress localaddr,int localPort);,例14:Socket client=new Socket(127.0.01.,80);Socket cc=new Socket(“”,80);2.读/写方法 1)public InputStream getInputStream()throws IOException 功能:从 Socket 中获得一个输入流,用于从 Socket 中读数据,抛出 I/O 异常。2)public OutputStream getOutputStream()throws IOException 功能:从 Socket 中获得一个输出流,用于从 Socket 中写数据,抛出 I/O 异常。3)public void close();关闭流,3基于TCP协议的的客户端编程步骤 1)创建一个指向一个服务器固定端口的Socket。例15:Socket sock=new Socket(“192.168.12.67”,8000);2)获得输入/输出流,进行数据的读/写操作。例16:/获取输入流 BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream();/获取输出流 PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),Java 语言为服务器端程序设计提供了 ServerSocket 类。该类允许程序绑定一个端口,等待客户端程序请求,然后根据客户端的请求执行相应操作,并对请求作出响应。,1.ServerSocket的构造方法 ServerSocket(int port);ServerSocket(int port,int backlog);ServerSocket(int port,int backlog,InetAddress bindAddr);例17:ServerSocket server=new ServerSocket(4460);ServerSocket sr=new ServerSocket(4460,10);,2监听方法 public Socket accept();功能:等待客户端的连接,在等待客户请求的过程中,方法 accept()将处于阻塞状态(即无限循环状态),直到接收到连接请求,返回一个用于连接客户端 Socket 的 Socket 实例。,例18:ServerSocket server=null;try server=new ServerSocket(4700);/创建一个ServerSocket在端口4700监听客户请求catch(IOException e)System.out.println(can not listen to:+e);Socket socket=null;try socket=server.accept();/监听catch(IOException e)System.out.println(Error:+e);,3基于Socket编程服务器端编程步骤 1)以某端口号为参数调用ServerSocket类的构造方法,创建一个ServerSocket对象,服务器端程序将在这个端口上监听、等待客户程序发来的请求。如上例。,2服务程序使用ServerSocket对象的方法accept(),等待接收某客户端程序发出的连接请求。例19:Socket soc=server.accept();通过Socket对象可获取客户端的相关信息。例20:clientIp=soc.getInetAddress();也可以利用Socket类提供的方法 getInputStream()和getOutputStream()来创建输入/输出流。例21:InputStream is=soc.getInputStream();OutputStream os=soc.getOutputStream();,3输入/输出 程序对socket的输入/输出流进行读/写操作都和对普通的输入/输出流进行读/写基本一样。但是需要在这两个流对象的基础上建立易于操作的数据流如DataInputStream、DataOutputStream或PrintStream。例22:DataInputStream in=new DataInputStream(is);DataOutputStream out=new DataOutputStream(os);PrintStream pout=new PrintStream(os);,另外为了便于输出字符或汉字,可以使用下列输出/输入流:BufferedReader in=new BufferedReader(new InputStreamReader(is);BufferedWriter out=new BufferedWriter(new OutputStremWriter(os);PrintWriter pout=new PrintWriter(new BufferedWriter(new OutputStreamWriter(os),true);,Socket应用,例23:基于连接的Client/Server程序1.Client端程序import.*;import java.io.*;public class JabberClient public static void main(String args)throws IOException InetAddress addr=InetAddress.getByName(null);System.out.println(addr=+addr);BufferedReader fin=new BufferedReader(new InputStreamReader(System.in);Socket socket=new Socket(addr,8080);,try System.out.println(socket=+socket);BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream();PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),true);,Socket应用,while(true)String str=fin.readLine();if(str.equals(exit)out.println(exit);break;else out.println(str);String s=in.readLine();System.out.println(server response:+s);,Socket应用,/关闭连接 finally System.out.println(closing.);socket.close();,Socket应用,2.服务器端程序,public class JabberServer public static void main(String args)throws IOException ServerSocket s=new ServerSocket(8080);Socket socket;System.out.println(Started:+s);,try socket=s.accept();try System.out.println(Connection accepted:+socket);BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream();PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),true);,2.服务器端程序,while(true)String str=in.readLine();if(str.equals(exit)break;System.out.println(Echoing:+str);out.println(server received+str);finally System.out.println(closing.);socket.close();finally s.close();,2.服务器端程序,客户/服务器通信,例24:多线程服务实现,基本方法:在服务器程序里创建单个ServerSocket对象,并调用accept()方法来等候一个新连接。一旦调用accept()方法成功,就会获得一个socket对象,并用它新建一个线程,令其只为那个特定的客户服务。然后再调用accept方法,等候下一个新的连接请求。,多线程服务器程序:import java.io.*;import.*;public class MultiTalkServer/静态成员变量,记录当前客户的个数 static int clientnum=0;public static void main(String args)throws IOException ServerSocket serverSocket=null;boolean listening=true;try serverSocket=new ServerSocket(4700);/创建一个ServerSocket在端口4700监听客户请求catch(IOException e),System.out.println(Could not listen on port:4700.);/出错,打印出错信息 System.exit(-1);/退出 while(listening)/永远循环监听 new ServerThread(serverSocket.accept(),clientnum).start();/监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动之clientnum+;/增加客户计数serverSocket.close();/关闭ServerSocket,线程程序:,public class ServerThread extends Thread Socket socket=null;/保存与本线程相关的Socket对象 int clientnum;/保存本进程的客户计数 public ServerThread(Socket socket,int num)/构造函数 this.socket=socket;/初始化socket变量 clientnum=num+1;/初始化clientnum变量 public void run()/线程主体try String line;BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream();/由Socket对象得到输入流,并构造相应的BufferedReader对象,PrintWriter os=new PrintWriter(socket.getOutputStream();/由Socket对象得到输出流,并构造PrintWriter对象 BufferedReader sin=new BufferedReader(new InputStreamReader(System.in);/由系统标准输入设备构造BufferedReader对象 System.out.println(Client:+clientnum+is.readLine();/在标准输出上打印从客户端读入的字符串 line=sin.readLine();/从标准输入读入一字符串while(!line.equals(bye)/如果该字符串为 bye,则停止循环 os.println(line);/向客户端输出该字符串 os.flush();/刷新输出流,使Client马上收到该字符串,System.out.println(Server:+line);/在系统标准输出上打印该字符串 System.out.println(Client:+clientnum+is.readLine();/从Client读入一字符串,并打印到标准输出上line=sin.readLine();/从系统标准输入读入一字符串/继续循环os.close();/关闭Socket输出流is.close();/关闭Socket输入流socket.close();/关闭Socket/server.close();/关闭ServerSocketcatch(Exception e)System.out.println(Error:+e);/出错,打印出错信息,2.客户端程序,try Socket socket=new Socket(127.0.0.1,4700);BufferedReader sin=new BufferedReader(new InputStreamReader(System.in);PrintWriter os=new PrintWriter(socket.getOutputStream();BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream();String readline;readline=sin.readLine();/从系统标准输入读入一字符串,while(!readline.equals(bye)os.println(readline);os.flush();System.out.println(Client:+readline);System.out.println(Server:+is.readLine();readline=sin.readLine();os.close();/关闭Socket输出流is.close();/关闭Socket输入流socket.close();/关闭Socketcatch(Exception e)System.out.println(Error+e);/出错,则打印出错信息,图12-5 多线程服务实现,数据报,UDP 编程主要有以下几个步骤:(1)创建包括有目的地址的数据报。(2)创建一个 Socket,用于发送或接收数据报。(3)发送数据报。(4)等待服务器响应。(5)从响应数据报中抽取信息并显示。Java 提供的有关 UDP 编程的类有 DatagramPacket 类和 DatagramSocket 类。,DatagramPacket,DatagramPacket 类表示一个数据报,有两个作用:1)在发送 UDP 数据之前,需要用 DatagramPacket 类封装一个数据报,可以包括发送的目的地址和端口号;2)当接收到一个 UDP 数据报后,需要用 DatagramPacket 类读取数据报中的各种信息。,1.构造方法 1)public DatagramPacket(bytebuf,int offset,int length);作用:使用指定字节数组的指定位置和指定长度的 DatagramPacket 类对象,指定长度必须小于或等于数组长度,2)public DatagramPacket(bytebuf,int length);作用:使用指定数组长度构造 DatagramPacket 对象,指定长度必须小于或等于数组长度,3)public DatagramPacket(bytebuf,int offset,int length,InetAddress address,int port);作用:使用指定数组、数组位置、数据长度、IP 地址和端口号构造 DatagramPacket 对象,指定长度必须小于或等于数组长度,4)public DatagramPacket(bytebuf,int length,InetAddress address,int port);作用:使用指定数组、数据长度、IP 地址和端口构造 DatagramPacket 对象,指定长度必须小于或等于数组长度 例:DatagramPacket packet=new DatagramPacket(buf,256);,2其他方法 public InetAddress getAddress();返回数据报中包含的 IP 地址。public int getPort();返回数据报中的端口信息。public bytegetData();返回数据报中所数据信息。public int getLength();返回数据长度。,DatagrameSocket,DatagramSocket 类用来创建一个 UDP Socket,用来在程序间建立传递数据服的通信连接,实现数据报的发送和接收过程。DatagramSocket是用来发送和接受DatagramSPacket的机制。,1构造方法 1)public DatagramSocket();作用:创建一个 UDP Socket,系统给它分配一个端口号 2)public DatagramSocket(int port);作用:创建一个 UDP Socket,编程人员给它分配一个端口号 3)public DatagramSocket(int port,InetAddress laddr);作用:创建一个 UDP Socket,并绑定到参数所示的地址和端口号上。端口号必须在 0 和 65535 之间。,DatagrameSocket,2其他方法 public synchronized void receive(DatagramPacket p);该方法运行后将进入阻塞状态,直到接收到一个数据报 public synchronized void close();关闭 UDP Server public void sen(DatagramPacket p);数据报的传送,应用,在接收数据前,应该生成一个DatagramPacket对象,给出接收数据的缓冲区及其长度。然后调用DatagramSocket 的方法receive()等待数据报的到来,receive()将一直等待,直到收到一个数据报为止。例:DatagramPacket packet=new DatagramPacket(buf,256);Socket.receive(packet);,发送数据前,也要先生成一个新的DatagramPacket对象,在给出存放发送数据的缓冲区的同时,还要给出完整的目的地址,包括IP地址和端口号。发送数据是通过DatagramSocket的方法send()实现的,send()根据数据报的目的地址来寻径,以传递数