网络协议分层思想以及IP、TCP、UDP总结

本文介绍了网络协议分层思想,包括TCP/IP的四层模型,详细讲解了IP地址的作用以及TCP和UDP这两个传输层协议的区别。TCP通过三次握手确保连接可靠性,而UDP则更注重效率,适用于实时通信场景。
部署运行你感兴趣的模型镜像

一、网络协议分层思想

什么是网络协议分层思想?系统概念性就不说了,打个比方说将军想向士兵传达命令,将军需要先从校军官衔传达命令,再由校军官衔传达给尉军官衔以此类推,最后传达给士兵。这就是分层思想!

 

分层思想

1、各层次之间相互独立,每层之间都有相应的接口,链接上下层

2、若任意一层发生变化只要层间接口关系保持不变,则该层的上下层均不受影响

3、若整个的系统被分解为若干个相对独立的子系统即分层思想,在进行调试和维护时,可以对每一层进行单独的调试,并不因为某一层的缘故从而导致整个系统瘫痪

 

TCP/IP 的分层管理

TCP/IP协议里最重要的一点就是分层。TCP/IP协议族按层次分别为 应用层,传输层,网络层,数据链路层,物理层。当然也有按不同的模型分为4层或者7层的。

  1. 物理层

    该层负责 比特流在节点之间的传输,即负责物理传输,这一层的协议既与链路有关,也与传输的介质有关。通俗来说就是把计算机连接起来的物理手段。

  2. 数据链路层

    控制网络层与物理层之间的通信,主要功能是保证物理线路上进行可靠的数据传递。为了保证传输,从网络层接收到的数据被分割成特定的可被物理层传输的帧。帧是用来移动数据结构的结构包,他不仅包含原始数据,还包含发送方和接收方的物理地址以及纠错和控制信息。其中的地址确定了帧将发送到何处,而纠错和控制信息则确保帧无差错到达。如果在传达数据时,接收点检测到所传数据中有差错,就要通知发送方重发这一帧。

  3. 网络层

    决定如何将数据从发送方路由到接收方。网络层通过综合考虑发送优先权,网络拥塞程度,服务质量以及可选路由的花费等来决定从网络中的A节点到B节点的最佳途径。即建立主机到主机的通信。

  4. 传输层

    该层为两台主机上的应用程序提供端到端的通信。传输层有两个传输协议:TCP(传输控制协议)和 UDP(用户数据报协议)。其中,TCP是一个可靠的面向连接的协议,udp是不可靠的或者说无连接的协议

  5. 应用层

    应用程序收到传输层的数据后,接下来就要进行解读。解读必须事先规定好格式,而应用层就是规定应用程序的数据格式。主要的协议有:HTTP.FTP,Telent等

二、IP

IP地址用于在TCP/IP通信协议中标记每台计算机的地址,通常用于十进制来表示,如192.168.1.100。但是在计算机内部,IP地址是一个32位的二进制数值,如11000000 10101000 00000001 00000110(192.168.1.6)。

每台电脑上的IP地址都是独一无二的,每台电脑上不同的应用程序可以分成不同的端口,端口又可以分TCP、UDP,每一个各有65536(即:2^16)个

三、TCP与UDP

1、TCP/UDP 都是传输层协议,但是两者具有不同的特效,同时也具有不同的应用场景。

image-20191027212512703

 

2、TCP的三次握手

  • 第一次握手: A给B打电话说,你可以听到我说话吗?
  • 第二次握手: B收到了A的信息,然后对A说: 我可以听得到你说话啊,你能听得到我说话吗?
  • 第三次握手: A收到了B的信息,然后说可以的,我要给你发信息啦!

在三次握手之后,A和B都能确定这么一件事: 我说的话,你能听到; 你说的话,我也能听到。 这样,就可以开始正常通信了,如果是两次,那将无法确定。

3、TCP与UDP程序与写法

