Python 进阶(一)网络编程初探

2023-12-20 10:22:35

python 进阶学习.png

  • 官网:

Welcome to Python.org

一 网络编程

Python 提供了两个级别访问的网络服务:

  • 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。
  • 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。
  1. Socket编程: Python提供了socket库,可用于创建网络套接字,进行基本的网络通信。您可以使用这个库创建TCP或UDP服务器和客户端。
  2. 网络框架: 有许多Python网络框架,例如Django和Flask,用于构建Web应用程序。这些框架提供了高级功能,如路由、模板引擎和数据库集成。
  3. 异步编程: Python的asyncio库使异步网络编程变得更容易。它允许您编写异步服务器和客户端,以提高性能和并发性。
  4. Web爬虫: 如果您对网络数据抓取和爬取感兴趣,可以使用库如Beautiful Soup和Requests来创建Python Web爬虫。
  5. 网络安全: Python也有一些库用于网络安全,例如cryptography库,可用于加密和解密数据,以及ssl库,用于处理安全套接字连接。

有些是我们后面需要学习的东西,首先我们来学习Socket模块

1.1 Socket

socket()函数是Python中用于创建套接字对象的函数。它属于socket模块,用于初始化套接字以进行网络通信。socket()函数通常用于两种类型的套接字:流套接字(用于TCP通信)和数据报套接字(用于UDP通信)。以下是socket()函数的一般语法:

socket.socket(family, type[, proto])
  • family:指定地址族(地址簇),通常使用socket.AF_INET表示IPv4,或者socket.AF_INET6表示IPv6。
  • type:指定套接字类型,可以是socket.SOCK_STREAM(用于TCP)或socket.SOCK_DGRAM(用于UDP)等。
  • proto:(可选)指定协议号。通常不需要指定,如果省略,则根据familytype自动选择协议。

以下是一些示例用法:

  1. 创建一个TCP套接字:
import socket

tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1. 创建一个UDP套接字:
import socket

udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

socket()函数返回一个套接字对象,该对象可以用于与其他计算机建立连接、发送和接收数据等网络通信操作。在创建套接字后,您可以使用其他方法来设置套接字的属性、绑定地址和端口、连接到远程主机等,具体操作取决于您的网络通信需求。

内部方法

以下是一些常见的内部方法:

  1. **bind(address)**:将套接字绑定到指定的地址和端口,使其可以监听该地址上的连接请求或接收来自该地址的数据。
  2. **listen(backlog)**:开始监听连接请求,其中backlog指定了在拒绝新连接之前可以排队的最大连接数。
  3. **accept()**:接受传入连接请求,返回一个新的套接字和客户端地址,用于与客户端通信。
  4. **connect(address)**:与指定地址的服务器建立连接,用于客户端套接字。
  5. **send(data)**:发送数据到已连接的套接字。对于TCP套接字,数据将以字节流形式发送。对于UDP套接字,数据将被封装在数据包中发送。
  6. **recv(bufsize)**:接收从套接字接收的数据,最多接收bufsize字节的数据。通常,这是一个阻塞操作,直到有数据可用。
  7. **sendto(data, address)**:将数据发送到指定的地址,用于UDP套接字。
  8. **recvfrom(bufsize)**:从UDP套接字接收数据,并返回数据和发送方的地址。
  9. **close()**:关闭套接字连接。一旦关闭,套接字将无法再用于通信。
  10. **getsockopt(level, optname[, buflen])**:获取套接字选项的值。
  11. **setsockopt(level, optname, value)**:设置套接字选项的值。

服务端

# ---encoding:utf-8---
# @Time    : 2023/9/9 09:43
# @Author  : Darwin_Bossen
# @Email   :3139066125@qq.com
# @Site    :  Socket 服务端
# @File    : Server.py

import socket

# 0. 获取主机名和端口号
host = socket.gethostname()
port = 9999

# 1. 创建套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定端口
server_socket.bind((host, port))
# 3. 设置监听
server_socket.listen(128)

if __name__ == '__main__':
    while True:
        # 4. 等待客户端连接
        client_socket, client_addr = server_socket.accept()
        # 5. 接收数据
        recv_data = client_socket.recv(1024)
        # 6. 打印接收到的数据
        print(recv_data.decode("utf-8"))
        # 7. 发送数据
        client_socket.send("我收到了数据".encode("utf-8"))
        # 8. 关闭套接字
        client_socket.close()

客户端

# ---encoding:utf-8---
# @Time    : 2023/9/9 09:44
# @Author  : Darwin_Bossen
# @Email   :3139066125@qq.com
# @Site    :  Socket 客户端
# @File    : Client.py
import socket

# 0. 获取主机名和端口号
host = socket.gethostname()
port = 9999

# 1. 创建套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 连接服务器
client_socket.connect((host, port))

