第9章 网络通信 1
主要内容 9.1 网络编程的基础知识 9.2 基于TCP协议网络程序设计 9.3 基于UDP协议网络程序设计 9.4 JApplet编程 9.1 网络编程的基础知识 9.2 基于TCP协议网络程序设计 9.3 基于UDP协议网络程序设计 9.4 JApplet编程 9.5 基于分布模式的云计算系统
9.1 网络编程的基础知识 9.1.1 IP地址和端口号 9.1.2 套接字
9.1.1 IP地址和端口号 1、IP地址 网络中的每台计算机都必须有一个惟一的IP地址作为标识,这个数通常写作一组由“.”号分隔的十进制数。
9.1.1 IP地址和端口号 在Java.net包中,IP地址由一个称作InetAddress的特殊的类来描述。这个类提供了三个用来获得一个InetAddress类的实例的静态方法。这三个方法是: getLocalHost( )返回一个本地主机的IP地址。 getByName(String host )返回对应于指定主机的IP地址。 getAllByName(String host )对于某个主机有多个IP地址(多宿主机)可用于得到一个IP地址数组。 此外,对一个InetAddress的实例可以使用: getAddress( )获得一个用字节数组形式表示的IP地址。 getHostName( )作反向查询,获得对应于某个IP地址的主机名。
【例9-1】通过域名查找IP地址。 核心语句: try{ InetAddress zsm_address; zsm_address =InetAddress.getByName("www.zsm8.com"); str="思维论坛的IP地址为:"+zsm_address.toString(); } catch(UnknownHostException e) { str="无法找到思维论坛"; }
【例9-2】查找本机IP地址。 核心语句: try{ InetAddress host_address; host_address=InetAddress.getLocalHost(); str="本机的IP地址为:"+host_address.toString(); } catch(UnknownHostException e) { str="本机没有安装网卡,无法找到IP。"; }
9.1.1 IP地址和端口号 2、端口 我们用“端口号”来标识正在计算机上运行的进程(程序)。每个被发送的网络数据包也都包含有“端口号”,,用于将该数据帧交给具有相同端口号的应用程序来处理。
9.1.1 IP地址和端口号 2、端口 端口号是一个整数,其取值范围为0~65535之间。由于同一台计算机上不能同时运行两个有相同端口号的进程。通常0~1023间的端口号作为保留端口号,用于一些网络系统服务和应用,用户的普通网络应用程序应该使用1024以后的端口号,从而避免端口号冲突。
9.1.1 IP地址和端口号 3、TCP与UDP协议 在网络中,有两个常用的协议,它们是“传输控制协议”(Transmission Control Protocol,简称TCP)和“用户数据报协议”(User Datagram Protocol,简称:UDP)。 TCP是面向连接的通信协议,TCP提供两台计算机之间的可靠无差错的数据传输。 UDP是无连接通信协议,UDP不保证可靠数据的传输。
9.1.2 套接字 1、什么是套接字 在TCP/IP通信协议中,套接字(Socket)就是IP地址与端口号的组合。 9.1.2 套接字 1、什么是套接字 在TCP/IP通信协议中,套接字(Socket)就是IP地址与端口号的组合。 如图所示,IP地址193.14.26.7与端口号13组成一个套接字。
9.1.2 套接字 1、什么是套接字 网络通信,准确地说,不能仅说成是两台计算机之间在通信,而是两台计算机上执行的网络应用程序(进程)之间在收发数据。 当两个网络程序需要通信时,它们可以通过使用Socket类建立套接字连接。我们把呼叫方称为“客户端”,负责监听的一方称为“服务器端”。
9.1.2 套接字 2、客户端建立套接字Socket对象 9.1.2 套接字 2、客户端建立套接字Socket对象 在客户端使用socket类,建立向指定服务器IP和端口号连接的套接字,其构造方法是: Socket(host_IP, prot); 其中host_IP是服务器的IP地址,prot是一个端口号。 Socket主要方法有: getInputStream( ):获得一个输入流,读取从网络线路上传送来的数据信息。 getOutputStream( ):获得一个输出流,用这个输出流将数据信息写入到网络“线路”上。
9.1.2 套接字 3、服务器端建立套接字Socket对象 9.1.2 套接字 3、服务器端建立套接字Socket对象 在服务器端用ServerSocket类创建服务器Socket,ServerSocket类的构造方法为: ServerSocket(int port); 创建ServerSocket实例是不需要指定IP地址的,ServerSocket总是处于监听本机端口的状态。 ServerSocket类的主要方法: Socket accept(); 该方法用于在服务器端的指定端口监听客户机发起的连接请求,并与之连接,其返回值为Socket对象。
9.2 基于TCP协议网络程序设计 9.2.1客户机/服务器模式 9.2.2同时服务于多个客户的解决方案
9.2.1客户机/服务器模式 利用Socket方式进行数据通信与传输,大致有如下步骤: (1)创建服务器端ServerSocket,设置建立连接的端口号。 (2)创建客户端Socket对象,设置绑定的主机名称或IP地址,指定连接端口号。 (3)客户机Socket发起连接请求。 (4)建立连接。 (5)取得InputStream和OutputStream。 (6)利用InputStream和OutputStream进行数据传输。 (7)关闭Socket和ServerSocket。
【例9-3】远程数据通信示例,本例由客户端程序和服务器程序两部分组成。 (1)客户端程序 (2)服务器端程序
9.2.2同时服务于多个客户的解决方案 1、启动多个服务程序 我们可以在服务器端启动多个服务程序,等待客户机的连接请求,每个服务程序处理一个客户机数据,它们只是监听的端口号不同。显然,这个方案耗用资源太多。
9.2.2同时服务于多个客户的解决方案 2、应用多线程 在服务程序中应用多线程技术,不同的线程为不同的客户服务。主线程负责等待客户机的连接请求,各个线程负责网络连接,接收客户发送来的信息。
【例9-4】服务程序应用多线程技术同时处理多个客户机的连接请求。 (1)客户端程序 (2)服务器端程序
9.3 基于UDP协议网络程序设计 9.3.1 基于UDP协议的数据报套接字 9.3.2 数据报的程序设计过程 9.3.3 广播数据报套接字
9.3.1 基于UDP协议的数据报套接字 TCP协议通过socket套接字建立一条虚电路。 UDP数据报的每个数据包要包含目的地址和端口号. server client Socket要求数据按照发送的次序接收,包丢失要重发,浪费网络资源,没有保持的连接和数据流,UDP的价值在于效率,如果通信子网可靠UDP大有用武之处.TCP和UDP都由端口的概念.TCP的可靠来源于确认和超时重传.要求先建立连接,传输后关闭,次序不变. UDP不需要实现连接,数据报是独立的,没有次序要求路径不同. UDP数据报的每个数据包要包含目的地址和端口号. Datagram数据报 server client
接收时,用 receive( )方法接收数据。 (2) DatagramPacket 类 用于打包或拆包 发送时打包: 在UDP中,要使用二个类: (1) DatagramSocket 类 发送时,用 send( )方法发送数据; 接收时,用 receive( )方法接收数据。 (2) DatagramPacket 类 用于打包或拆包 发送时打包: 包由数据、接收地址、端口号组成; 接收时拆包: 取出包中的数据、接收地址、端口号。 TCP非常复杂,因为要包容通信子网的不可靠因素 可靠并以一定比效率重要,视情况而定
9.3.2 数据报的程序设计过程 1、服务器端发出报文的步骤 (1)定义数据成员。 DatagramSocket socket; 9.3.2 数据报的程序设计过程 1、服务器端发出报文的步骤 (1)定义数据成员。 DatagramSocket socket; DatagramPacket packet; InetAddress address;(用来存放接收方的地址) int port; (用来存放接收方的端口号) (2)创建数据报文Socket对象。 try {socket = new DatagramSocket(1111);} catch(java.net.SocketException e){ } socket 绑定到一个本地的可用端口,等待接收客户的请求。
9.3.2 数据报的程序设计过程 1、服务器端发出报文的步骤 (3)分配并填写数据缓冲区(一个字节类型的数组)。 9.3.2 数据报的程序设计过程 1、服务器端发出报文的步骤 (3)分配并填写数据缓冲区(一个字节类型的数组)。 byte[ ] Buf = new byte[256]; 存放从客户端接收的请求信息. (4)创建一个DatagramPacket。 packet = new DatagramPacket(Buf数组, 256字节长度); 用来从socket接收数据,它只有两个参数。 (5)服务器阻塞。 socket.receive(packet); 在客户的请求报道来之前一直等待。
9.3.2 数据报的程序设计过程 1、服务器端发出报文的步骤 (6)从到来的包中得到地址和端口号。 9.3.2 数据报的程序设计过程 1、服务器端发出报文的步骤 (6)从到来的包中得到地址和端口号。 InetAddress address = packet.getAddress(); int port = packet.getPort(); (7)将数据送入缓冲区。来自文件,或键盘输入。 (8)建立报文包,用来从socket上发送信息。 Packet = new DatagramPacket(buf, buf.length, address, port); (9)发送数据包。 socket.send(packet); (10)关闭socket。 socket.close();
9.3.2 数据报的程序设计过程 2、客户端接收包的步骤 (1)定义数据成员。 int port; InetAddress address; 9.3.2 数据报的程序设计过程 2、客户端接收包的步骤 (1)定义数据成员。 int port; InetAddress address; DatagramSocket socket; DatagramPacket packet; byte[ ] sendBuf = new byte[256]; (2)建立socket。 socket = new DatagramSocket(); (3)向服务器发出请求报文。 address = InetAddress.getByName(args[0]); port = parseInt(args[1]); packet = new DatagramPacket(sendBuf, 256, address, port); socket.send(packet);
9.3.2 数据报的程序设计过程 2、客户端接收包的步骤 (4)客户机等待应答。 9.3.2 数据报的程序设计过程 2、客户端接收包的步骤 (4)客户机等待应答。 packet = new DatagramPacket(sendBuf, 256); socket.receive(packet);(如果没有到就一直等待,因此程序要设置时间限度) (5)处理接收到的数据。 String received = new String(packet.getData(), 0, packet.getLength()); System.out.println(received);
数据报工作过程 建立数据报socket(); 建立数据报socket 建立一个报文包packet 建立一个请求包 发出请求 等待请求报文 创建接收包 获得对方地址 等待接收 构成信息包 发送出去
【例9-5】一个简单的数据报示例。 (1)主机1(数据发送方): (2)主机2(数据接收方):
9.3.3 广播数据报套接字 我们把网络上的IP地址划分为A、B、C、D四类,它们是: 9.3.3 广播数据报套接字 我们把网络上的IP地址划分为A、B、C、D四类,它们是: A类地址为:0.0.0.0~127.255.255.255 B类地址为:128.0.0.0~191.255.255.255 C类地址为:192.0.0.0~223.255.255.255 D类地址为:224.0.0.0~239.255.255.255 广播数据报套接字就是利用网络系统保留的D类地址进行发送和接收数据。一个D类地址称为一个广播组,把要广播或接收广播的主机都加入到同一个广播组中,即设置为相同的D类IP地址。
9.3.3 广播数据报套接字 在java中,广播数据报套接字为MulticastSocket类实现,MulticastSocket 是UDP协议 套接字DatagramSocket的子类 ,其构造方法为: (1)MulticastSocket() 创建多播套接字。 (2)MulticastSocket(int port) 创建多播套接字并将其绑定到指定端口。 MulticastSocket类的常用方法: (1)void joinGroup(InetAddress mcastaddr) 加入多播组。 (2)void setTimeToLive(int ttl) 设置在此 MulticastSocket 上发出的多播数据包的默认生存时间,以便控制多播的范围。
【例9-6】一个广播数据报套接字的演示示例。 在这个例子中,一个主机不断地重复播发图像文件,加入到同一组的主机可以随时接收广播的数据内容。接收方接收信息后,将接收到的信息在窗体中显示出来。 (a) 信息发送方播发信息 (b) 显示接收到的信息内容(图像文件)
9.4 JApplet编程 9.4.1 JApplet及常用方法 9.4.2 JApplet应用示例
9.4.1 JApplet及常用方法 JApplet是一个能够嵌入到HTML页面中并在浏览器中运行的Java程序。当使用浏览器对一个包含JApplet的Web页面进行浏览时,浏览器将从Web服务器下载JApplet程序到本地执行。
9.4.1 JApplet及常用方法 1、JApplet的主要特性 JApplet类是一个很特殊的容器,它Applet的子类,Applet是从Java的抽象窗口工具集类库(awt)中的Panel类扩展而来的,它将继承Panel的所有属性。因此,JApplet类具有容器的特性,在其内部可以放置swing组件。
9.4.1 JApplet及常用方法 2、JApplet的常用方法 方法名 功 能 JApplet() JApplet的构造方法 功 能 JApplet() JApplet的构造方法 void init() 由浏览器调用,完成初始化。 void start() 由浏览器调用,开始applet运行。 void stop() 由浏览器调用,终止applet执行。 void destroy() 由浏览器调用,回收分配给applet的资源 void play(URL url) 播放在URL指定的音频剪辑。 AudioClip getAudioClip(URL url) 返回 URL 参数指定的 AudioClip 对象。 Image getImage(URL url) 返回能被绘制到屏幕上的 Image 对象。 URL getDocumentBase() 返回文档的URL路径 void setJMenuBar(JMenuBar menuBar) 设置JApplet的菜单栏。
9.4.1 JApplet及常用方法 3、JApplet程序的一般形式 一个JApplet程序必须是JApplet的子类,它必须是public的。JApplet程序的一般形式为: import javax.JApplet.*; public 类名 extends JApplet { public void init(){…;} public void start(){…;} public void stop(){…;} public void destroy(){…;} … }
9.4.1 JApplet及常用方法 4、JApplet程序的运行 为了执行Applet,必须在HTML文档中使用特殊的标记,即<APPLET>标记来调用Applet。例如: <HTML> <APPLET CODE="Example9_x.class" WIDTH="200" HEIGHT="300"> </APPLET> </HTML>
9.4.2 JApplet应用示例 【例9-7】在浏览器中运行JApplet程序。 1. import javax.swing.*; 2. public class Example9_7 extends JApplet 3. { 4. public void init() 5. { 6. JButton btn = new JButton("确定"); 7. add(btn); 8. } 9. } 编译这个源程序,得到一个Example9_7.class字节码文件。
使用记事本之类的文本编辑工具,编写一个HTML文件如下: < applet code=Example9_7.class height=100 width=300 > </applet> 将这个超文本文件保存为e9_7.html,并且与Example9_7.class在同一文件目录下。现在使用浏览器打开文件e9_7.html就可看到JApplet程序的运行结果。
【例9-8】用getImage()方法和drawImage()方法加载和显示图像。 核心语句: 9. public void init() { 10. img = getImage(getDocumentBase(), getParameter("img")); 11. } 12. 13. public void paint(Graphics g) { 14. g.drawImage(img, 0, 0, this); 15. }
【例9-9】在JApplet程序中使用play()方法播放声音文件。 可以使用JApplet的静态方法编写播放.wav等格式的音频文件的程序。 1. import java.swing.*; 2. import java.awt.Graphics; 3. public class Example9_9 extends JApplet { 4. public void paint(Graphics g) { 5. g.drawString("Listen to the music!", 25, 25); 6. play(getDocumentBase(), "茉莉花.wav"); 7. } 8. }
【例9-10】使用getAudioClip()方法播放声音文件。 用getAudioClip()方法建立的AudioClip对象可以处理声音: play() 开始播放; loop() 循环播放; stop() 停止播放。
9.5 基于分布模式的云计算系统 9.5.1 分布模式的云计算 9.5.2 简易云计算系统设计
9.5.1 分布模式的云计算 在传统的客户/服务环境中,一般有一个功能强大的计算机作为服务器为多个客户提供服务, 9.5.1 分布模式的云计算 在传统的客户/服务环境中,一般有一个功能强大的计算机作为服务器为多个客户提供服务, 下面将讨论一种以客户端为核心、多个服务器为其提供服务的计算模式。这种客户/服务器方式的云计算非常适合分布式系统模型下实现,该模型可以分为3个角色:管理节点、子节点和客户端。管理节点和子节点构成了云计算的服务器端,客户端通过对API的调用实现对云计算系统的访问,并通过API整合为不同的应用程序。
9.5.1 分布模式的云计算 在这种分布模型下,一个并行应用很容易使用这种客户/服务器模式来设计:一个客户可以将一个大的应用分成若干小的问题,这些小的问题可以由多个服务器程序(子节点)同时处理,所以服务器程序对相应问题求得解答后,再发送给客户机。客户机汇集所有从服务器程序发来的结果,然后再输出给用户。
9.5.1 分布模式的云计算 在具体实现这个模型的过程中,要将多个可用服务器(子节点)和它们的Internet域名保存在一个node.txt文件中,这个文件称为子节点配置文件,由客户程序存取它。 客户机同时还要读取另一个文件root.txt,称为用户配置文件,它包括用户定义的应用参数。 子节点配置文件node.txt和用户配置文件root.txt构成管理节点。
9.5.1 分布模式的云计算 基于分布模式的云计算系统
9.5.2 简易云计算系统设计 下面设计一个简易云计算系统,该系统实现由多台服务器共同完成n 阶矩阵的乘法运算任务。 1、系统结构
9.5.2 简易云计算系统设计 2、设计示例 我们现在用C/S结构求解矩阵乘法问题。假定有多台计算机处于WAN中并使用TCP/IP进行通信。使用一个客户和几个服务器求解n * n的“大型”矩阵乘法问题。客户通过子节点配置文件“node.txt”中获取所有的服务器程序必要的信息。如服务器的个数、IP地址或主机名。例如,node.txt文件中的内容为: 3 192.168.1.1 192.168.1.2 192.168.1.3 表示有三个子节点及相应的IP地址。
9.5.2 简易云计算系统设计 然后建立与所有服务的Scoket连接和I/O流。客户从用户配置文件“root.txt”获得矩阵维数N的值,再创建三个矩阵A,B,C,并输入A,B的值,在客户端对任务进行分解,并向每个节点发送一个子任务。这个任务要求每个服务程序收到这个请求之后,完成计算并把结果返回客户。而客户等待各子节点的回复,并将计算结果拼接起来,组成矩阵C。最后,客户将得到结果矩阵C返回给用户。
【例9-11】 简易云计算系统计算矩阵乘法。 (b)客户机端 (a)子节点
小结 实现网络功能要靠URL类, URLConection类, Socket类和DatagramSocket类 网络上的数据传送是将网络连接转换成输入输出流 DataInputStream和DataOutputStream (PrintStream)是网间流的载体. URL适用于web应用,如访问http服务器是高层服务
小结 环回地址可用于在本地机器上调试网络程序 Socket适用于面向连接的,可靠性要求高的应用 Datagram适用于效率要求高的应用 Socket是由IP和端口构成的一种网上通信链路的一端 Socket通信要分别运行服务器和客户程序 服务器程序是多线程的,可处理多个客户的请求
作业 编写一个会话程序 要求: 会话双方可以自由通话,看到对方发来“bye”则退出