网络通信实现

【 一 】网络通信实现

【 1 】实现网络通信的四要素

  • 本机的ip地址

  • 子网掩码

  • 网关的IP地址

  • DNS的IP地址( 域名系统)

DNS服务器是指提供域名解析服务的服务器。它负责将域名转换为相应的IP地址,以便计算机可以通过IP地址与其他设备进行通信。

image-20240112151848635

通过使用DNS服务器,计算机可以方便地将域名转换为IP地址,并与其他设备进行通信。这在互联网中起到了至关重要的作用。

【2】获取四要素的两种方式

(1) 静态获取

  • 即手动配置

(2)动态获取

  • 通过dhcp获取

以太网头 IP 头 udp头 dhcp数据包

  1. 最前面的”以太网标头”,设置发出方(本机)的MAC地址和接收(DHCP服务器)的MAC地址。前者就是本机网卡的MAC地址,后者这时不知道,就填入一个广播地址:00:1A:2B:3C:4D:5E)。

  2. 后面的‘IP标头’,设置发出的IP地址和接收方的IP地址。这时,对于这两者, 本机都不知道。 于是, 发出方的IP地址就设为0.0.0.0,接收方的IP地址设为255.255.255.255

  3. 最后面的‘UDP标头’, 设置发出方的端口和接收方的端口。这一部分是DHCP协议规定好的,发出方是68端口,接收方是67端口

  4. DHCP数据包(DHCP Packet) : DHCP数据包是动态主机配置协议 (DHCP)中用于自动分配网络配置的信息交换单元。 DHCP数据包由于以下字段组成:

    • 操作码: 指明数据包的类型, 如请求、回复等。

    • 硬件地址: 指明客户端设备的物理地址, 通常是MAC地址。

    • 选项信息: 包括IP地址租约时间、子网掩码、默认网关等配置参数。

【 二 】DNS域名解析

【 1 】DNS的作用

        DNS(Domain Name System,域名系统)是一种用于将域名转换成IP地址的分布式数据库系统。

(1)DNS的作用

  1. 域名解析:最基本的作用是将域名解析为对应的IP地址。当用户在浏览器中输入一个域名时,操作系统会向本地DNS服务器发送查询请求,本地DNS服务器会递归地向其它DNS服务器查询,直到找到该域名对应的IP地址。然后,操作系统将获取到的IP地址返回给浏览器,浏览器通过该IP地址与服务器建立连接。

  2. 负载均衡:DNS还可以用于实现负载均衡。当一个域名对应多个IP地址时,DNS服务器可以根据配置的策略将请求分发到不同的服务器上,从而均衡地分担服务器的负载,提高系统的性能和可用性。

  3. 邮件传递:DNS在邮件系统中也扮演重要角色。MX记录指定了接收邮件的服务器地址,当发送邮件时,邮件服务器会查找目标域名的MX记录,将邮件发送到相应的服务器上。

  4. 安全性:DNS在安全方面也起到关键作用。例如,DNSSEC(DNS Security Extensions)可以提供域名数据的数字签名,确保域名解析结果的真实性和完整性,防止DNS劫持和欺骗攻击。

        总之,DNS的作用是通过将域名解析为对应的IP地址,实现互联网上不同计算机和服务之间的可访问性。同时,DNS还可以用于负载均衡、邮件传递和安全性保证等方面,为互联网的正常运行提供了重要支持。

(2)为什么一定要设置DNS才能上网

有一些客户端应用是打不开网页的,其实大部分原因都是因为DNS服务器故障造成的, DNS服务器地址是唯一的。它们是设定不了DNS服务器地址,那么就无法查询地址的去向,自然也就打不开网页。

而QQ、微信等聊天软件,它们采用的协议是不一样的UDP传输协议, 即不可靠传输协议,无需提供DNS服务器地址, 也同样可以登陆。

【2】DNS的两种查询方式

(1)递归

  • 主机向本地域名服务器的查询一般都是采用递归查询。

  • 所谓递归查询就是:

    • 如果主机询问的本地域名服务器不知道被查询的域名IP地址

    • 那么本地域名服务器就以DNS客户的身份,向其他根域名服务器继续发出查询请求报文(即替主机继续查询)

    • 而不是让主机自己进行下一步查询。

    因此,递归查询返回的查询结果或者是所要查询的IP地址,或者是报错,表示无法查询到所需的IP地址。

