02Socket编程.ppt
Java Web应用开发应用开发 第一章第一章SOCKETSOCKET编程编程回顾回顾Java课程课程Java语言的基本语法OOP思想封装、继承和多态异常处理java.lang包、java.util包JDBC数据库访问技术本章相关词汇本章相关词汇单 词说 明Internet Protocol(IP)互联网协议net网络,网状物socket套接字,插座server服务器,服务端client客户,客户端port端口accept接收,认可本章目标本章目标网络基础知识IP地址与端口包InetAddressSocketServerSocket扩展IO流的相关知识计算机网络与通信计算机网络与通信通信是人类生活中最重要的需求之一;通信是指:对语言、文字、声音和图片以及其它任何类型的相关数据进行传输;计算机的出现以及网络的构成,使得数据通信更加快速有效。网络原理网络原理网络就是一组连接在一起的计算机。使用网卡、电缆、集使用网卡、电缆、集线器等连接设备连接线器等连接设备连接计算机以组成网络。计算机以组成网络。客户端客户端/服务器模式服务器模式网络发展,促使客户端/服务器模式应运而生;通过网络,向另一台计算机请求服务的计算机称为客户端,而处理请求的计算机称为服务器;如数据服务器,需要数据的客户端机器向数据服务器提出请求,而服务器则处理客户端的请求并向其发送所需的数据;客户端/服务器的优势在于:服务器和客户端分摊任务,分别负责部分处理工作;服务器可以同时为多台客户端服务;多个客户端可以同时访问服务器上的相同数据。IP地址地址网络中有多台计算机,它们必须通过某种标识来区分每一台机器,这就是IP地址;IP地址由4个字节共32位二进制数组成,类似于:192.168.0.8;在网络寻找某一台计算机都是依靠它的IP地址(用域名或计算机名定位主机其实也是通过某种服务转成IP地址后再找到该主机的);网络ID:网络ID标识了计算机或网络设备所在的网段;主机ID:主机ID标识了特定的主机或网络设备特殊特殊IP地址地址许多网络地址被保留用于特殊用途;0.0.0.0和127.0.0.1就是两个此类地址,第一个称为缺省路由,后一个是环回地址;127.0.0.1被保留用于用户主机的本地IP话务,它被分配给一个特殊接口,即起到闭合电路作用的环回接口。端口端口在一台物理性的计算机中,往往运行着多个网络程序,一个IP地址并不足以完整标识一个服务器,因此,端口是机器内部独一无二的场所;一台计算机上可能同时运行多个网络程序,IP地址只能确保把数据送到指定的计算机,但不能保证把这些数据传递给哪个网络程序;端口使用一个16位的数字来表示,它的范围是065535,1024以下的端口号保留给预定义的服务,如:http使用80端口;网络间通信其实是在网络应用程序端口之间进行的。系统端口号列表系统端口号列表包包使用包可以实现Java的网络功能,其中包含了一系列与网络通讯相关的类,比较重要的有:InetAddressSocketServerSocket如果要进行网络通讯编程的话,必须导入此包。.InetAddressInetAddress用来表示互联网协议(IP)地址,它的实例将IP地址和DNS(主机名解析)进行了封装;该类无法直接实例化,只能通过下列静态工厂方法获得实例:方 法 原 型说 明static InetAddress getByName(String host)throws UnknownHostException在给定主机名的情况下确定主机的 IP 地址static InetAddress getLocalHost()throws UnknownHostException返回本地主机的InetAddress对象static InetAddress getByAddress(byte address)throws UnknownHostException在给定原始 IP 地址的情况下,返回 InetAddress 对象static InetAddress getAllByName(String host)throws UnknownHostException在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组InetAddress示例示例import .*;/导入导入包包public class InetAddressDemo public static void main(String args)try /获得当前本地主机的获得当前本地主机的IP地址地址 InetAddress add1=InetAddress.getLocalHost();System.out.println(当前本地主机:当前本地主机:+add1);/根据域名,通过根据域名,通过DNS域名解析,获得相应服务的主机地址域名解析,获得相应服务的主机地址 InetAddress add2=InetAddress.getByName();System.out.println(网易服务器主机:网易服务器主机:+add2);/根据字符串表现形式的根据字符串表现形式的IP地址获得相应的主机地址地址获得相应的主机地址(若果网络上有该若果网络上有该IP地址的话地址的话)InetAddress add3=InetAddress.getByName(192.168.0.22);System.out.println(IP地址为地址为192.168.0.22的主机:的主机:+add3);/根据机器名获得相应的主机地址(如果网络上有该机器名的话)根据机器名获得相应的主机地址(如果网络上有该机器名的话)InetAddress add4=InetAddress.getByName(J104);System.out.println(机器名为机器名为J104的主机:的主机:+add4);catch(UnknownHostException uhe)uhe.printStackTrace();InetAddress的其它方法的其它方法方 法 原 型说 明byte getAddress()返回此 InetAddress 对象的原始 IP 地址String getHostAddress()返回此 InetAddress 对象的IP地址字符串String getHostName()返回此 InetAddress 对象的主机名称boolean equals(Object other)判断两个IP地址是否相等String toString()返回此 InetAddress 对象的字符串表现形式(主机名/IP地址)套接字套接字网络上计算机通过TCP/IP协议进行通信,而套接字(socket)则将这些通信协议进行了封装;TCP/IP套接字用于在主机和Internet之间建立可靠的、双向的、持续的、点对点的流式连接;socket用于描述IP地址和端口,应用程序通过套接字向网络发出请求或者应答网络请求;也就是说,套接字起到通信端点的作用;客户端和服务器通过套接字建立连接和通信。主机甲主机甲套接字通信原理套接字通信原理A程序程序主机乙主机乙B程序程序TCP/IP协议协议网网 卡卡网络管理软件网络管理软件socketsocket主机甲上的主机甲上的A程程序将一段数据写序将一段数据写入入socket中中 主机乙上的主机乙上的B程程序从序从socket中读中读取这段数据取这段数据 .SocketSocket类用于创建套接字对象,其构造方法共有9种重载,常用的有如下几种:套接字会因为网络的连接中断而失效,所以对它的操作都有可能抛出IOException构 造 方 法说 明Socket(InetAddress address,int port)throws IOException用预先存在的InetAddress对象和端口创建一个与本地主机连接的套接字Socket(String hostName,int port)throws UnknownHostException,IOException创建一个本地主机与给定名称的主机和端口连接的套接字Socket的常用方法的常用方法一旦Socket对象被成功创建,就可以获得访问与之相关的输入/输出流的权力,通过流操作从套接字中发送(输出)和接收(输入)数据:方 法 原 型说 明InputStream getInputStream()throws IOException获得当前套接字的输入流OutputStream getOutputStream()throws IOException获得当前套接字的输出流void close()throws IOException关闭当前套接字Socket的其它方法的其它方法使用下面的方法,可以在任何时候检查套接字的地址和与之相关的端口信息:方 法 原 型说 明InetAddress getInetAddress()返回与当前套接字连接的远程主机的InetAddress对象,如果未连接,则返回nullint getPort()返回与当前套接字连接的远程主机端口InetAddress getLocalAddress()返回与当前套接字绑定的本地主机的InetAddress对象int getLocalPort()返回与当前套接字绑定的本地主机端口.ServerSocketServerSocket类用来创建服务器套接字,它监听本地或远程客户程序通过公共端口的连接;ServerSocket类有4个重载的构造方法,以下是常用的:ServerSocket的常用方法如下:构 造 方 法说 明ServerSocket(int port)throws IOException创建服务套接字,它负责侦听由port指定的端口方 法 原 型说 明Socket accept()throws IOException等待并侦听来自客户端的请求,一旦接收到,返回一个与客户进行通信的Socketvoid close()throws IOException关闭当前服务器套接字Socket编程编程编写服务器端程序:创建一个服务器套接字(ServerSocket),绑定到指定端口;调用accept方法,侦听来自客户端的请求,如果客户发出请求,则接受连接,返回通信套接字(Socket);调用Socket的getInputStream和getOutputStream方法,获得输入/输出流,开始网络数据的接收和发送;关闭通信套接字,关闭服务器套接字。编写客户端程序:创建一个套接字(Socket),向服务器的侦听端口发出请求;与服务器正确连接后,调用Socket的getInputStream和getOutputStream方法,获得输入/输出流,开始网络数据的接收和发送;关闭通信套接字。ClientServerSocket编程示意图编程示意图ServerSocket(int port)InputStream getInputStream()OutputStream getOutputStream()close()close()InputStream getInputStream()OutputStream getOutputStream()Socket(InetAddress address,int port)Socket accept()示例(服务端)示例(服务端)public class Server private static final int SERVER_PORT=9001;/指定侦听端口指定侦听端口 public Server()try ServerSocket ss=new ServerSocket(SERVER_PORT);/创建服务器套接字创建服务器套接字 System.out.println(服务端已启动,正在等待客户端服务端已启动,正在等待客户端.);Socket s=ss.accept();/侦听来自客户端的请求侦听来自客户端的请求 InputStream in=s.getInputStream();/获得输入流,用来接收数据获得输入流,用来接收数据 OutputStream out=s.getOutputStream();/获得输出流,用来发送数据获得输出流,用来发送数据 byte buf=new byte1024;int len=in.read(buf);/从输入流中读取数据从输入流中读取数据 String strFromClient=new String(buf,0,len);System.out.print(来自客户端的信息来自客户端的信息);System.out.println(strFromClient);String strToClient=我也很好!我也很好!;out.write(strToClient.getBytes();/往输出流中发送数据往输出流中发送数据 in.close();out.close();/关闭输入流和输出流关闭输入流和输出流 s.close();ss.close();/关闭通信套接字和服务器套接字关闭通信套接字和服务器套接字 System.out.println(服务端已关闭。服务端已关闭。);catch(IOException ioe)ioe.printStackTrace();public static void main(String args)new Server();示例(客户端)示例(客户端)public class Client private static final int SERVER_PORT=9001;/服务器的侦听端口服务器的侦听端口 public Client()try /由于服务端也是运行在本机,所以创建本机的由于服务端也是运行在本机,所以创建本机的InetAddress对象对象 InetAddress address=InetAddress.getByName(localhost);Socket s=new Socket(address,SERVER_PORT);/向服务器侦听端口发出请求向服务器侦听端口发出请求 System.out.println(客户端已启动。客户端已启动。);InputStream in=s.getInputStream();/获得输入流,用来接收数据获得输入流,用来接收数据 OutputStream out=s.getOutputStream();/获得输出流,用来发送数据获得输出流,用来发送数据 String strToServer=你好!你好!;out.write(strToServer.getBytes();/往输出流中发送数据往输出流中发送数据 byte buf=new byte1024;int len=in.read(buf);/从输入流中读取数据从输入流中读取数据 String strFromServer=new String(buf,0,len);System.out.print(来自服务端的回答来自服务端的回答);System.out.println(strFromServer);in.close();out.close();/关闭输入流和输出流关闭输入流和输出流 s.close();/关闭通信套接字关闭通信套接字 System.out.println(客户端已关闭。客户端已关闭。);catch(UnknownHostException nhe)System.out.println(未找到指定主机未找到指定主机.);catch(IOException ioe)ioe.printStackTrace();public static void main(String args)new Client();关于关于IO流流计算机系统将除了CPU和内存以外其它所有设备都当成文件来处理,包括网络终端(网卡)也不例外;在两台主机之间通过socket建立握手连接之后,主要是通过输入/输出流来接收和发送数据,实际上,对于网络的操作,绝大部分是在操作IO流;实际上操作网络端口流与操作磁盘文件流的原理是相似的;出于效率的考虑,scoket使用的是字节流,但是在实际操作中,字节往往会带来不便,所以我们一般会把字节流改造成字符流后进行操作。输入输入对于InputStream,先使用InputStreamReader转化成字符流;然后再使用BufferedReader建立缓冲,以提高效率,如:InputStream is=socket.getInputStream();InputStreamReader isr=new InputStreamReader(is);BufferedReader in=new BufferedReader(isr);总结总结网络的发展促使计算机之间的通信日趋重要;网络上的计算机通过IP地址来区分不同的机器,端口是数据的通道,使得多个应用程序在同一主机上进行网络通信;InetAddress用来描述主机地址;Socket用来创建两台主机之间的连接;ServerSocket用来侦听来自客户端的请求;我们实际上是通过操作IO流来进行数据的收发工作,将字节流改造成字符流会使操作更加方便。