革吉网站建设,做网站 域名 服务器的关系,拍卖网站模板,wordpress编辑器添加短代码按钮目录 1.网络中重要的概念
1#xff09;IP地址#xff1a;
2#xff09;端口号#xff1a;
3#xff09;协议
协议分层
OSI七层模型(教科书)
TCP/IP五层模型
封装和分用
网络套接字
面试题#xff1a;TCP/UDP的区别#xff1f;
UDP数据报套接字编程
模拟一个回…目录 1.网络中重要的概念
1IP地址
2端口号
3协议
协议分层
OSI七层模型(教科书)
TCP/IP五层模型
封装和分用
网络套接字
面试题TCP/UDP的区别
UDP数据报套接字编程
模拟一个回显客户端-服务器 1.网络中重要的概念
在网络通信中如何区别是从哪台主机将数据传输到哪台主机上呢这就需要IP地址来标识。
1IP地址
IP地址描述了一台主机在互联网上的位置IP地址是使用一个32位的二进制数表示的通常被分为4个“8位二进制数”也就是4个字节。
使用“点分十进制”这样的方式来表示“IP地址”。这样的方式更有利于人们的阅读。 2端口号
标识主机中发送数据接收数据的进程定位主机上的指定位置应用程序进程
一个主机上使用网络有的很多个程序通过端口号区分当前主机收到的数据是要交给哪些程序来使用。端口号同样也是一个整数一个2个字节的整数。
虽然端口号是0-65535范围但是0-1023这些端口都是有特定含义的我们一般使用这个范围之外的。
问题有了IP地址和端口号就可以定位网络中的唯一进程但是网络通信是基于二进制0/1数据来传输的如何告诉对方发送的数据是什么样呢因为数据的形式多种多样有文字有图片等等
3协议
网络协议简称协议所有网络数据传输经过所有的网络设备都必须遵守的规则比如怎么样建立链接怎么样相互识别。遵守统一的规则计算机才能相互通信交流。
协议最终体现为网络传输数据包的格式。
为什么需要协议?
计算机传播的媒介是光信号和电信号,通过频率,强弱来表示0/1,相传数不同的信息就需要约定好双方的数据格式
计算机的生厂商很多计算机操作系统很多计算机网络硬件设备也很多
如果让这些厂商生产的计算机顺利通信,就必须要有一个共同的标准来遵守 协议分层
了解协议之后,如何进行网络通信的问题就转化为如何设计网络通信协议
网络传输数据依靠光信号,电信号,电磁波,本质上是传输010101这样的一串二进制,通信时就需要约定好这串数字是什么意思..
由于网络通信十分复杂,仅仅一个协议约定网络通信中所有细节是不可能的.所以就会把一个大协议拆分许多小的协议,去解决某一类问题,再让这些小协议相互配合------协议分层 约定好,协议之间不能i相互调用,只能上层调用下层协议; 图中的最后就叫做 协议栈/协议族
协议分层的好处?
降低使用的成本,使用某个协议的时候不需要关注其他协议的实现细节.降低整个协议的耦合性,灵活的变更某个层次的协议 OSI七层模型(教科书) 七层模型过于复杂不实用,所以只存在与教科书上,没有被应用.
TCP/IP五层模型 物理层考虑的较少,所以有时候就是四层模型
应用层负责程序之间的沟通,程序具体要做什么事情.程序员网络编程主要负责这一层的处理传输层只关心网络通信中的起点和终点,不关心通信的中间细节网络层进行网络通信的中间路径规划,还需要负责地址的管理数据链路层针对上述规划的路径进行具体的实施物理层描述的是硬件设备需要描述的物理设备需要什么条件
设备驱动程序是操作系统和硬件通信,管理硬件使用的程序,驱动程序是厂商配套使用的.
主机实现了从传输层到物理层,也就是下四层模型
路由器实现了网络层到物理层下三层结构
交换机实现数据链路层到物理层的下两层结构
集线器只实现了物理层
这里说的交换机与路由器都是传统意义上的机器,现在随着技术发展已经可以实现3/4层的交换机,4层路由器.
所以真实情况下,交换机可能工作在网络层 甚至传输层,路由器也可能工作在数据链路层和网络层,甚至应用层. 封装和分用
封装就类似于字符串的拼接
在使用通信工具的时候,在输入框内一个内容发送; 这个内容就被读取构造成一个应用层数据包
应用层网络协议就描述了数据包的构造. 一般应用层的协议是程序员自己定义的.
例举一个定义应用层数据包的案例.
1.将内容打包成应用层数据包
数据包的格式: 发送者的账号_接受者的账号_发送时间_消息正文\n
数据包的样例: 1234567890_20520863360_2024-08-8-12:00:00_hellow\n;
进行网络传输数据 通常需要把一个结构化的数据转化成一个字符串;
把结构化的数据转化成二进制字符串 这个过程为序列化;
把二进制字符串转化为一个结构化的数据 这个过程为反序列化 2.通信应用程序会调用操作系统提供的API (传输层给应用层提供的API)
操作系统会提供一个类似发送数据这样的API,然后应用程序就会把上述组织好的应用层数据包作为参数传进来,于是应用层数据包就到了系统内核里面,就进入到传输层的代码部分中去.
此时.传输层就会把上述应用层数据包封装成一个传输层数据包. 传输层有多种协议其中最主要的是TCP和UDP,假设此处使用的是UDP.看你代码中具体是哪种API就调用哪个协议.
计算机的封装就类似于字符串的拼接, 3.传输层构造好数据之后,就会继续调用网络层给传输层提供的API,把数据进一步交给网络层.
网络层里也有很多协议,最主要的是IPv4协议(简称IP协议). 当然还有IPv6,但是当前仍是IPv4占主导地位,所以这里默认是IPv4.
IP协议就会把上述的 传输层数据包构造成 网络层数据包 4.网络层继续调用API,把数据交给数据链路层处理
数据链路层常见的协议是以太网(平时插网线,进行上网的这种方式) 5.上述的数据进一步交给物理层(硬件设备)
网卡就会针对上述的二进制数据,进行真正的传输操作.就需要把数据0101这样的序列,转化为光信号/电信号/电磁波. 接收方视角此处做的工作就是发送方的逆向工作发送方的封装认为是快打包接受就是快递拆解。
1.接收光电信号,把这样的信号还原成101001这样的二进制字符串
2.物理层转换回来的数据交给数据链路层,以太网拿到这个数据包,就会对其进行解析.
拿出这里的报头与载荷,根据报头中的一些信息,做出一些处理. 根据报头信息决定是丢弃还是转发,还是保留(向上解析) 3.网络层拿到上述解析好的数据也要对其进一步解析取出IP报头和荷载。 拿出报头数据后也要进行解析取出IP报头 与 载荷决定是丢弃转发 或者是保留
4.传输层这边UDP协议取出UDP报头 和 载荷 此处需要把载荷里的内容交给应用层协议依赖UDP报头中的“端口号” 端口号就是来区分不同的进程的。
5.数据就到了通信应用这样的程序里了 通信程序就要针对数据进行“反序列化”针对这里的数据进行进一步的逻辑。
需要把收到的消息显示到界面上播放消息铃声提醒收到消息显示弹窗更新未读的消息列表 总结什么是封装 与 分用
封装就是将数据从一个层级 包装 到另一个层级的过程。在网络传输中 数据从应用层到物理层会经历的多层包装。以上发送信息的举例就是封装。
分用就是 封装的反过程即从物理层到应用层 逐步剥离各个层级的包装。在接收端数据最终被还原为原始的应用数据。 在封装与分用的过程中可能存在很多交换机 路由器完成数据转发的过程。 中间过程的交换机 路由器也会涉及到 封装与分用。
交换机封装到 数据链路层决定数据是丢弃还是继续转发不再继续分用教科书上的交换机
路由器封装分用到网络层可以决定是数据继续转发 还是丢弃。 网络套接字
Socket套接字
是由系统提供的用于网络通信技术基于TCP/UDP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。
本身为插槽的意思是操作系统给应用程序传输层给应用层提供的API。
这个API有两种一种是TCP一种是UDP
面试题TCP/UDP的区别
TCP有连接可靠传输面向字节流全双工
UDP无连接不可靠传输面向数据报全双工
解释
有无连接就是通信双方是否保留了通信对端的信息保留就相当于是“有连接”不保留就是“无连接”。
可靠不可靠传输就是能不能将数据传输到对端这里的可靠也不是%100而是大概率。
TCP内置了一些机制能够保证可靠传输
1.感知到对方是不是收到了
2.重传机制在对方没有收到的时候进行重试。
UDP没有重传机制也不管数据有没有顺利达到对端。
面向字节流TCP传输的过程就和文件流/水流一样特点。
面向数据报传输数据的基本单位不是字节而是 ”UDP数据报“一次发送或者接受的就是一个 UDP数据报。
全双工一个通信链路可以发送数据也可以接收数据双向通信
半双工一个通信链路只能发送/只能接收单向通信 UDP数据报套接字编程
DatagramSocket代表一个Socket对象通过代码直接操作网卡不好操作通过操作系统把网卡封装成Socket应用程序不关心硬件差异 统一操作Socket对象就能间接操作网卡。
DatagramSocket 是UDP Socket⽤于发送和接收UDP数据报。
DatagramSocket 构造⽅法
⽅法签名⽅法说明DatagramSocket()创建一个UDP数据报嵌套字的Socket绑定到本机任意一个随机端口一般用于客户端DatagramSocket(int port)创建一个UDP数据报嵌套字Socket绑定到本机指定端口一般用于服务器
DatagramSocket ⽅法
⽅法签名⽅法说明void receive(DatagramPacket p)从此套接字接收数据报如果没有接收到数据报该⽅法会阻塞等待void send(DatagramPacket p)从此套接字发送数据报包不会阻塞等待直接发送void close()关闭此数据报套接字 模拟一个回显客户端-服务器
服务器代码
package network;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UdpEchoServer {private DatagramSocket socket null;public UdpEchoServer(int port) throws SocketException {socket new DatagramSocket(port);}// 通过 start 启动服务器的核心流程public void start() throws IOException {System.out.println(服务器启动!);while (true) {// 此处通过 死循环 不停的处理客户端的请求.// 1. 读取客户端的请求并解析DatagramPacket requestPacket new DatagramPacket(new byte[4096], 4096);socket.receive(requestPacket);// 上述收到的数据, 是二进制 byte[] 的形式体现的. 后续代码如果要进行打印之类的处理操作// 需要转成字符串才好处理.String request new String(requestPacket.getData(), 0, requestPacket.getLength());// 2. 根据请求计算响应, 由于此处是回显服务器. 响应就是请求.String response process(request);// 3. 把响应写回到客户端DatagramPacket responsePacket new DatagramPacket(response.getBytes(), response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);// 4. 把日志打印一下.System.out.printf([%s:%d] req%s, resp%s\n, requestPacket.getAddress(), requestPacket.getPort(),request, response);}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoServer server new UdpEchoServer(9090);server.start();}
}
客户端代码
package network;import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket null;private String serverIP;private int serverPort;public UdpEchoClient(String serverIP, int serverPort) throws SocketException {socket new DatagramSocket();this.serverIP serverIP;this.serverPort serverPort;}public void start() throws IOException {System.out.println(启动客户端);Scanner scanner new Scanner(System.in);while (true) {// 1. 从控制台读取到用户的输入.System.out.print(- );String request scanner.next();// 2. 构造出一个 UDP 请求, 发送给服务器.DatagramPacket requestPacket new DatagramPacket(request.getBytes(), request.getBytes().length,InetAddress.getByName(this.serverIP), this.serverPort);socket.send(requestPacket);// 3. 从服务器读取到响应DatagramPacket responsePacket new DatagramPacket(new byte[4096], 4096);socket.receive(responsePacket);String response new String(responsePacket.getData(), 0, responsePacket.getLength());// 4. 把响应打印到控制台上.System.out.println(response);}}public static void main(String[] args) throws IOException {// UdpEchoClient client new UdpEchoClient(47.108.28.88, 9090);UdpEchoClient client new UdpEchoClient(127.0.0.1, 9090);client.start();}
}