if __name__ == '__main__':
    # 3. 发送数据
    client_socket.send("hello".encode("utf-8"))
    # 4. 接收数据
    recv_data = client_socket.recv(1024)
    # 5. 打印接收到的数据
    print(recv_data.decode("utf-8"))
    # 6. 关闭套接字
    client_socket.close()

image.png
image.png

1.2 TCP 与UDP

TCP(传输控制协议)和UDP(用户数据报协议)是两种不同的传输层协议,用于在计算机网络中传输数据。它们具有不同的特点和适用场景,下面是它们的主要区别和用途:

TCP(传输控制协议)

  1. 可靠性: TCP提供可靠的数据传输,确保数据按顺序到达,并且没有丢失或损坏。如果发生丢包或错误,TCP会重新传输丢失的数据。
  2. 连接导向: TCP是面向连接的协议,通信之前需要建立连接。它使用三次握手来确保双方都准备好进行通信,并在通信结束时使用四次挥手来关闭连接。
  3. 流式传输: TCP数据以字节流的形式进行传输,不保留消息边界。这意味着发送方和接收方需要自己管理消息的边界。
  4. 延迟较高: 由于TCP的可靠性和连接管理,它的传输延迟较高,适用于需要数据完整性和可靠性的应用,如Web浏览、电子邮件、文件传输等。
  5. 拥塞控制: TCP具有拥塞控制机制,可以动态调整传输速率以避免网络拥塞。

服务端:

import socket

# 创建TCP服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定地址和端口
server_address = ('127.0.0.1', 8080)
server_socket.bind(server_address)

# 开始监听连接
server_socket.listen(5)

print("等待客户端连接...")

while True:
    # 接受客户端连接
    client_socket, client_address = server_socket.accept()
    print(f"接受来自 {client_address} 的连接")

    # 与客户端通信
    data = client_socket.recv(1024)
    if not data:
        break
    print(f"接收到的数据: {data.decode()}")

    # 向客户端发送响应
    response = "Hello, client!"
    client_socket.send(response.encode())

    # 关闭客户端连接
    client_socket.close()

# 关闭服务器套接字
server_socket.close()

客户端:

import socket

# 创建TCP客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接到服务器
server_address = ('127.0.0.1', 8080)
client_socket.connect(server_address)

# 发送数据到服务器
message = "Hello, server!"
client_socket.send(message.encode())

# 接收服务器的响应
response = client_socket.recv(1024)
print(f"服务器响应: {response.decode()}")

# 关闭客户端套接字
client_socket.close()

UDP(用户数据报协议)

  1. 不可靠性: UDP是一种不可靠的协议,不提供数据可靠性保证。它发送数据后不关心数据是否到达,可能会发生丢包或乱序。
  2. 无连接: UDP是面向无连接的协议,通信不需要建立连接。每个UDP数据包都是独立的,不保留状态信息。
  3. 消息边界: UDP保留消息的边界,这意味着每个UDP数据包都对应于一个完整的消息。
  4. 低延迟: 由于UDP不具备TCP的连接管理和拥塞控制,它通常具有较低的传输延迟。这使得它适用于实时应用,如语音通话、视频流、在线游戏等。
  5. 简单: UDP相对于TCP来说更简单,没有复杂的连接建立和维护过程。

服务端:

import socket

# 创建UDP服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 绑定地址和端口
server_address = ('127.0.0.1', 8080)
server_socket.bind(server_address)

print("等待客户端消息...")

while True:
    # 接收来自客户端的消息和客户端地址
    data, client_address = server_socket.recvfrom(1024)
    print(f"接收来自 {client_address} 的消息: {data.decode()}")

    # 向客户端发送响应
    response = "Hello, client!"
    server_socket.sendto(response.encode(), client_address)

客户端:

import socket

# 创建UDP客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 服务器地址和端口
server_address = ('127.0.0.1', 8080)

# 发送数据到服务器
message = "Hello, server!"
client_socket.sendto(message.encode(), server_address)

# 接收服务器的响应
response, server_address = client_socket.recvfrom(1024)
print(f"服务器响应: {response.decode()}")

# 关闭客户端套接字
client_socket.close()

1.3 Http

HTTP(Hypertext Transfer Protocol)是一种用于在网络上传输超文本的协议。它是互联网上应用最广泛的协议之一,通常用于在客户端和服务器之间传输Web页面、图像、视频、音频和其他资源。

