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

it2026-01-01  1

一、网络协议分层思想

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

 

分层思想

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

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

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

 

TCP/IP 的分层管理

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

物理层

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

数据链路层

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

网络层

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

传输层

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

应用层

应用程序收到传输层的数据后,接下来就要进行解读。解读必须事先规定好格式,而应用层就是规定应用程序的数据格式。主要的协议有: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 都是传输层协议,但是两者具有不同的特效,同时也具有不同的应用场景。

 

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(); } }

 

最新回复(0)