(1)TCP:

               ServerSocket端

                    1、建立ServerSocket服务器端口

                    2、调用ServerSocket类中的accept()方法,等待接收

                    3、建立InputStream输入、OutputStream输出通道

                    4、把字节数据封装到DataInputStream、DataOutputStream中

                    5、再调用DataInputStream类中readUTF()方法读取数据,DataOutputStream类中writeUTF()写入数据

                    6、关闭流通道

代码如下:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TestSockServer {

	public static void main(String[] args) {
		InputStream in=null;
		OutputStream out=null;
		
		try {
			//1、建立ServerSocket服务器端口
			ServerSocket ss=new ServerSocket(7777);
			
			//2、调用ServerSocket类中的accept()方法,等待接收
			Socket socket=ss.accept();
			
			// 3、建立InputStream输入、OutputStream输出通道
			in=socket.getInputStream();
			out=socket.getOutputStream();
			
			//4、把字节数据封装到DataInputStream、DataOutputStream中
			DataInputStream dis=new DataInputStream(in);
			DataOutputStream dos=new DataOutputStream(out);
			
			//5、再调用DataInputStream类中readUTF()方法读取数据,DataOutputStream类中writeUTF()写入数据
			String s=null;
			if((s=dis.readUTF())!=null){
				System.out.println(s);
				System.out.println("from:"+socket.getInetAddress());
				System.out.println("Port:"+socket.getPort());
			}
			dos.writeUTF("hi,hello");
			
			//6、关闭流通道
			dos.close();
			dis.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

               Clinet端

                            1、建立socket端口与IP地址,注意Clint端比Server多个IP地址

                            2、建立输入、输出流通道

                            3、把字节数据封装到DataInputStream、DataOutputStream中

                            4、调用DataInputStream类中readUTF()方法读取数据,DataOutputStream类中writeUTF()写入数据

                            5、关闭流通道

代码如下:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TestSockClinet {

	public static void main(String[] args) throws IOException {
		InputStream is=null;
		OutputStream os=null;
		
		try {
			//1、建立socket端口与IP地址,注意Clint端比Server多个IP地址
			Socket socket=new Socket("localhost",7777);
			
			//2、建立输入、输出流通道
			is=socket.getInputStream();
			os=socket.getOutputStream();
			
			//3、把字节数据封装到DataInputStream、DataOutputStream中
			DataInputStream dis=new DataInputStream(is);
			DataOutputStream dos=new DataOutputStream(os);
			
			//4、调用DataInputStream类中readUTF()方法读取数据,DataOutputStream类中writeUTF()写入数据
			dos.writeUTF("hei");
			String s=null;
			if((s=dis.readUTF())!=null);
			System.out.println(s);
			
			//5、关闭流通道
			dis.close();
			dos.close();
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
}

TCP中Server端与Client端写法基本上大同小异,唯一的区别就在于Server端多个accept()方法、Client端多个IP地址,启动程序之前须先启动Server端再启动Celient

 

TCP代码对话框综合练习如下:

Server端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TalkServer {

	public static void main(String[] args) throws IOException {
		Socket socket=null;
		ServerSocket ss=null;
		try {
			ss=new ServerSocket(4700);//建立服务器
			socket=ss.accept();//建立服务器端口连接
			} catch (Exception e) {
				System.out.println("can not listen to:");
				System.out.println("Error"+e);//错误异常
				System.exit(0);//退出
			}
		
		//1)建立socket输入通道,将对话输入进来
		BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
		
		//2)显示Cline端
		System.out.println("Cline:"+is.readLine());
		
		//3)建立socket输出通道,将对话传送出去
		PrintWriter pw=new PrintWriter(socket.getOutputStream());
		//BufferedWriter bw=new BufferedWriter(new OutStreamReader(socket.getOutStream()));
		
		//4)键盘输入转化成字符输入流
		BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
		String s;//null
		s=sin.readLine();//读取一行
		
		//5)显示对话框
		while(!s.equals("bye")){
			//如果键盘不等于bye为true即键盘输入bye结束
			pw.println(s);
			//将在键盘输入的字符串传送到socket端口
			pw.flush();
			//缓冲
			System.out.println("Server:"+s);
			System.out.println("Clinet:"+is.readLine());
			s=sin.readLine();
		}
		
		is.close();
		socket.close();
		ss.close();
		}
}

Client端

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class TalkClient {

	public static void main(String[] args) {
		try {
			//1)建立socket端口
			Socket socket=new Socket("127.0.0.1",4700);
			
			//2)建立socket输出通道,将对话传送出去
			PrintWriter pw=new PrintWriter(socket.getOutputStream());
			
			//3)建立socket输入通道,将对话输入进来
			BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
			
			//4)键盘输入转化成字符输入流
			BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
			String s;
			s=sin.readLine();
			
			//5)
			while(!s.equals("bye")){
				pw.println(s);
				pw.flush();
				System.out.println("Clinet:"+s);
				System.out.println("Server:"+is.readLine());
				s=sin.readLine();
			}
			pw.close();
			is.close();
			socket.close();
		} catch (Exception e) {
			System.out.println("Error"+e);
		}
	}
}

 

(2)UDP

UDP与TCP的区别

1、UDP和TCP不同,UDP中的Server端和Client端都有着各自的端口,Client端在发包时须于Server端接口一致

2、UDP通过DatagramPacket类调用receive()方法接收数据,DatagramSocket调用send()方法发送数据。与TCP建立流通道不同

3、TCP是通过流来进行传送输入数据,UDP是通过基本数据类型包装成数组进行传送输入

          UDPServer端

                             1、新建数组

                              2、新建DatagramPacket类将数组存储

                              3、创建UDP端口5678

                              4、调用DatagramSocket类中的方法receive()接收数据包

                              5、将接收到的数据包转化成数组

                              6、DataInputStream调用readLong()方法读取数据

代码如下

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class TestUDPServer2 {

	public static void main(String[] args) throws Exception {
		//1、新建数组
		byte b[]=new byte[1024];
		
		//2、新建DatagramPacket类将数组存储
		DatagramPacket dp=new DatagramPacket(b,b.length);
		
		//3、创建UDP端口5678
		DatagramSocket ds=new DatagramSocket(5678);
		
		//4、调用DatagramSocket类中的方法receive()接收数据包
		while(true){
			ds.receive(dp);//从此套接字接收数据包
			
			//5、将接收到的数据包转化成数组
			ByteArrayInputStream bais=new ByteArrayInputStream(b);
			
			//6、DataInputStream调用readLong()方法读取数据
			DataInputStream dis=new DataInputStream(bais);
			System.out.println(dis.readLong());
		}
	}
}

          UDPClient端

                             1、新建long类型属性

                              2、将发送的数据包转化成数组

                              3、将数组发送包存储在DataOutputStream数据中,并写入

                              4、调用ByteArrayOutputStream.toByteArray()方法存储在数组当中

                              5、调用DatagramPacket.send()方法发送数据包

代码如下:

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class TestUDPClinet2 {

	public static void main(String[] args)throws Exception{
		//1、新建long类型属性
		long n=10000L;
		
		//2、将发送的数据包转化成数组
		ByteArrayOutputStream baos=new ByteArrayOutputStream();
		
		//3、将数组发送包存储在DataOutputStream数据中,并写入
		DataOutputStream dos=new DataOutputStream(baos);
		dos.writeLong(n);
		
		//4、调用ByteArrayOutputStream.toByteArray()方法存储在数组当中
		byte [] buf=baos.toByteArray();
		
		//5、调用DatagramPacket.send()方法发送数据包
		DatagramPacket dp=new DatagramPacket(buf, buf.length,new InetSocketAddress("127.0.0.1",5678));//dp端口须Server端口一致
		DatagramSocket ds=new DatagramSocket(9999);//Cline端口
		ds.send(dp);//发包
		ds.close();
	}
}

 

您可能感兴趣的与本文相关的镜像

TensorFlow-v2.9

TensorFlow-v2.9

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值