主要特点

  1. 无状态协议: HTTP是一种无状态协议,每个HTTP请求都是独立的,服务器不会保留关于客户端的状态信息。这意味着每个请求都必须包含足够的信息来理解客户端的请求。
  2. 基于文本: HTTP通信基于文本,请求和响应都是文本数据,通常使用ASCII编码。这使得HTTP请求和响应容易阅读和调试。
  3. 请求-响应模型: HTTP遵循请求-响应模型。客户端发送HTTP请求,服务器接收并处理请求,然后返回HTTP响应。
  4. 支持多种请求方法: HTTP定义了多种请求方法,最常见的包括GET(获取数据)、POST(提交数据)、PUT(更新数据)、DELETE(删除数据)等。
  5. URL(Uniform Resource Locator): HTTP使用URL来标识和定位资源。URL包括协议、主机名、端口号和路径等信息。

用途

  1. Web浏览: HTTP是Web浏览器和Web服务器之间的通信协议,用于请求和传输HTML页面、图像、CSS、JavaScript和其他Web资源。
  2. Web服务: HTTP用于构建Web服务,允许应用程序通过HTTP请求和响应进行通信。RESTful API通常基于HTTP协议。
  3. 文件传输: HTTP可以用于上传和下载文件,例如,通过HTTP POST请求上传文件到服务器,或通过HTTP GET请求下载文件。
  4. 电子邮件: HTTP也用于Webmail客户端与邮件服务器之间的通信,如使用HTTP请求来获取和发送电子邮件。
  5. 社交媒体: 社交媒体平台使用HTTP来传输用户生成的内容,如文本、图像、视频和音频。
  6. 应用程序集成: HTTP被广泛用于应用程序之间的通信,允许不同应用程序通过HTTP请求和响应来交换数据。

HTTP通常在TCP/IP协议栈的应用层上运行,并使用TCP作为传输层协议,但也可以通过TLS/SSL进行安全加密,形成HTTPS(HTTP Secure)以保护数据的传输安全。

# ---encoding:utf-8---
# @Time    : 2023/9/9 10:10
# @Author  : Darwin_Bossen
# @Email   :3139066125@qq.com
# @Site    :  
# @File    : Http.py

# 导入http.server模块
import http.server
import socketserver

# 定义要使用的端口号
port = 8080

# 创建一个简单的HTTP请求处理程序
handler = http.server.SimpleHTTPRequestHandler

# 启动HTTP服务器并监听指定端口
with socketserver.TCPServer(("", port), handler) as httpd:
    print(f"Serving on port {port}")

    # 开始监听并处理HTTP请求
    httpd.serve_forever()
# Compare this snippet from 进阶语法\socket\HTTPServer.py:

1.4 扩展

OSI七层协议

OSI(Open Systems Interconnection)模型是一种计算机网络协议的抽象架构,用于将网络通信的不同方面分层并描述其功能。它将网络通信划分为七个不同的层次,每个层次都有特定的功能和责任。以下是OSI模型的七个层次,从底层到顶层:

  1. 物理层(Physical Layer)
    • 主要负责传输数据的物理介质,如电缆、光纤和无线信号。
    • 定义了数据的传输速率、电压级别和物理接口标准。
    • 主要关注数据的物理传输。
  2. 数据链路层(Data Link Layer)
    • 负责在直接相连的两个节点之间进行数据传输。
    • 提供了物理地址(MAC地址)的寻址和数据的错误检测和校正。
    • 分为两个子层:逻辑链路控制子层和介质访问控制子层。
  3. 网络层(Network Layer)
    • 负责在网络中的不同节点之间进行数据传输。
    • 提供了逻辑地址(IP地址)的寻址和路由选择。
    • 主要关注数据的路由和跨网络传输。
  4. 传输层(Transport Layer)
    • 负责端到端的数据传输,确保数据可靠性和完整性。
    • 提供了端口号的寻址,以及数据的流量控制和差错检测。
    • 主要关注数据的端到端传输。
  5. 会话层(Session Layer)
    • 负责建立、管理和终止会话(会话是两个应用程序之间的通信会话)。
    • 提供了会话建立、同步和恢复功能。
    • 主要关注数据的会话管理。
  6. 表示层(Presentation Layer)
    • 负责数据的格式转换和加密解密。
    • 提供了数据的编码、压缩和加密。
    • 主要关注数据的表示和编码。
  7. 应用层(Application Layer)
    • 最高层,提供了应用程序之间的通信和交互。
    • 包括各种应用协议,如HTTP、FTP、SMTP等。
    • 主要关注用户应用和应用程序之间的通信。
网络通信的原理:
"网络存在的意义就是可以跨地域传输信息>>>>称之为通信"
网络 = 物理链接介质+互联网协议
"互联网的本质其实就是一堆协议"
3、os七层协议
# 互联网协议按照功能不同分为OSI七层或者TCP/IP五层或者TCP/IP四层
七层协议:
应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
五层协议:# 五层协议是将应用层、表示层、会话层统称为应用层
应用层、传输层、网络层、数据结构层、物理层
四层协议:# 就是在五层协议的基础上将数据链路层跟物理层统称为网络接口层
应用层、传输层、网络层、网络接口层
协议是什么:
    "协议就是规定数据的组织格式"
    格式:头部+数据部分
    封装过程:数据外部加头
    拆封过程:拆掉加上的头部获取数据
    
