OSI模型包含7个层次:
物理层是OSI参考模型的最低层,它利用传输介质为数据链路层提供物理连接。物理层的作用是通过传输介质发送和接收二进制比特流。
(2)数据链路层(Data Link Layer)
数据链路层是为网络层提供服务的,解决两个相邻结点之间的通信问题,传送的协议数据单元称为数据帧。
(3)网络层(Network Layer)
网络层是为传输层提供服务的,传送的协议数据单元称为数据包或分组。该层的主要作用是解决如何使数据包通过各结点传送的问题。
(4)传输层(Transport Layer)
传输层的作用是为上层协议提供端到端的可靠和透明的数据传输服务,包括处理差错控制和流量控制等问题。该层向高层屏蔽了下层数据通信的细节,使高层用户看到的只 是在两个传输实体间的一条主机到主机的、可由用户控制和设定的、可靠的数据通路。
传输层传送的协议数据单元称为段或报文。
(5)会话层(Session Layer)
会话层主要功能是管理和协调不同主机上各种进程之间的通信(对话),即负责建立、管理和终止应用程序之间的会话。
(6)表示层(Presentation Layer)
表示层处理流经结点的数据编码的表示方式问题,以保证一个系统应用层发出的信息可被另一系统的应用层读出。数据压缩和加密是表示层可提供的转换功能之一。
(7)应用层(Application Layer)
应用层是OSI参考模型的最高层,是用户与网络的接口。该层通过应用程序来完成网络用户的应用需求,如文件传输、收发电子邮件等。
TCP/IP分层模型:
(1)网络接口层
网络接口层包括用于协作IP数据在已有网络介质上传输的协议。实际上TCP/IP标准并不定义与ISO数据链路层和物理层相对应的功能。相反,它定义像地址解析协议 (Address Resolution Protocol,ARP)这样的协议,提供TCP/IP协议的数据结构和实际物理硬件之间的接口。
(2)网络互联层
网间层对应于OSI七层参考模型的网络层。本层包含IP协议、RIP协议(Routing Information Protocol,路由信息协议),负责数据的包装、寻址和路由。同时还包含网 间控制报文协议(Internet Control Message Protocol,ICMP)用来提供网络诊断信息。
(3)传输层
传输层对应于OSI七层参考模型的传输层,它提供两种端到端的通信服务。其中TCP协议(Transmission Control Protocol)提供可靠的数据流运输服务,UDP协议 (Use Datagram Protocol)提供不可靠的用户数据报服务。
(4)应用层
应用层对应于OSI七层参考模型的应用层和表达层。因特网的应用层协议包括Finger、Whois、FTP(文件传输协议)、Gopher、HTTP (超文本传输协议)、 Telent(远程终端协议)、SMTP(简单邮件传送协议)、IRC(因特网中继会话)、NNTP(网络新闻传输协议)等。
客户端与服务器:
客户端(client)是通信的发起者;服务器(server)程序则被动等待客户端分清通信。客户端与服务器组成了应用程序。
一个程序是作为客户端还是服务器,决定了它在与其对等端(Peer)建立通信时使用的套接字API形式。
套接字:
Socket(套接字)是一种抽象层应用程序通过它来发送和接受数据。现在TCP/IP协议族中的主要socket类型为流套接字和数据报套接字。一个TCP/IP套接字由一个IP地址、一个端对端协议(TCP或UDP协议)以及一个端口号唯一确定。
TCP套接字编程:
1.服务器初始化一个ServerSocket对象,指示通讯将要发生在那个端口上;
2.服务器调用SErverSocket类的accept()方法。该方法会一只等待,直到一个客户端连接到服务器上的指定端口;
3.在服务器等待的同时,客户端实例化一个Socket对象,指定要连接的服务器名和端口号;
4.Socket类的构造器试图将客户端连接到指定的服务器和端口号,如果通讯建立了,客户端现在就有一个能够与服务器进行通讯的Socket对象;
5.在服务器端,accept()方法返回一个将要连接到客户端的套接字的服务器新套接字的引用。
1 package Chap18; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 import java.io.OutputStreamWriter; 8 import java.net.ServerSocket; 9 import java.net.Socket; 10 /* 11 * 服务端 12 */ 13 public class Server { 14 public static void main(String[] args) throws IOException { 15 ServerSocket server = new ServerSocket(3001); 16 Socket socket = server.accept(); 17 //写 18 BufferedReader reader = new BufferedReader( 19 new InputStreamReader(socket.getInputStream())); 20 char[] ch = new char[100]; 21 int len = reader.read(ch); 22 System.out.println("从客户端接收消息:"); 23 System.out.println(new String(ch, 0, len)); 24 //读 25 BufferedWriter writer = new BufferedWriter( 26 new OutputStreamWriter(socket.getOutputStream())); 27 writer.write("你好我是服务器"); 28 writer.flush(); 29 //释放资源 30 reader.close(); 31 writer.close(); 32 socket.close(); 33 server.close(); 34 } 35 }
1 package Chap18; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 import java.io.OutputStreamWriter; 8 import java.net.Socket; 9 import java.net.UnknownHostException; 10 /* 11 * 客户端 12 */ 13 public class Client { 14 public static void main(String[] args) throws UnknownHostException, IOException { 15 Socket socket = new Socket("127.0.0.1", 3001); 16 //向服务器写入数据 17 BufferedWriter writer = new BufferedWriter( 18 new OutputStreamWriter(socket.getOutputStream())); 19 writer.write("你好服务器,我是客户端"); 20 writer.flush(); 21 //从服务器读取数据 22 BufferedReader reader = new BufferedReader( 23 new InputStreamReader(socket.getInputStream())); 24 25 char[] ch = new char[100]; 26 int len = reader.read(ch); 27 System.out.println("从服务端接收到消息:"); 28 System.out.println(new String(ch, 0, len)); 29 writer.close(); 30 reader.close(); 31 socket.close(); 32 } 33 }
套接字之间的相互通讯:一个Socket的InputStream和OutputStream属性是两台计算机进行相互通讯的途径。
UDP套接字编程:
作用:
将二进制数据从一台计算机发送到另一台计算机的非连接协议。这里,数据被称为数据包,它包含了数据将要发送到的目标服务器和端口号。
数据报包的发送者和接收者都使用java.net.DatagramSocket类分别发送和接收包。
DatagramSocket类的构造器:
1.DatagramSocket():创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、本机所有可用端口中随机选择的某个端口。
2.DatagramSocket(int prot):创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、指定端口。
3.DatagramSocket(int port, InetAddress laddr):创建一个DatagramSocket实例,并将该对象绑定到指定IP地址、指定端口。
通过上面三个构造器中的任意一个构造器即可创建一个DatagramSocket实例,然后通过如下两个方法来接收和发送数据:
receive(DatagramPacket p):从该DatagramSocket中接收数据报。
send(DatagramPacket p):以该DatagramSocket对象向外发送数据报。
DatagramPacket类的构造器:
接收数据报包的两个构造器:
DatagramPacket(byte[] buf,int length):以一个空数组来创建DatagramPacket对象,该对象的作用是接收DatagramSocket中的数据。
DatagramPacket(byte[] buf, int offset, int length):以一个空数组来创建DatagramPacket对象,并指定接收到的数据放入buf数组中时从offset开始,最多放length 个字节。
发送数据报包的四个构造器:
DatagramPacket(byte[] buf, int length, InetAddress addr, int port):以一个包含数据的数组来创建DatagramPacket对象,创建该DatagramPacket对象时还指定 了IP地址和端口--这就决定了该数据报的目的地。
DatagramPacket(byte[] buf, int length, SocketAddress address):与上一个构造器相似,但接收者名字和端口号储存在SocketAddress参数中。
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):创建一个用于发送的DatagramPacket对象,指定发送buf数组中从offset开 始,总共length个字节。
DatagramPacket(byte[] buf, int offset, int length,SocketAddress address):与上一个构造器相似,但接收者名字和端口号储存在SocketAddress参数中。
接收报文包:
1.创建一个足够大的字节数组,用于储存要接收的包的数据;
2.使用该字节数组实例化一个DatagramPacket对象;
3.DatagramSocket被实例化它被指定该套接字要绑定到的本地主机上的一个端口;
4.调用DatagramSocket类的receive()方法,将DatagramPacket对象传入该方法,这将导致执行线程阻塞,直到接收到一个数据报包或者发送了超市超时。
发送报文包:
1.创建一个足够大的字节数组,用于储存要发送的包数据,用该数据填充数组;
2.创建一个新的DatagramPacket对象,用于储存上面的字节数组,以及服务器名和接收者的端口号;
3.DatagramSocket被实例化它被指定套接字要绑定到本地主机的那个端口;
4.DatagramSocket类的send()方法被调用,传入DatagramPacket对象。