Net 2

  • October 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Net 2 as PDF for free.

More details

  • Words: 2,004
  • Pages: 58
网络部分 网络基础理论 InetAddress 类 URL 类 Socket 通信机制 多线程服务器 数据报文通信 广播式通信

计算机网络基础  什么是计算机网络 –把分布在不同地理区域的计算机与专门的外部设备 用通信线路互连成一个规模大、功能强的网络系统 ,从而使众多的计算机可以方便地互相传递信息, 共享硬件、软件、数据信息等资源。

 计算机网络的主要功能 –资源共享 –信息传输与集中处理 –均衡负荷与分布处理 –综合信息服务 (www/ 综合业务数字网络 ISDN)

计算机网络分类  按规模大小和延伸范围划分: – 局域网( LAN -- local area network ) – 城域网( MAN-- metropolitan area network ) – 广域网( WAN – wide area network )  按照网络的拓扑结构划分: – 环形网、星形网、总线型网等  按照通信 传输的介质来划分: – 双绞线网、同轴电缆网、光纤网和卫星网等  按照信号频带占 用方式划分: – 基带网和宽带网

局域网的几种工作模式  专用服务器结构 (Server-Based) 又称为“工作站/文件服务器”结构,由若干台微机工作站 与一台或多台文件服务器通过通信线路连接起来组成工作站 存取服务器文件,共享存储设备。

 客户机 / 服务器模式 (client / server) 其中一台或几台较大的计算机集中进行共享数据库的管理和 存取,称为服务器,而将其它的应用处理工作分散到网络中 其它微机上去做,构成分布式的处理系统。

 对等式网络:( Peer-to-Peer) 在拓扑结构上与专用 Server 与 C / S 相同。在对等式网络 结构中,没有专用服务器 每一个工作站既可以起客户机作用 也可以起服务器作用。

网络通信协议及接口  什么是网络通信协议 计算机网络中实现通信必须有一些约定即通信协议 ,对速率、传输代码、代码结构、传 输控制步骤 、出错控制等制定标准。

 网络通信接口 为了使两个结点之间能进行对话,必须在它们之间 建立通信工具 ( 即接口 ) ,使彼此之间 能进行信 息交换。接口包括两部分: –硬件装置 : 实现结点之间的信息传送 –软件装置 : 规定双方进行通信的约定协议

通信协议分层的思想  为什么要分层 由于结点之间联系很复杂,在制定协议时,把复杂成份分 解成 一些简单的成份,再将它们复合起来。最常用的复 合方式是层次方式,即同层间可以通信、上一层可以调用 下一层,而与再下一层不发生关系。

 通信协议的分层规定 把用户应用程序作为最高 层,把物理通信线路作为最低 层,将其间的协议处理分为若干层,规定每层处理的任务 ,也规定每层的接口标准。

通信协议分层演示 主机 A

第 5 层 第 4 层 第 3 层 第 2 层 第 1 层

第 5 层协议 第 4 层协议 第 3 层协议 第 2 层协议 第 1 层协议

物 理 介 质

第 5 层 第 4 层 第 3 层 第 2 层 第 1 层

主机 B

参考模型 OSI 参考模型

TCP/IP 参考模型

应 用 层 表 示 层







传 输 层







网 络 层







会 话 层

数据链路层 物 理 层

物理 + 数据链路层

数据的封装与拆封 • 封装 – 发送方数据在网络模型的各层传送过程中加入 头尾的过程

• 拆封 – 接受方收到数据后去除相应的头尾的过程

TCP/IP 协议 TCP -- Transmission Control Protocol IP -- Internet Protocol  TCP/IP 协议可保证不同厂家生产的计算机能在共同网 络环境下运行,解决异构网通信问题, TCP/IP 与低 层的数据链路层和物理层无关,能广泛地支持由低两层 协议构成的物理网络结构。  TCP -- 面向连接的可靠数据传输协议; TCP 重发一切 没有收到的数据,进行数据内容准确性检查并保证分组 的正确顺序。

IP 协议  IP 协议是网际层的主要协议,支持网间互连 的数据报通信。它提供主要功能有: – 无连接数据报传送 – 数据报路由选择和差错控制

 IP 协议主要特性: IP 协议将报文传送到目的主机后,无论传送正确与否 都不进行检验、不回送确认、不保证分组的正确顺序 。