(2)迭代

  • 本地域名服务器向根域名服务器的查询的迭代查询。

  • 迭代查询的特点:

    • 当根域名服务器收到本地域名服务器发出的迭代查询请求报文时

      • 要么个所要查询的IP地址

      • 要么高数本地服务器: ‘你下一本应当向哪一个域名服务器进行查询。’

    • 然后让本地服务器进行后续的查询。

    • 根域名服务器通常是把自己知道的停机域名服务器的IP地址高数本地狱名服务器,让本地域名服务器再向停机域名服务器查询。

    • 顶级域名服务器在收到本地域名服务器的查询请求后

      • 要么给出所要查询的IP地址

      • 要么高数本地服务器下一步应当想哪一个权限域名服务器进行查询。

    • 最后,知道了所要解析的IP地址或报错,然后把这个结果返回给发起查询的主机

    总结:
    递归查询在查询过程中只向DNS服务器发起一次请求,DNS服务器一直查找直到找到所需的解析记录,然后返回给客户端。
    而迭代查询则是向DNS服务器发起多次请求,每次请求都会返回指向下一个域名服务器的IP地址或被告知去联系另一个DNS服务器,客户端需要不断向本地DNS服务器发送查询请求,直到回去到最终的IP地址。

【三】Scoket

【1】Scoket层在哪

【2】什么是scoket

Scoket是可以理解为一种抽象端点,它可以用来建立网络连接、发送和接收数据。通过Socket,应用程序可以在不同的计算机之间进行数据交换,实现客户端与服务器之间的通信。

总之:Scoket是一种用于实现网络通信的编程接口,它允许应用程序通过网络在不同的计算机之间进行数据传输和通信。

【3】套接字发展史以及分类

1971年, 美国的伯克利大学开发了第一个实现套接字概念的Unix操作系统。也就是BSD Unix.

分类:

  • 流式套接字(SOCK_STREAM):提供可靠、面向连接的通信方式,例如TCP协议。
  • 数据报套接字(SOCK_DGRAM):提供无连接、不可靠的通信方式,例如UDP协议。
  • 原始套接字(SOCK_RAW):可以直接访问底层网络协议,例如IP协议和ICMP协议。主要用于网络管理和安全领域。
  • 序列包套接字(SOCK_SEQPACKET):提供可靠的数据传输服务,保证数据包按照顺序到达。

(1)基于文件型

  • 基于文件系统实现的套接字。

  • 使用UNIX域协议 (Unix Domain Protocol) 进行通信

  • 适用于进程通信(IPC), 在同一台主机上的进程可以通过该类型套接字互相通信。

(2)网络型套接字

  • 基于网络协议实现的套接字。

  • 包括TCP套接字和UDP套接字, 使用TCP/IP协议进行通信。

  • 适用于网络通信, 可以实现跨主机的进程通信。

需要注意的是, 套接字作为一种通信接口, 实际上并不是文件, 只是UNIX系统中一文件描述的形式存在。因此,我们可以将套接字分为文件型套接字和网络型套接字,以便更好地区分它们的特点和使用场景。

【 四 】TCP协议

TCP(传输控制协议)是一种可靠的、面向连接的网络传输协议,它在计算机网络中提供可靠的数据传输。下面是使用TCP协议的一般流程:

  1. 服务器端创建Socket:服务器应用程序首先创建一个Socket对象,并绑定到特定的IP地址和端口号上,以侦听客户端的连接请求。

  2. 客户端创建Socket:客户端应用程序创建一个Socket对象,并指定服务器的IP地址和端口号,尝试连接到服务器。

  3. 三次握手建立连接:客户端向服务器发送连接请求报文段,服务器接收到请求后可以同意连接,回复一个确认报文段,客户端再发送一个确认报文段,完成连接的建立。

  4. 数据传输:连接建立后,客户端和服务器之间可以通过Socket对象进行数据传输。应用程序可以使用Socket API提供的函数,将数据写入Socket发送给对方,对方则可以通过Socket接收数据。

  5. 四次挥手断开连接:当连接不再需要时,任何一方都可以发送断开连接的请求,并等待对方的确认。双方都发送了断开请求并确认后,连接才会完全关闭。

在IPv4协议中,本地回环地址是127.0.0.1,

在使用TCP协议进行数据传输时,TCP提供了许多功能,如分段、序列号、确认和重传等,以确保数据的可靠性和顺序性。这使得TCP成为应用层协议(如HTTP、FTP等)的常用传输协议,用于可靠地传输数据。

【五】什么是socket粘包

【1】什么是socket的粘包

Socket粘包是值在网络通信中, 由于数据传输的不可预测性,导致接受无法准确的确区分和解析接收到的数据包,使得多个数据包黏在一起,形成一个较大的粘包。这种情况可能会影响同学的可靠性和正确性。