五层协议:
计算机1                     计算机2

应用层                       应用层
传输层          段           传输层
网络层          包           网络层
数据链路层       帧          数据链路层
物理层<--------交换机------>物理层

三次握手


TCP协议使用三次握手(Three-Way Handshake)来建立一个可靠的连接。三次握手的过程包括三个步骤,每个步骤都是一个TCP报文段(segment)的交换,以确保双方都能够正常通信。以下是三次握手的步骤:

  1. 第一步:客户端发送请求
    • 客户端首先创建一个TCP报文段,其中包含一个用于生成随机序列号的初始序列号(ISN)。
    • 客户端将报文段发送给服务器。
    • 客户端进入等待状态,等待服务器的确认。
  2. 第二步:服务器确认请求并发送响应
    • 服务器收到客户端的请求后,确认接收到了报文段。
    • 服务器生成自己的随机序列号,并在响应中包含客户端的初始序列号+1作为确认号(ACK)。
    • 服务器也创建一个报文段并将其发送回客户端。
    • 服务器进入等待状态,等待客户端的确认。
  3. 第三步:客户端确认响应
    • 客户端收到服务器的响应后,确认接收到了报文段。
    • 客户端将服务器的初始序列号+1作为确认号(ACK)发送给服务器。
    • 客户端也创建一个报文段并将其发送回服务器。
    • 此时,客户端和服务器都确认了彼此的请求和响应,并建立了连接。
    • 连接建立后,客户端和服务器可以开始在此连接上进行数据传输。

以下是三次握手的示意图:

客户端              服务器
  |                    |
  |   第一次握手:     |
  |   发送请求(SYN)  |
  |  -----------------> |
  |                    |
  |   第二次握手:     |
  |   确认请求(ACK)  |
  |  <----------------- |
  |                    |
  |   第三次握手:     |
  |   确认响应(ACK)  |
  |  -----------------> |
  |                    |
  |   连接建立         |

三次握手确保了双方都具备接收和发送数据的能力,并建立了一个可靠的连接。如果其中任何一方未能收到另一方的确认,或者出现其他问题,都会导致握手失败,连接不会建立。这有助于确保在数据传输开始之前,双方都已准备好进行通信。

四次挥手

TCP连接的四次挥手(Four-Way Handshake)是用于关闭一个已经建立的TCP连接的过程。它与三次握手不同,因为在关闭连接时,双方都可能还有未传输完的数据或未确认的数据,因此需要四个步骤来完成。以下是四次挥手的步骤:

  1. 第一步:客户端发送关闭请求
    • 客户端希望关闭连接,因此它发送一个TCP报文段,其中包含FIN标志(FIN = 1)。
    • 客户端进入FIN_WAIT_1状态,等待服务器的确认或拒绝。
  2. 第二步:服务器确认关闭请求
    • 服务器收到客户端的关闭请求后,发送一个确认报文段(ACK),其中包含客户端的序列号+1作为确认号。
    • 服务器进入CLOSE_WAIT状态,等待应用程序告知它可以关闭连接。
  3. 第三步:服务器发送关闭请求
    • 服务器的应用程序决定可以关闭连接后,服务器发送一个包含FIN标志的TCP报文段。
    • 服务器进入LAST_ACK状态,等待客户端的确认。
  4. 第四步:客户端确认关闭请求
    • 客户端收到服务器的关闭请求后,发送一个确认报文段(ACK),其中包含服务器的序列号+1作为确认号。
    • 客户端进入TIME_WAIT状态,等待一段时间以确保服务器收到了确认,然后关闭连接。
    • 服务器收到客户端的确认后,也关闭连接。
    • 客户端在TIME_WAIT状态等待的时间(称为2MSL,最大报文段寿命)过后,彻底关闭连接,释放资源。

以下是四次挥手的示意图:

客户端              服务器
  |                    |
  |   第一步:         |
  |   发送关闭请求(FIN)|
  |  -----------------> |
  |                    |
  |   第二步:         |
  |   确认关闭请求(ACK)|
  |  <----------------- |
  |                    |
  |   第三步:         |
  |   发送关闭请求(FIN)|
  |  -----------------> |
  |                    |
  |   第四步:         |
  |   确认关闭请求(ACK)|
  |  <----------------- |
  |                    |
  |   连接关闭         |

四次挥手确保了双方都能够完成数据传输,然后安全地关闭连接。在连接关闭之前,双方都有机会确认已经接收到的数据,并通知对方可以关闭连接。这有助于确保数据的完整性和可靠性。

文章来源:https://blog.csdn.net/Darwin_Bossen/article/details/132774192
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。