IP 地址 TCP/IP 用 IP 地址来标识源地址和目的地址  IP 地址功能:为实现网络中不同计算机之间的通信 ,每台机器都必须有一个与众不同的标识 ---IP 地址 ;  IP 地址格式:数字型, 32 位,由 4 个 8 位的二进制 数组成,每 8 位之间用圆点隔开,如: 166.111.78.98 ;  IP 地址组成:网络标识 (netId) + 主机标识 (hostId) ;  IP 地址分类:分为 A 、 B 、 C 三类,每个类别的网 络标识和主机标识各有规则。

Java 网络编程 • Java 所提供的网络功能可大致分为三大类 – URL 和 URLConnection 这是三大类功能中最高级 的一种。通过 URL 的网络资源表达方式,很容 易确定网络上数据的位置 – Socket ,可以想像成两个不同的程序通过网络 的通道,而这是传统网络程序中最常用的方法 – Datagram 是不可靠方式的连接, Datagram不能 保证传送质量

网络部分 网络基础理论 InetAddress 类 URL 类 Socket 通信机制 多线程服务器 数据报文通信 广播式通信

InetAddress 类 • java.net.InetAddress 类是 Java 的 IP 地址封装类,它 不需要用户了解如何实现地址的细节 • InetAddress 类没有构造方法,要创建该类的实例对 象,可以通过该类的静态方法获得该对象 – public static InetAddress getLocalHost() – public static InetAddress getByName (String host) – public static InetAddress[] getAllByName(String host)

