python笔记-传输模型与套接字

一、基本模型

avatar

​ 每一个应用程序客户端要实现数据传输,都需要套接字去发送或者响应网络请求,客户端通过套接字,沿着网络设备将数据发送给其他客户端,相应客户端解析并接收数据。

1.1、层次划分

osi模型 各层级说明
应用层 供操作系统或应用进行网络通信的标准接口
表示层 将不同的编码方式转换成网络通信中采用的标准表现形式
会话层 不同PC不同进程间建立或解除连接,插入同步点
传输层 两个主机间端对端的数据连接与传输
网络层 选择路由并正确的找着目标主机
数据链路层 两个相邻节点间准确的数据传输
物理层 原始比特数据在物理介质上的传输
tcp/ip模型 层次说明 网络协议
应用层 供操作系统或应用进行网络通信的标准接口
将不同的编码方式转换成网络通信中采用的标准表现形式
不同PC不同进程间建立或解除连接,插入同步点
Telnet,FTP,SMTP,DNS,HTTP
传输层 两个主机间端对端的数据连接与传输 TCP,UDP
网络层 选择路由并正确的找着目标主机 IP,ARP,RARP,ICMP
数据链路层 两个相邻节点间准确的数据传输
原始比特数据在物理介质上的传输
网络通信硬件及接口
  • OSI(Open System Interconnect)开放系统互连参考模型七层协议模型,是一个理想化的网络互连参考模型,但基本不使用.

现使用的是TCP/IP四层网络模型

  • TCPUDP的区别是前者是可靠的的网络互联协议,而后者不可靠
  • ARP指的是根据IP地址获取MAC(网络设备的物理地址,硬件地址,每台电脑中均装有网卡,其地址为MAC地址)
  • RARP为根据MAC地址获取IP地址

传输层次说明

  • Python是在应用层的HTTP协议之上进行开发
  • 网络编程,主要是了解Python能编写的最低的层次即传输层的基本情况
  • HTTP协议是基于TCP之上的,因此需要了解TCP连接的基本过程

1.2 TCP链接

建立连接(三次握手)、数据传输、断开连接(四次挥手)

1.2.1 建立连接

avatar

连接过程

  • 首先由客户端发起同步请求(SYN),即想建立连接,服务端处于监听状态,可接收客户端的请求。
  • 服务端收到同步请求,发送应答信号(ACK)给客户端。
  • 客户端接收应答信号,已建立连接并发送已建立连接的应答信号给服务端,连接建立完毕。

1.2.2 数据传输

avatar

​ 客户端发送数据传输请求,操作系统接受请求并接收数据,发送数据给相应客户端,客户端接收数据并发送响应信号,客户端接收。

1.2.3 断开连接

avatar

断开过程

  • 客户端主动请求断开连接,发送结束信号(FIN),客户端等待关闭
  • 服务端接收FIN信号,响应请求,发送ACK信号,第一阶段完成(客户端已无数据发送给服务端,但服务端可能还有数据发送给客户端, 故还有后续过程)
  • 服务端被动关闭,发送FIN信号,等待客户端确认
  • 客户端发送ACK,等待服务端关闭,服务端接收信号,关闭连接,客户端关闭连接

二、IP地址和端口

2.1 IP地址

IP协议提供的一种统一的地址格式,它为互联网上的每一个网络每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。即为每一台计算机编号,以便于在网络中定位到一台计算机的位置。

一些特殊的IP地址

127.0.0.1:本地回环地址。该地址指电脑本身,主要预留测试本机的TCP/IP协议是否正常。只要使用这个地址发送数据,则数据包不会出现在网络传输过程中。

0.0.0.0:代表的是本机所有ip地址,不管你有多少个端口,多少个ip。如果监听本机的0.0.0.0上的端口,就等于监听机器上的所有ip端口。换句话说,就是只要数据报目的地址是你机器上的一个ip地址,那么就能被接受。