造成Socket粘包的主要原因有两个:

  • TCP协议的特性: TCP是面向流的协议,它提供的是一个字节流的传输,而不是固定大小的的消息。发送方写入的数据以字节为单位被传输,而接收方则以字节为单位进行读取。这就导致了接收方法无法知道数据的边界,容易将多个发送方的小消息喝不成一个大消息,或者将一个大消息拆分成多个小消息

  • 发送频率较快:如果发送方的数据发送速度很快,而接收发的处理速度较慢,接收方可能在处理一个数据包时已经接收到了下一个数据包,从而形成粘包。

解决Socket粘包问题的方法:

  • 消息边界:在消息中包含消息的长度信息, 这样接收方就可以根据长度信息准确地划分出每个完整的消息。这可以通过在消息头部添加长度字段实现。

  • 定界符:使用特殊的字符或序列作为消息的定界符,表示一个消息的结束。接收方通过检测定界符来确定消息的边界。

  • 使用更高层次的协议:例如:使用HTTP或者其他应用层协议,他们通常已经定义了消息的格式和边界。

  • 使用缓冲区:接收方可以使用缓冲区逐步接收数据,并根据特定的规则来提取完整的消息。

【2】解决粘包现象的思路

(1)服务端 

先计算总数据长度 ----> 打到字典 ----> 转成josn字符串 ----> json字符串转成二进制 ----> 计算json二进制的长度 ----> struct打包成四个字节的二进制数据

先发送4个长度的二进制数据 ----> json二进制数据 ----> 总的数据

(1)客户端

先接收收到4个长度的二进制数据 ----> 转码(json二进制数据的长度)----> 继续从通道里面取出json二进制长度的二进制数据 ----> 转码(总数据的长度)----> 获取总的数据

先接收4长度的struct二进制数据 ----> josn二进制数据 ----> 总数据

【六】struct模块如何使用

【1】format参数用于指定打包和解包数据的格式

  • 整数类型:

    • b:有符号字节(signed char)
    • B:无符号字节(unsigned char)
    • h:有符号短整数(signed short)
    • H:无符号短整数(unsigned short)
    • i:有符号整数(signed int)
    • I:无符号整数(unsigned int)
    • l:有符号长整数(signed long)
    • L:无符号长整数(unsigned long)
    • q:有符号长长整数(signed long long)
    • Q:无符号长长整数(unsigned long long)
  • 浮点类型:

    • f:单精度浮点数(float)
    • d:双精度浮点数(double)
  • 字符串类型:

    • s:固定长度的字符串,后面跟上字符串长度。例如,10s表示长度为10的字符串。
    • p:与s类似,但会自动在字符串后面添加空字节。例如,10p表示长度为10的字符串,末尾会自动添加空字节。
  • 其他类型:

    • ?:布尔值(bool)
    • x:占位符,用于对齐数据

在使用format参数时,可以将多个格式代码组合在一起。例如,'ihi'表示有符号整数、有符号短整数、有符号整数的顺序。

需要注意的是,在使用struct模块时,打包和解包数据的格式必须一致,否则会导致数据解析错误。

【2】使用方法

import struct

# 打包数据
data = struct.pack('10s',  b'123')
print(f"打包数据 data: {data}")

# 解包数据
unpacked_data = struct.unpack('10s', data)
print(f"解包数据 data: {unpacked_data}")
# 打包数据 data: b'123\x00\x00\x00\x00\x00\x00\x00'
# 解包数据 data: (b'123\x00\x00\x00\x00\x00\x00\x00',)

相关推荐

  1. Docker 新建网络实现容器间通信

    2024-01-28 15:48:03       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-28 15:48:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-28 15:48:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-28 15:48:03       82 阅读
  4. Python语言-面向对象

    2024-01-28 15:48:03       91 阅读

热门阅读

  1. linux 内核对多播报文的处理

    2024-01-28 15:48:03       49 阅读
  2. Android开发中如何实现语音输入输出

    2024-01-28 15:48:03       58 阅读
  3. ubuntu18.04更换软件源

    2024-01-28 15:48:03       38 阅读
  4. 用Python做一个简单的后端框架

    2024-01-28 15:48:03       47 阅读
  5. SRE-Redis基本概念篇

    2024-01-28 15:48:03       53 阅读
  6. CUBEMX与FreeRTOS在Arm Compiler 6下的配置方法

    2024-01-28 15:48:03       51 阅读
  7. 打开多个文件打印并去掉其中的空行

    2024-01-28 15:48:03       61 阅读