实例 1—— 查寻 IP 地址版本 import java.net.*; import java.io.*; public class IPVersion { public static void main(String args[]) { try { InetAddress inetadd=InetAddress.getLocalHost(); byte[ ] address=inetadd.getAddress( ); if (address.length==4) { System.out.println("The ip version is ipv4"); int firstbyte=address[0]; if (firstbyte<0) firstbyte += 256; if((firstbyte&0x80)==0 ) System.out.println("the ip class is A"); else if ((firstbyte&0xC0)==0x80 ) System.out.println("The ip class is B"); else if((firstbyte&0xE0)==0xC0 ) System.out.println("The ip class is C"); else if((firstbyte&0xF0)==0xE0) System.out.println("The ip class is D"); else if((firstbyte&0xF8)==0xF0 ) System.out.println("The ip class is E"); } else if(address.length==16) System.out.println("The ip version is ipv6"); } 36 catch (Exception e) { };

实例 2—— 取得主机名 import java.net.*; import java.io.*; class Internet { public static void main(String args[]) { try { InetAddress inetadd; inetadd=InetAddress.getLocalHost(); System. out. println ("hostname="+inetadd.getHostName()); System. out. println(inetadd.toString() ); } catch(Exception e) { System.out.println(e); }} }

网络部分 网络基础理论 InetAddress 类 URL 类 Socket 通信机制 多线程服务器 数据报文通信 广播式通信

URL 类  URL(Uniform Resource Locator)---- 统一资源定位器 ,表示 Internet 上某一资源的地址。  URL 组成 : 协议名和资源名 protocol:resourceName

 URL 举例 : – http://www.sun.com/ – http://home.netscape.com/home/welcome.html – http://www.sun.com.cn/developers/

java.net .URL 类  常用构造方法 – public URL(String spec); URL u1 = new URL(“http://home.netscape.com/home/”); – public URL(URL context, String spec); URL u2 = new URL(u1, “welcome.html”); – public URL(String protocol, String host, String file); URL u3 = new URL(“http”, “www.sun.com”, “developers/index.html” ); – public URL (String protocol, String host, int port, String file); URL u4 = new URL(“http”, “www.sun.com”, 80, “developers/index.html” );

URL 类中基本方法 • • • • •

public final Obect getContent() 这个方法取得传输协议 public String getFile() 这个方法取得资源的文件名     public String getHost() 这个方法取得机器的名称     public int getPort() 这个方法取得端口号     public String getProtocol() 这个方法取得传输协议

• public String toString() 这个方法把 URL 转化为字符串。

URL 类应用举例 (1) import java.io.*; import java.net.*; public class URLReader{ public static void main(String args[]){ try{ URL tirc = new URL("http://www.tsinghua.edu.cn/"); BufferedReader in = new BufferedReader(new InputStreamReader(tirc.openStream())); String s; while((s = in.readLine())!=null) System.out.println(s); in.close(); }catch(MalformedURLException e) { System.out.println(e); }catch(IOException e){ System.out.println(e); } } }

URL 类应用举例 (2) 程序 URLReader.java 输出结果 : 清华大学网站首页 <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <meta http-equiv="refresh" content="0;URL=./eng/index.htm"> // 如使用了代理服务器,则使用下述命令运行: //java -Dhttp.proxyHost= -Dhttp.proxyPort=<port> URLReader

网络部分 网络基础理论 InetAddress 类 URL 类 Socket 通信机制 多线程服务器 数据报文通信 广播式通信

什么是套节字( Socket ) • 网络接口是实现服务器程序与一个或多个客户程 序之间双向通信的软件端点 • 网络接口使服务器程序与运行该程序的计算机上 特定的硬件端口关联起来,这样 在网络中的任何 位置上,带有与该端口相关联的网络接口的客户 程序都可以与这 个服务器程序实现通信。 • 套节字是用于实现网络上的客户程序与服务器程 序之间的连接,这个连接的端点即称为套节字 – 套节字负责网络上的通信,客户程序可以向套节字里 写入请求,然后服务器会处理这个请求,并把处理结 果通过套节字返回

• 套节字是在较底的层次上进行通信的

Socket  两个 Java 应用程序可通过一个双向的网络通信连 接实现数据交换,这个双向链路的一端称为一个 socket 。  socket 通常用来实现 client-server 连接。  java.net 包中定义的两个类 Socket 和 ServerSocket , 分别用来实现双向连接的 client 和 server 端  建立连接时所需的寻址信息 – 远程计算机的机器名或 IP 地址 – 试图连接的端口号 (Port number)

套节字工作原理 • 服务器程序对某个特定的端口监听 • 客户端对服务器端进行连接请求 • 建立连接,客户端被分配一个本地端口号 与一个 socket 连接 • 客户端与服务器端通过 socket 套节字进行交 流

Socket 通信模型 Server

Client

ServerSocket s (port #) s.accept()/ 等待连接 Socket() OutputStream InputStream socket.close()

Socket (host, port #) ( Attempt to connect ) OutputStream InputStream socket.close()

网络编程的四个基本步骤 1. 创建 socket; 2. 打开连接到 socket 的输入 / 输出流; 3. 按照一定的协议对 socket 进行读 / 写操作 ; 4. 关闭 socket;

创建 socket Socket/ServerSocket 类的构造方法 Socket(InetAddress address, int port); Socket(InetAddress address, int port, boolean stream); Socket(String host, int port); Socket(String host, int port, boolean stream); ServerSocket(int port); ServerSocket(int port, int count);

 客户端 Socket 的建立 try{ Socket socket=new Socket(”127.0.0.1",2000); }catch(IOException e){ System.out.println("Error:"+e); }

 服务器端 Socket 的建立 ServerSocket server=null; try { server=new ServerSocket(2000); }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); }

 打开输入 / 出流 PrintStream os=new PrintStream(new BufferedOutputStream (socket.getOutputStream())); DataInputStream is=new DataInputStream(socket.getInputStream());

 关闭 Socket os.close(); is.close(); socket.close();

简单的 client/server 程序 import java.net.*; import java.io.*; public class TestServer { public static void main(String args[]) { try { ServerSocket s = new ServerSocket(8888); while (true) { Socket s1 = s.accept(); OutputStream os = s1.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); dos.writeUTF("Hello," + s1.getInetAddress() + "port#" +s1.getPort() + " bye-bye!"); dos.close(); s1.close(); } }catch (IOException e) { System.out.println(" 出错 :" + e);} } }

简单的 client/server 程序 import java.net.*; import java.io.*; public class TestClient { public static void main(String args[]) { try { Socket s1 = new Socket("127.0.0.1", 8888); InputStream is = s1.getInputStream(); DataInputStream dis = new DataInputStream(is); System.out.println(dis.readUTF()); dis.close(); s1.close(); } catch (ConnectException connExc) { System.err.println(" 服务器连接失败! "); } catch (IOException e) { } } }

网络部分 网络基础理论 InetAddress 类 URL 类 Socket 通信机制 多线程服务器 数据报文通信 广播式通信

多线程服务器 • 服务器程序一般都向客户程序网络提供资源。客 户程序向服务器程序发送请求, 而服务器程序则 对该请求作出应答。 • 处理一个以上客户请求的方法之一是使服务器程 序多线程化。多线程的服务器 为每一个从客户机 接收到的通信创建一个线程。线程是一个独立于 运行程序和其 他线程的指令序列。 • 通过使用线程,多线程化的服务器程序就可以接 受来自客户机的连接,启动该 通信的线程并继续 监视来自其它客户机的请求。

多线程服务器原理 • 上述代码只能在服务器程序和一个客户程 序之间工作 • 若要实现多客户连接,就必须把服务器程 序转化为一个多线程化的服务器程序 • 多线程化服务器程序为每个客户请求生成 一个新线程,这样,每个客户机就有了自 己与服务器来往传递数据的连接。当运行 多个线程时,用户必须确保一个线程不会 受到其它线程中数据的干扰

创建服务器端 public void listenSocket(){ try{ server = new ServerSocket(4444); } catch (IOException e){ System.out.println("Could not listen on port 4444"); System.exit(-1); } while(true){ ClientWorker w; try{ //server.accept returns a client connection w = new ClientWorker(server.accept(), textArea); Thread t = new Thread(w); t.start(); } catch (IOException e) { System.out.println("Accept failed: 4444"); System.exit(-1); }}}

线程 class ClientWorker implements Runnable { private Socket client; private JTextArea textArea; //Constructor ClientWorker(Socket client, JTextArea textArea){ this.client = client; this.textArea = textArea; } public void run(){ String line; BufferedReader in = null; PrintWriter out = null; try{ in = new BufferedReader(new InputStreamReader(client.getInputStream())); out = new PrintWriter(client.getOutputStream(), true); } catch (IOException e) { System.out.println("in or out failed"); System.exit(-1); } while(true){ try{ line = in.readLine(); //Send data back to client out.println(line); //Append data to text area textArea.append(line); }catch (IOException e) { System.out.println("Read failed"); System.exit(-1);

网络部分 网络基础理论 InetAddress 类 URL 类 Socket 通信机制 多线程服务器 数据报文通信 广播式通信

数据报通信 • 数据报是网上传输的独立数据包 ,数据报 是否能正确地到达目的地,到达的时间, 顺序,内容的正确性均没有保障 • java.net 包中有两个类 DatagramSocket 和 DatagramPacket ,为应用程序中采用数据报 通信方式进行网络通信

DategramPacket 包 • DategramPacket 类用来创建数据包 – 数据包有两种,一种用来传递数据包,该数据包有要 传递到的目的地址;另一种数据包用来接收传递过来 的数据包中的数据 – 要创建接收的数据包,通过 DatagramPackett 类的方法构 造:      public DatagramPacket(byte ibuft[],int ilength) public DatagramPacket( byte ibuft[],int offset ,int ilength) –   创建发送数据包的构造方法为:      public DatagramPacket ( byt ibuf[],int ilength,InetAddrss iaddr,int port )      public DatagramPacket ( byt ibuf[],int offset , int ilength,InetAddrss iaddr,int port )

一些基本方法 • • • •

• •

public InetAddress getAddress() 如果是发送数据包,则获得数据包要发送 的目标地址,但是如果是接收数据包则返回发送此数据包的源地址 public byte [] getData() 返回一个字节数组,其中是数据包的数据。如 果想把字节数组转换成别的类型就要进行转化 public int getLength() 获得数据包中数据的字节数。     pubic int getPort( ) 返回数据包中的目标地址的主机端口号。发送和接收 数据包还需要发送和接收数据包的套接字,即 DatagramSocket 对象, DatagramSocket 套接字在本地机器端口监听是否有数据到达或者将数 据包发送出去 public DatagramSocket() 用本地机上任何一个可用的端口创建一个套接 字,这个端口号是由系统随机产生的 public DatagramSocket ( int port )用一个指定的端口号 port 创建一个套 接字

Datagram 通信方式 • Java 的 java.net.package 通过 DatagramPacket 和 DatagramSocket 类来收发 datagram • 这两个类的创建和用法并不相同 – 要发送数据报,首先要创建一个 DatagramPacket ,指定 要发送的数据和数据长度,发送的主机地址和端口号 ,然后用 DatagramSocket 类的 Send() 方法发送数据 – 要接收数据报,首先要创建 DatagramSocket 对象来监听 主机上的端口,然后创建 Datagram Packet 对象,指定缓 冲区接收数据。最后, DatagramSocket 的 receive() 方法 接收数据

数据报通信原理

例——多线程数据报服务器 import java.io.*; public class QuoteServer { public static void main(String[] args) throws IOException { new QuoteServerThread().start(); } }

import java.io.*; import java.net.*; import java.util.*; public class QuoteServerThread extends Thread { protected DatagramSocket socket = null; protected BufferedReader in = null; protected boolean moreQuotes = true; public QuoteServerThread() throws IOException { this("QuoteServerThread"); } public QuoteServerThread(String name) throws IOException { super(name); socket = new DatagramSocket(4445); try { in = new BufferedReader(new FileReader("one-liners.txt")); } catch (FileNotFoundException e) { System.err.println("Could not open quote file. Serving time instead."); } } public void run() { while (moreQuotes) { try { byte[] buf = new byte[256]; // receive request DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); // figure out response String dString = null; if (in == null) dString = new Date().toString(); else dString = getNextQuote();

buf = dString.getBytes(); // send the response to the client at "address" and "port" InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); socket.send(packet); } catch (IOException e) { e.printStackTrace(); moreQuotes = false; } } socket.close(); } protected String getNextQuote() { String returnValue = null; try { if ((returnValue = in.readLine()) == null) { in.close(); moreQuotes = false; returnValue = "No more quotes. Goodbye."; } } catch (IOException e) { returnValue = "IOException occurred in server."; } return returnValue; } }

import java.io.*; import java.net.*; import java.util.*; public class QuoteClient { public static void main(String[] args) throws IOException { if (args.length != 1) { System.out.println("Usage: java QuoteClient "); return; } // get a datagram socket DatagramSocket socket = new DatagramSocket(); // send request byte[] buf = new byte[256]; InetAddress address = InetAddress.getByName(args[0]); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); // get response packet = new DatagramPacket(buf, buf.length); socket.receive(packet); // display response String received = new String(packet.getData(), 0); System.out.println("Quote of the Moment: " + received); socket.close(); } }

例——端口扫描 import java.net.*; public class UDPScan { public static void main(String args[]){ for (int port=1024;port<=65535;port++) { try { DatagramSocket server=new DatagramSocket(port); server.close(); }catch(SocketException e){ System.out.println("there is a server in port "+port+"."); } } } }

网络部分 网络基础理论 InetAddress 类 URL 类 Socket 通信机制 多线程服务器 数据报文通信 广播式通信

广播式通信 • 服务器一端以一定的间歇广播发送数据,客户端 被动接收 • java 的 MulticastSocket 类可以实现广播发送 • datagramsocket 只允许数据报发送一个目的地址, java.net 包中提供了一个类 multicastsocket ,允许数 据以广播方式发送到该端口的所有用户 • multicastsocket 用在客户端,监听服务器广播来的 数据

例——多线程广播服务器 public class MulticastServer { public static void main(String[] args)throws java.io.IOException { new MulticastServerThread().start(); } }

import java.io.*; import java.net.*; import java.util.*; public class MulticastServerThread extends QuoteServerThread { private long FIVE_SECONDS = 5000; public MulticastServerThread() throws IOException{ super("MulticastServerThread"); } public void run() { while (moreQuotes) { try { byte[] buf = new byte[256]; // construct quote String dString = null; if (in == null) dString = new Date().toString(); else dString = getNextQuote(); buf = dString.getBytes(); // send it InetAddress group = InetAddress.getByName("230.0.0.1"); DatagramPacket packet = new DatagramPacket(buf, buf.length, group, 4446); socket.send(packet); // sleep for a while try{ sleep((long)(Math.random() * FIVE_SECONDS)); } catch (InterruptedException e) { } } catch (IOException e) { e.printStackTrace(); moreQuotes = false; } } socket.close(); }}

import java.io.*; import java.net.*; import java.util.*; public class MulticastClient { public static void main(String[] args) throws IOException { MulticastSocket socket = new MulticastSocket(4446); InetAddress address = InetAddress.getByName("230.0.0.1"); socket.joinGroup(address); DatagramPacket packet; // get a few quotes for (int i = 0; i < 5; i++) { byte[] buf = new byte[256]; packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String(packet.getData()); System.out.println("Quote of the Moment: " + received); } socket.leaveGroup(address); socket.close(); } }

练习 1. 分析并运行前述 client/server 程序,体会 Socket 编程原理及其实现机制; 2. 在 1 的基础上,编写程序实现一对一的聊天 程序 (talkshow) : client 和 server 端程序建立 连接后双方可以自由通话;

小结 • 掌握 : – 网络基础与协议原理 – URL 类的用法 – 建立 Socket 通信的步骤

• 了解: – 多线程服务器原理 – 数据报通信方式 – 广播

Related Documents

Net 2
October 2019 10
Net 2
October 2019 8
Net
November 2019 45
Net
May 2020 23
Net
October 2019 36
Net
April 2020 24