2.2 端口

  • 端口用来唯一标识应用程序
  • 每个应用程序都占了一个端口,一个端口同时只能被一个程序使用
  • 共有65535个端口
  • 数据传输,发送与接收必须通过端口,指明了数据应发送的进程编号。每个进程都有一个端口号,以此来作为数据传输的门户。

三、套接字

3.1 TCP

3.1.1 服务端

socket常用的方法 描述
socket.socket(socket.AF_INET, socket.SOCK_STREAM) 创建tcp服务端socket对象
socket对象.bind((ip,port)) 绑定ip和端口
socket对象.listen() 监听客户端发起的连接请求
socket对象.accept() 接受客户端连接请求,返回用于与客户端通信的对等socket对象,和客户端的ip和端口
对等socket对象.recv(int) 接受客户端发来的消息
对等socket对象.send(data) 向客户端发送消息
socket对象.close() 关闭连接
对等socket对象.getpeername() 获取客户端的ip地址和端口

示例代码

import socket

# 创建ipv4的TCP socket
server_tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定ip和端口
server_tcp_socket.bind(('127.0.0.1', 8080))
# 监听客户端链接
server_tcp_socket.listen()
# 接受链接,返回一个用于和客户端通信的对等套接字和客户端ip地址和端口
clientSocket, address = server_tcp_socket.accept()
print(f"{address}已连接")

# 通信
## 接受客户端发来的消息
recv_date = clientSocket.recv(1024)
print(recv_date.decode())

# 将收到的信息返回个客户端
clientSocket.send(recv_date)

# 关闭
clientSocket.close()  # 先关闭对等套接字
server_tcp_socket.close()  # 关闭套接字

3.1.2 客户端

socket常用的方法 描述
socket.socket(socket.AF_INET, socket.SOCK_STREAM) 创建tcp客户端socket对象
socket对象.client((ip,port)) 连接服务端
socket对象.send(data) 向服务端发送数据
socket对象.recv(int) 接受服务端返回的数据
socket对象.close() 关闭连接

示例代码

import socket

# 创建客户端tcp_socket
kehu_tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接服务端
kehu_tcp_socket.connect(('127.0.0.1', 8080))
# 发送消息
kehu_tcp_socket.send('hello world'.encode())
# 接受服务端返回消息
recv_data = kehu_tcp_socket.recv(1024)
print(recv_data.decode())

3.2 UDP

3.2.1 服务端

socket常用的方法 描述
socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 创建udp服务端的socket对象
socket对象.bind((ip, port)) 绑定ip和端口
socket对象.recvfrom(int) 接受客户端发来的消息,返回客户端发来的消息和客户端地址
socket对象.sendto(data, address) 向客户端发送消息
socket对象.close() 关闭连接
import socket

# 创建udp服务端的socket对象
server_udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定ip和端口
server_udp_socket.bind(('127.0.0.1', 8081))

print('等待用户来连解')
# 接受客户端传来的消息,返回消息和客户端的地址
data, address = server_udp_socket.recvfrom(1024)
print(data.decode(), address)
# 将客户发来的信息返回给客户端
server_udp_socket.sendto(data, address)

3.2.2 客户端

socket常用方法 描述
socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 创建udp客户端socket对象
socket对象.sendto(data, address) 向服务端发送消息
socket对象.recv(int) 接收服务端返回的消息
socket对象.close() 关闭连接
import socket

# 创建udp客户端的socket对象
client_udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 向服务端发送消息
client_udp_socket.sendto('hello world'.encode(), ('127.0.0.1', 8081))
# 接受服务端返回的消息
recv_data = client_udp_socket.recv(1024)
print(recv_data.decode())
# 关闭客户端
client_udp_socket.close()

附录

1 图片的base64编码

1.1 传输模型

1.2 三次握手

1.3 数据传输

1.4 四次挥手

猜你喜欢

转载自www.cnblogs.com/duyupeng/p/13200181.html
今日推荐