1、Java网络通信,网络的基本概念Socket 通信数据报,掌握网络通信的基本原理学会Socket类的运用学会Datapacket类的应用,课程目标,学习完本课程,您应该能够:,第一节 网络的基本概念,IP地址(Novell Netware(IPX/SPX), NetBIOS(NetBEUI)主机名(hostname)端口号(port number)如:80(http),21(ftp),23(telnet),25(SMTP)通信协议,IP地址是计算机网络中任意一台计算机地址的惟一标识。如127.129.121.3,主机名是计算机网络中一台计算机的标识名,也可以看作是IP地址的助记名。如,主机名,
2、IP地址,1. 几个重要概念,端口号和通信协议,端口号是用一个16位的整数来表达的,其范围为0-65535,其中0-1023为系统所保留,有一套通信规则保证网络上可靠高效的数据传输,端口号,传输层协议用端口号来标识和区分各种上层应用程序。套接字(Socket)IP端口号,80,20/21,23,25,53,69,161,QQ,TCP/IP协议和OSI参考模型,TCP/IP协议栈具有简单的分层设计,与OSI参考模型有清晰的对应关系。,TCP/IP,应用层,表示层,会话层,传输层,网络层,数据链路层,物理层,1,2,3,4,5,6,7,应用层,传输层,网络层,数据链路层,物理层,OSI参考模型,T
3、CP/IP,如何使用TCP端口号,服务器IP:10.1.1.2,主机,Telnet 10.1.1.2,目的端口23,1028,23,10.1.1.2,源端口,目的端口,IP地址,URL和信息定位,URL语法格式::/ :/#,统一资源定位器(URL)uniform resource locator指出网站中某个网页或者文件的所在位置,协议,域名,文件夹名称,文件名,http:/ Java的网络通信分为三个层次: 最高一级的网络通信就是我们上一讲中所涉及到的从网络上下载Applet。客户端浏览器通过HTML文件中的标记来识别Applet,并解析Applet的属性,通过网络获取Applet得字节码
4、文件。(由浏览器提供) 上一讲中所涉及到的声音播放和图象显示,其中声音文件和图象文件的获取是次一级的通信。通过类URL的对象指明文件所在位置,并从网络上下载声音和图象文件。(由Java开发环境提供) 最低一级的通信是利用包中提供的类直接在程序中实现网络通信。(由Java语言开发包提供),2、Java与InternetJava中的网络支持,针对网络通信的不同层次,Java提供的网络功能有四大类: URL、 InetAddress 、Sockets、Datagram。 URL面向的应用层,通过URL,Java程序可以直接送出或读入网络上的数据。InetAddress面向的是网络层(IP层),用于标
5、识网络上的硬件资源。 Sockets和Datagram面向的则是传输层。Sockets使用的是TCP协议,这是传统网络程序最常用的方式,可以想象为两个不同的程序通过网络的通信信道进行通信。Datagram则使用UDP协议,是另一种网络传输方式,它把数据的目的地纪录在数据包中,然后直接放在网络上。,2、Java与InternetJava中的网络支持,包中的主要的类和可能产生的例外包括:面向IP层的类:InetAddress (Inet4Address,Inet6Address)面向应用层的类:URL、URLConnection面向网络层的类:TCP协议相关类:Socket、ServerSocke
6、tUDP协议相关类:DatagramPacket、DatagramSocket、MulticastSocket可能产生的例外:BindException、ConnectException、MalformedURLException、NoRouteToHostException、ProtocolException、SocketException、UnknownHostException、UnknownServiceException,类InetAddress可以用于标识网络上的硬件资源(逻辑网络中端),它提供了一系列方法以描述、获取及使用网络资源。 InetAddress类没有构造函数,因此不能
7、用new来构造一个InetAddress实例。通常是用它提供的静态方法来获取:public static InetAddress getByName(Stringhost) :host可以是一个机器名,也可以是一个形如“%d.%d.%d.%d”的IP地址或一个DSN域名。public static InetAddress getLocalHost() public static InetAddress getAllByName(Stringhost)/多个网卡public static InetAddress getByAddress(Stringhost, Byteaddr) 这些方法通常会
8、产生UnknownHostException例外,应在程序中捕获处理。 以下是InetAddress类的几个主要方法,通过上述方法获得InetAddress类的实例后就可以使用:public byte getAddress():获得本对象的IP地址(存放在字节数组中)。public String getHostAddress():获得本对象的IP地址“%d.%d.%d.%d”。public String getHostName():获得本对象的机器名。,3、使用InetAddress,下面的例子演示Java如何根据域名自动到DNS(域名服务器)上查找IP地址(与DNS服务器的连接减至一行):p
9、ublic class getIP public static void main(String args) InetAddress pku = null; try pku = InetAddress.getByName(“”); catch(UnknownHostException e) System.out.println(pku); ,3、使用InetAddress,getIP.java,通过InetAddress,可以获取本机的IP地址:public class getLocalHostTest public static void main() InetAddress myIP =
10、null; try myIP = InetAddress.getLocalHost(); catch(UnknownHostException e) System.out.println(myIP); ,3、使用InetAddress,getLocalHostTest.java,4、使用URL在Java中构造URL,在包中,提供了类URL来表示URL。类URL提供了很多构造方法来生成一个URL对象:public URL(Stringspec) public URL(URL context, String spec)public URL(Stringprotocol, Stringhost, S
11、tringfile) public URL(Stringprotocol, Stringhost, intport, Stringfile) 以下是一些具体的构造实例:URL url1 = new URL(“http:/ base = new URL(“http:/”);URL url2 = new URL(base, “mywork1.html”);URL url3 = new URL(base, “mywork2.html”);URL url4 = new URL(“http”, “”,“/lyw/test.html”);URL url5 = new URL(“http”, “”, 808
12、0, “/java/network.html”); 另外还有两种稍微复杂些的构造方法(参见JDK文档)。,当创建URL时发生错误,系统会产生例外MalformedURLException,这是非运行时例外,必须在程序中捕获处理。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();,4、使用URL
13、在Java中构造URL,一个URL对象生成后,其属性是不能被改变的(与String对象相似),但可以通过它给定的方法来获取这些属性: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 ge
14、tQuery() :获取该URL的查询名,4、使用URLURL的基本方法,ParseURL.java,4、使用URL通过URL读取www信息,通过URL类提供的方法openStream(),就可以读取一个URL对象所指定的资源。public final InputStream openStream() 方法openStream()与指定的URL建立连接并返回一个InputStream对象,将URL位置的资源转成一个输入数据流。通过这个InputStream对象,就可以读取资源中的数据。,4、使用URL通过URL读取www信息,import .*;import java.io.*;public
15、class URLReader public static void main (String args) try URL gis = new URL(http:/ BufferedReader in = new BufferedReader( new InputStreamReader( gis.openStream() ) ); String line; while( (line = in.readLine() != null ) System.out.println(line); in.close(); catch(Exception e) System.out.println(e);
16、,URLReader.java,4、使用URLURL和InetAddress的联合使用,Applet中的网络通信需要将URL和InetAddress联合使用来得到相关的IP地址。 通过类Applet的getCodeBase()方法获得提供它的主机的URL实例 利用类URL的getHost()方法得到主机名 利用类InetAddress的getByName()得到该主机的IP地址 通过IP地址,就可以进行网络通信(TCP, UDP),URL url = getCodeBase();String host = url.getHost();Try InetAddress address = Inet
17、Address.getByName(host);catch(Exception e)Try DatagramSocket socket = new DatagramSocket(); DatagramPacket packet = new DatagramPacket(buf, length, address, port); socket.send(packet);catch(Exception e),AppletURLReader.java,4、使用URLURL连接,通过URL类提供的方法openConnection(),就可以获得一个URL连接(URLConnection)对象。publi
18、c URLConnection openConnection() 通过URL的方法openStream(),只能从网络上读取资源中的数据。通过URLConnection类,可以在应用程序和URL资源之间进行交互,既可以从URL中读取数据,也可以向URL中发送数据。URLConnection类表示了应用程序和URL资源之间的通信连接。try URL url = new URL(“http:/”); URLConnection uc = url.openConnection();catch(MalformedURLException e1) catch(IOException e2) ,4、使用U
19、RLURL连接,public class URLConnectionReader public static void main (String args) try URL gis = new URL(http:/ URLConnection uc = gis.openConnection(); BufferedReader in = new BufferedReader( new InputStreamReader( uc.getInputStream() ) ); String line; while( (line = in.readLine() != null ) System.out.
20、println(line); in.close(); catch(Exception e) System.out.println(e); ,URLConnectionReader.java,通过URLConnection对象获取的输入流和输出流(不是所有的资源都可以获得有效的输出流),可以与现有的CGI程序进行交互。URL和URLConnection的区别在于前者代表一个资源的位置,后者代表一种连接。,4、使用URLURL连接,URL url = new URL(http:/ URLConnection uc = url.openConnection(); uc.setDoOutput(tru
21、e);PrintStream out = new PrintStream(uc.getOutputStream();BufferedReader in = new BufferedReader( new InputStreamReader( uc.getInputStream() ) );,4、使用URL其他URL类,URLConnection类的其他方法以及其他URL相关的类(URLClassLoader,URLDecoder,URLEncoder,URLStreamHandler,HttpURLConnection,JarURLConnection,ContentHandler)的使用,大
22、家在以后的实践中去学习。,第九章 网络通信,网络的基本概念Socket 通信数据报,高级语言程序设计(JAVA),第二节 Socket通信,网络通信的基本原理Socket的定义Socket的应用,掌握网络通信的基本原理了解Socket通信的基本原理掌握Socket类的运用,课程目标,学习完本节课,您应该能够:,1、网络通信的基本原理,计算机之间的通信是要遵循一定规则的,通信协议就是计算机之间进行通信所要遵循的各种规则的集合。网络中的不同计算机之间要实现准确、迅速地传递信息,可以通过TCP/IP协议建立网络上的两台计算机(程序)之间的可靠连接,并进行双向通信。,TCP/IP协议和OSI参考模型,
23、TCP/IP协议栈具有简单的分层设计,与OSI参考模型有清晰的对应关系。,TCP/IP,应用层,表示层,会话层,传输层,网络层,数据链路层,物理层,1,2,3,4,5,6,7,应用层,传输层,网络层,数据链路层,物理层,OSI参考模型,TCP/IP,TCP/IP协议栈,传输层协议,应用层,传输层,网络层,数据链路层,物理层,TCP(Transmission Control Protocol)UDP(User Datagram Protocol),TCP协议,TCP:Transfer Control Protocol面向连接的能够提供可靠的流式数据传输的协议。类似于打电话的过程。URL, URL
24、Connection, Socket, ServerSocket等类都使用TCP协议进行网络通讯。,UDP协议,UDP是一个简单的不可靠的数据报协议。 非面向连接的提供不可靠的数据包式的数据传输的协议。类似于从邮局发送信件的过程。DatagramPacket, DatagramSocket, MulticastSocket等类使用UDP协议进行网络通讯。UDP不提供可靠性:它把应用程序传给IP层的数据发送出去,但是并不保证它们能到达目的地。,TCP三次握手建立连接,服务器,主机,SYN (seq=a),SYN (seq=b,acka+1),SYN (seq=a+1,ackb+1),发送SYN,
25、接收SYN,发送SYN,ACK,发送SYN,建立会话,有连接的通信,2、Socket通信,所谓Socket通常也称为”套接字”,由IP地址和端口号有两部分组成,应用程序通过“套接字”向网络发出请求或者应答网络请求。,port,Socket,客户机,服务器,1)什么是Socket?,Socket,请求,响应,客户机/服务器(C/S)模式是在网络应用程序中最常用的通信模式。 在C/S模式通信过程中主动发起通信的一方被称为客户机,而监听并接受请求进行通信的一方成为服务器。服务器使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,所以一般使用大于102
26、4的端口),等待客户端连接请求,客户端连接后,会话产生,在完成会话后,关闭连接。,2)客户机/服务器(C/S)模式的原理,C/S聊天室案例,建立套接字Socket,在服务器端使用ServerSocket类,以等待客户端的连接: ServerSocket(port);,客户端呼叫,服务器等待,在客户端使用socket类,指定服务器IP和端口号,以便连到服务器上:Socket(host_IP, port);,3)Socket的建立,Socket主要方法,在客户端:建立socket连接后,还应该建立输入输出数据流。 getInputStream( ) 获得输入流 getOutputStream( )
27、 获得输出流在服务器端:ServerSocket类的accept( )方法使服务器处于阻塞状态,等待用户请求。,Socket通信,Server端程序,ServerSocket(port #),Socket socket = ServerSocket.accept(),接收连接,OutputStream,InputStream,Close Socket,Client端程序,Socket(host, port #),与服务器建立连接,OutputStream,InputStream,Close Socket,socket,Socket通信,无论一个Socket通信程序的功能多么齐全、程序多么复杂,
28、其基本结构都是一样的,都包括以下四个基本步骤:1、在客户方和服务器方创建Socket/ServerSocket实例。2、打开连接到Socket的输入/输出流。3、利用输入/输出流,按照一定的协议对Socket进行读/写操作。4、关闭输入/输出流和Socket。,例1:演示服务器与客户之间的交互,服务器等待,客户访问,相互通一次信息。,客户端向服务器发出信息:“你好”,服务器接收到信息后,给出回应:“你好,我是服务器。”,3、Socket的应用案例,21.5 Socket,. 21.5 Socket,创建服务器(端口号),定义数据成员,服务器等待网络连接,建立socket流,读客户 端信息,向用
29、户发出确认字符串,创建Socket实例,定义数据成员,建立socket流,读socket流(接收并显示),送用户名给服务器,关闭流,waiting for user,127.0.0.1 4331,4331,“这里是服务器,connetcting client.,你好,提示用户登录成功,读socket流,客户机端,import java.io.*;import .*;class C public static void main(String args) try Socket socket=new Socket(127.0.0.1,6565); DataOutputStream out=new
30、DataOutputStream(socket.getOutputStream(); out.writeUTF(我是客户机); DataInputStream in=new DataInputStream(socket.getInputStream(); String s=in.readUTF(); System.out.println(客户机收到:+s); catch(Exception e),服务器端,import java.io.*;import .*;class Spublic static void main(String args) try ServerSocket s_socke
31、t=new ServerSocket(6565); Socket socket=s_socket.accept(); DataInputStream in=new DataInputStream(socket.getInputStream(); String s=in.readUTF(); System.out.println(服务器收到:+s); DataOutputStream out=new DataOutputStream(socket.getOutputStream(); out.writeUTF(我是服务器); catch(Exception e),21.5 Socket,显示服务
32、器与客户机间的通信(服务器端),DataOutputStream out=null;DataInputStream in=null;ServerSocket s_socket=null;Socket c_socket=null;String s; /存放读取到的信息,try s_socket=new ServerSocket(4331); catch (IOException e) ,try c_socket=s_socket.accept(); catch (IOException e) ,创建服务器(端口号),定义数据成员,服务器等待网络连接,用循环语句收发信息(见下页),in=new D
33、ataInPutStream(clientSocket.getInputStream();out=new DataOutputStream(clientSocket.getOutputStream();,创建服务器(端口号),建立socket流,等待客户登录,out.writeUTF(“这里是服务器); clientSocket.close();,While (true) s=in.readUTF( ); if ( s!=null ) break; ,读客户 端信息,创建Socket实例,DataOutputStream out=null;DataInputStream in=null;Str
34、ing string;Socket socket=null;,定义数据成员,trysocket=new Socket(127.0.0.1,4331);,input=new DataInputStream(socket.getInputStream();output=new PrintStream(socket.getOutputStream();,建立socket流,catch(IOException e) System.out.println(“无法连接 ”); ,Out.writeUTF(“你好”);System.out.println(input.readLine();,读socket流
35、(看到提示),从键盘上读送用户名送给服务器端,关闭流,mysocket.close();System.out.println(“s);,读服务器反馈,While (true) s=in.readUTF( ); if ( s!=null ) break; ,考虑多用户,第一种解决方案:一台计算机上一次启动多个服务器程序,只是端口号不同。myserver myclient-f21.batmyserver2myclient2-f9.bat,多用户的第二种方案,(支持多客户),Server,client1,client2,serverthread,serverthread,将服务器写成多线程的,不同的
36、线程为不同的客户服务.main()只负责循环等待线程负责网络连接,接收客户输入的信息,客户1,客户2,服务器,线程run(),MySocketServer.java,client(),Run( ),Out.writeUTF(),In.readUTF(),客户端,writer.start(),按钮事件(),socket,getInputStream,getOutputStream,服务器,服务器端,.,服务器(4321)acceptsocket,客户,IP client1,线程,客户,IP client2,线程,服务器一端为了能接收多个客户的信息,它的输入流,输出流都是数组型的.ServerSo
37、cket.accept()等待用户连接,一旦连接上,则调用服务程序.服务程序的主要内容是网络的读写,多客户的原因,网络读写的功能用多线程实现,因此将此部分功能单独分离出来,构成线程类,服务器端,client1,client2,serviceRequest,server,ServerSocket,Socket,getOutputStream,getInputStream,reader.run,reader.run,accept(),reader.start(),read_net_input,write_net_output(),作业,编写一个会话程序要求:会话双方可以自由通话,看到对方发来“by
38、e”则退出预习下节课内容,第三节 基于数据报Datagram,TCP/IP传输层由两个并列的协议:TCP,UDP.UDP数据报的每个数据包要包含目的地址和端口号.,socket,server,client,Datagram数据报,server,client,在UDP中,要使用二个类: (1) DatagramSocket 类发送时,用 send( )方法发送数据;接收时,用 receive( )方法接收数据。(2) DatagramPacket 类 用于打包或拆包 发送时打包: 包由数据、接收地址、端口号组成; 接收时拆包: 取出包中的数据、接收地址、端口号。,Datagram 工作过程,建立
39、数据报socket();,建立一个报文包packet,等待请求报文,建立数据报socket,建立一个请求包,发出请求,获得对方地址,构成信息包,发送出去,创建接收包,等待接收,Datagram,一、服务器端发出报文的步骤如下:1. 定义数据成员 DatagramSocket socket; DatagramPacket packet; InetAddress address;(用来存放接收方的地址) int port; ;(用来存放接收方的端口号)2. 创建数据报文Socket对象 try socket=new DatagramSocket(1111); catch(.SocketExcept
40、ion e) socket 绑定到一个本地的可用端口,等待接收客户的请求.,Datagram,3.分配并填写数据缓冲区(一个字节类型的数组) byte Buf=new byte256; 存放从客户端接收的请求信息.4.创建一个DatagramPacket packet=new DatagramPacket(Buf数组, 256长度); 用来从socket接收数据,它只有两个参数 5. 服务器阻塞 socket.receive(packet); 在客户的请求报道来之前一直等待,Datagram,6. 从到来的包中得到地址和端口号 InetAddress address=packet.getAdd
41、ress(); int port=packet.getPort();7. 将数据送入缓冲区 或来自文件,或键盘输入8. 建立报文包,用来从socket上发送信息 packet=new DatagramPacket (buf,buf.length, address,port);9. 发送数据包 10.关闭socket socket.send(packet); socket.close();,Datagram,二、客户端接收包的步骤如下:1. 定义数据成员 int port; InetAddress address; DatagramSocket socket; DatagramPacket pa
42、cket; byte sendBuf=new byte256;2. 建立socket socket=new DatagramSocket();,Datagram,3. 向服务器发出请求报文 address=InetAddress.getByName(args0); port=parseInt(args1); packet=new DatagramPacket(sendBuf,256,address,port); socket.send(packet); 这个包本身带有客户端的信息4. 客户机等待应答 packet=new DatagramPacket(sendBuf,256); socket.
43、receive(packet);(如果没有到就一直等待,因此实用程序要设置时间限度),Datagram,5. 处理接收到的数据 String received=new String(packet.getData(),0);System.out.println(received);数据报套接字首先是强调发送方和接收方的区别,同时也指出服务器和客户之间的不同:一个客户机必须事先知道服务器的地址和端口,以便进行出事连接一个服务器从它接收到的数据报文中读取客户端的地址和端口.,举例,小结,实现网络功能要靠URL类, URLConection类, Socket类和DatagramSocket类网络上的数据传送是将网络连接转换成输入输出流DataInputStream和DataOutputStream (PrintStream)是网间流的载体.URL适用于web应用,如访问http服务器是高层服务,