Python 网络编程 -- WebSocket编程

作者主要是为了用python构建实时网络通信程序。

概念性的东西越简单越好理解,因此,下面我从晚上摘抄的概念 + 我的理解。

什么是网络通信?

更确切地说,网络通信是两台计算机上的两个进程之间的通信。比如,浏览器进程和新浪服务器上的某个Web服务进程在通信,而QQ进程是和腾讯的某个服务器上的某个进程在通信。

而网络编程就是针对网络通信的编程。

1.网络编程基础

1.1 基本概念与协议

TCP/IP协议栈

网络编程的基础是 理解数据在网络中的传输过程,这通常通过OSI模型和TCP/IP协议栈进行解释。而TCP/IP协议栈则是实际应用中更为广泛的模型,包含物理层、数据链路层、网络层、传输层、会话层、表示层和应用层

计算机为了联网,需要规定通信协议,一开始是不统一的,相互不同协议之间的计算机交互是困难的。因此,就出现了互联网协议簇,任何网络只要遵守这个协议,就可以连入互联网。

互联网协议,包括上百种协议,最重要的当属TCP/IP协议,因此,大家把互联网协议简称TCP/IP协议。

通信的时候,双方必须知道对方的标识,好比发邮件必须知道对方的邮件地址。互联网上每个计算机的唯一标识就是IP地址,类似123.123.123.123。如果一台计算机同时接入到两个或更多的网络,比如路由器,它就会有两个或多个IP地址,所以,IP地址对应的实际上是计算机的网络接口,通常是网卡。

IP协议负责把数据从一台计算机通过网络发送到另一台计算机。数据被分割成一小块一小块,然后通过IP包发送出去。由于互联网链路复杂,两台计算机之间经常有多条线路,因此,路由器就负责决定如何把一个IP包转发出去。IP包的特点是按块发送,途径多个路由,但不保证能到达,也不保证顺序到达。

TCP协议则是建立在IP协议之上的。TCP协议负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。TCP协议会通过握手建立连接,然后,对每个IP包编号,确保对方按顺序收到,如果包丢掉了,就自动重发。

许多常用的更高级的协议都是建立在TCP协议基础上的,比如用于浏览器的HTTP协议、发送邮件的SMTP协议等。

一个TCP报文除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。

端口有什么作用?在两台计算机通信时,只发IP地址是不够的,因为同一台计算机上跑着多个网络程序。一个TCP报文来了之后,到底是交给浏览器还是QQ,就需要端口号来区分。每个网络程序都向操作系统申请唯一的端口号,这样,两个进程在两台计算机之间建立网络连接就需要各自的IP地址和各自的端口号。

一个进程也可能同时与多个计算机建立链接,因此它会申请很多端口。

TCP

TCP (Transmission Control Protocol) 是面向连接的、提供端到端可靠的数据流(flow of data)。TCP 提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

“面向连接”就是在正式通信前必须要与对方建立起连接。这一过程与打电话很相似,先拨号振铃,等待对方摘机说“喂”,然后才说明是谁。

端到端的数据流,建立在IP协议之上,提供超时重发、重复数据校验、流量控制灯基本功能。

保证数据能从一端到另一端。

三次握手

TCP 是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个 TCP 连接必须要经过三次“握手”才能建立起来,简单的讲就是:

  1. 主机 A 向主机 B 发出连接请求数据包:“我想给你发数据,可以吗?”;
  2. 主机 B 向主机 A 发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你来吧”;
  3. 主机 A 再发出一个数据包确认主机 B 的要求同步:“好的,我来也,你接着吧!”

三次“握手”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机 A 才向主机 B 正式发送数据。

A和B要通过 TCP通信的流程:

A 连接B,B被连接允许A连接,A接受到响应确认连接B。 -> A和B可以通信了。

UDP

UDP (User Datagram Protocol) 面向无连接的,主机发送独立的数据报(datagram)给其他主机,不保证数据到达。由于 UDP 在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

而无连接是一开始就发送信息(严格说来,这是没有开始、结束的),只是一次性的传递,是先不需要接受方的响应,因而在一定程度上也无法保证信息传递的可靠性了,就像写信一样,我们只是将信寄出去,却不能保证收信人一定可以收到。

通信时,可以不用与目标主机建立连接,就能发送数据。

A和B通信,直接发送就可以,不用管对方是否  "可连接"。

TCP 是面向连接的,有比较高的可靠性, 一些要求比较高的服务一般使用这个协议,如FTP、Telnet、SMTP、HTTP、POP3 等,而 UDP 是面向无连接的,使用这个协议的常见服务有 DNS、SNMP、QQ 等。对于 QQ 必须另外说明一下,QQ2003 以前是只使用UDP协议的,其服务器使用8000端口,侦听是否有信息传来,客户端使用 4000 端口,向外发送信息(这也就不难理解在一般的显IP的QQ版本中显示好友的IP地址信息中端口常为4000或其后续端口的原因了),即QQ程序既接受服务又提供服务,在以后的 QQ 版本中也支持使用 TCP 协议了。

端口

一般来说,一台计算机具有单个物理连接到网络。数据通过这个连接去往特定的计算机。然而,该数据可以被用于在计算机上运行的不同应用。那么,计算机知道哪个应用程序转发数据?通过使用端口。

在互联网上传输的数据是通过计算机的标识和端口来定位的。计算机的标识是 32-bit 的 IP 地址。端口由一个 16-bit 的数字。

在诸如面向连接的通信如 TCP,服务器应用将套接字绑定到一个特定端口号。这是向系统注册服务用来接受该端口的数据。然后,客户端可以在与服务器在服务器端口会合,如下图所示:

网络基础 - 图2

TCP 和 UDP 协议使用的端口来将接收到的数据映射到一个计算机上运行的进程。

在基于数据报的通信,如 UDP,数据报包中包含它的目的地的端口号,然后 UDP 将数据包路由到相应的应用程序,如本图所示的端口号:

网络基础 - 图3

端口号取值范围是从 0 到 65535 (16-bit 长度),其中范围从 0 到 1023 是受限的,它们是被知名的服务所保留使用,例如 HTTP (端口是 80)和 FTP (端口是20、21)等系统服务。这些端口被称为众所周知的端口(well-known ports)。您的应用程序不应该试图绑定到他们。

嗯 ...,网络通信具体来讲,是两个进程之间的通信,很显然我们只要目标主机的IP是没法跟对方通信的,因此我们还必须知道目标进程运行占用的端口,通过 ip + port来与其通信。

2. Socket

Socket(套接字):是在网络上运行两个程序之间的双向通信链路的一个端点socket绑定到一个端口号,使得 TCP 层可以标识数据最终要被发送到哪个应用程序

正常情况下,一台服务器在特定计算机上运行,​​并具有被绑定到特定端口号的 socket。服务器只是等待,并监听用于客户发起的连接请求的 socket 。

在客户端:客户端知道服务器所运行的主机名称以及服务器正在侦听的端口号。建立连接请求时,客户端尝试与主机服务器和端口会合。客户端也需要在连接中将自己绑定到本地端口以便于给服务器做识别。本地端口号通常是由系统分配的。

Socket - 图1

如果一切顺利的话,服务器接受连接。一旦接受,服务器获取绑定到相同的本地端口的新 socket ,并且还具有其远程端点设定为客户端的地址和端口。它需要一个新的socket,以便它可以继续监听原来用于客户端连接请求的 socket 。

Socket - 图2

在客户端,如果连接被接受,则成功地创建一个套接字和客户端可以使用该 socket 与服务器进行通信。

客户机和服务器现在可以通过 socket 写入或读取来交互了。

端点是IP地址和端口号的组合。每个 TCP 连接可以通过它的两个端点被唯一标识。这样,你的主机和服务器之间可以有多个连接。

Socket是对互联网通信协议(如TCP/IP)的封装和应用,它提供了一个调用接口(API),通过这个接口我们可以使用这些协议栈来与目标计算机进行通信。

在具体的编程语言中,针对不同的通信协议会有不同的Socket实现。当你需要与目标计算机进行基于某个协议的通信时,你可以调用相应协议的Socket实现。这些Socket实现会根据协议的要求进行数据的封装和解封装,以便你能够与目标计算机进行通信。

因此,通过创建针对特定协议的Socket实现,你就可以使用Socket进行基于该协议的通信了。

具体举一下例子:

如果抖音有一个通信协议,并且针对Java提供了一个具体的SDK,那么这个SDK中应该包含了一个Socket的实现,用于与抖音服务器进行通信。

当你创建这个Socket时,你可以使用SDK提供的API来与抖音服务器建立连接、发送和接收数据。SDK会根据抖音的通信协议对数据进行封装和解封装,以便你能够与抖音服务器进行通信。

因此,通过创建这个Socket,你就可以使用SDK提供的API与抖音服务器进行通信了。

服务器指一个管理资源并为用户提供服务的计算机软件,通常分为文件服务器、数据库服务器和应用程序服务器。严格来说,服务器本身就是计算机硬件,并在其中运行的管理软件的一种管理资源,就如同电脑。按硬件还会分塔式服务器、卡片机、小型机。是一个大的概念,任何一台电脑安装了软件的服务器端就可以叫服务器。

2.Python网络编程

Socket

python提供了内置socket库,从而能够进行网路通信。下面我们直接展示一个案例。

下面简单利用了sockert库,来建立一个服务器,并且建立了一个客户端,去访问服务器并进行数据交互。

来源于菜鸟编程: Python 网络编程 | 菜鸟教程 (runoob.com)

Server.py

import socket
if __name__ == '__main__':# 建立一个服务端server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind(('localhost', 6999))  # 绑定要监听的端口server.listen(5)  # 开始监听 表示可以使用五个链接排队while True:  # conn就是客户端链接过来而在服务端为期生成的一个链接实例conn, addr = server.accept()  # 等待链接,多个链接的时候就会出现问题,其实返回了两个值print(conn, addr)while True:try:data = conn.recv(1024)  # 接收数据print('recive:', data.decode())  # 打印接收到的数据conn.send(data.upper())  # 然后再发送数据except ConnectionResetError as e:print('关闭了正在占线的链接!')breakconn.close()

client.py

import socket
if __name__ == '__main__':client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 声明socket类型,同时生成链接对象client.connect(('localhost', 6999))  # 建立一个链接,连接到本地的6969端口while True:# addr = client.accept()# print '连接地址:', addrmsg = '欢迎访问菜鸟教程!'  # strip默认取出字符串的头尾空格client.send(msg.encode('utf-8'))  # 发送一条信息 python3 只接收btye流data = client.recv(1024)  # 接收一个信息,并指定接收的大小 为1024字节print('recv:', data.decode())  # 输出我接收的信息client.close()  # 关闭这个链接

WebSocket

 PS:以下全引用于HTML 菜鸟编程: HTML5 WebSocket | 菜鸟教程 (runoob.com)

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

以下 API 用于创建 WebSocket 对象。

我们可以看出,websocket协议是基于tcp协议的全双工通信协议。

它,允许服务端主动向客户端推送数据。而且,只需要一次握手,就可建立一次长连接

与传统 AJAX轮训方法实现推送技术相比,发送请求的次数减少,(数据每一次更新,就代表一次ajax的请求和响应,这是相对比较浪费带宽资源的,通过websocket,客户端和服务端可以建立一次长连接完成数据的交互。)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/908321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GM DC Monitor如何实现TCP端口状态监控-操作分享

本节讲解如何通过现有指标提取监控脚本制作自定义的TCP端口监控指标 一、功能介绍 通过提取已有的监控指标的监控命令,来自定义TCP端口的监控指标。 二、配置端口监控 1)定位监控脚本 确定脚本及参数如下: check_protocol_tcp.pl --plug…

LabVIEW与Modbus/TCP温湿度监控系统

基于LabVIEW 开发平台与 Modbus/TCP 通信协议,设计一套适用于实验室环境的温湿度数据采集监控系统。通过上位机与高精度温湿度采集设备的远程通信,实现多设备温湿度数据的实时采集、存储、分析及报警功能,解决传统人工采集效率低、环境适应性…

Ntfs!ReadIndexBuffer函数分析之nt!CcGetVirtualAddress函数之nt!CcGetVacbMiss

第一部分: NtfsMapStream( IrpContext, Scb, LlBytesFromIndexBlocks( IndexBlock, Scb->ScbType.Index.IndexBlockByteShift ), Scb->ScbType.Index.BytesPerIndexBuffer, &am…

vite+vue3项目中,单个组件中使用 @use报错

报错信息: [plugin:vite:css] [sass] use rules must be written before any other rules.use 官方说明 注意事项: https://sass-lang.com/documentation/at-rules/use/ 样式表中的 use 规则必须位于所有其他规则(除 forward 外&#xff0…

基于VMD-LSTM融合方法的F10.7指数预报

F10.7 Daily Forecast Using LSTM Combined With VMD Method ​​F10.7​​ solar radiation flux is a well-known parameter that is closely linked to ​​solar activity​​, serving as a key index for measuring the level of solar activity. In this study, the ​​…

React 新项目

使用git bash 创建一个新项目 建议一开始就创建TS项目 原因在Webpack中改配置麻烦 编译方法:ts compiler 另一种 bable 最好都配置 $ create-react-app cloundmusic --template typescript 早期react项目 yarn 居多 目前npm包管理居多 目前pnpm不通用 icon 在public文件夹中…

2025年- H65-Lc173--347.前k个高频元素(小根堆,堆顶元素是当前堆元素里面最小的)--Java版

1.题目描述 2.思路 (1)这里定义了一个小根堆(最小堆),根据元素的频率从小到大排序。小根堆原理:堆顶是最小值,每次插入或删除操作会保持堆的有序结构(常用二叉堆实现)。 …

VR/AR 显示瓶颈将破!铁电液晶技术迎来关键突破

在 VR/AR 设备逐渐走进大众生活的今天,显示效果却始终是制约其发展的一大痛点。纱窗效应、画面拖影、眩晕感…… 传统液晶技术的瓶颈让用户体验大打折扣。不过,随着铁电液晶技术的重大突破,这一局面有望得到彻底改变。 一、传统液晶技术瓶颈…

【bug】Error: /undefinedfilename in (/tmp/ocrmypdf.io.9xfn1e3b/origin.pdf)

在使用ocrmypdf的时候,需要Ghostscript9.55及以上的版本,但是ubuntu自带为9.50 然后使用ocrmypdf报错了 sudo apt update sudo apt install ghostscript gs --version 9.50 #版本不够安装的版本为9.50不够,因此去官网https://ghostscript.c…

【TinyWebServer】线程同步封装

目录 POSIX信号量 int sem_init(sem_t* sem,int pshared,unsingned int value); int sem_destroy(sem_t* sem); int sem_wait(sem_t* sem); int sem_post(sem_t* sem); 互斥量 条件变量 为了对多线程程序实现同步问题,可以用信号量POSIX信号量、互斥量、条件变…

打造高效多模态RAG系统:原理与评测方法详解

引言 随着信息检索与生成式AI的深度融合,检索增强生成(RAG, Retrieval-Augmented Generation) 已成为AI领域的重要技术方向。传统RAG系统主要依赖文本数据,但真实世界中的信息往往包含图像、表格等多模态内容。多模态RAG&#xf…

Unity安卓平台开发,启动app并传参

using UnityEngine; using System;public class IntentReceiver : MonoBehaviour {public bool isVR1;void Start(){Debug.LogError("app1111111111111111111111111");if (isVR1){LaunchAnotherApp("com.HappyMaster.DaKongJianVR2");}else{// 检查是否有传…

云计算 Linux Rocky day05【rpm、yum、history、date、du、zip、ln】

云计算 Linux Rocky day05【rpm、yum、history、date、du、zip、ln】 目录 云计算 Linux Rocky day05【rpm、yum、history、date、du、zip、ln】1.RPM包的一般安装位置2.软件名和软件包名3.查询软件信息4.查询软件包5.导入红帽签名信息,解决查询软件包信息报错6.利用…

【图像处理3D】:点云图是怎么生成的

点云图是怎么生成的 **一、点云数据的采集方式****1. 激光雷达(LiDAR)****2. 结构光(Structured Light)****3. 双目视觉(Stereo Vision)****4. 飞行时间相机(ToF Camera)****5. 其他…

javaweb -html -CSS

HTML是一种超文本标记语言 超文本&#xff1a;超过了文本的限制&#xff0c;比普通文本更强大&#xff0c;除了文字信息&#xff0c;还可以定义图片、音频、视频等内容。 标记语言&#xff1a;由标签"<标签名>"构成的语言。 CSS:层叠样式表&#xff0c;用于…

pyinstaller 安装 ubuntu

安装命令 pip install pyinstaller 读取安装路径 ➜ ~ find ~/.local/ -name pyinstaller/home/XXX/.local/bin/pyinstaller 路径配置 vi ~/.zshrc 添加到文件最后 export PATH"$PATH:/home/XXX/.local/bin/" 查看版本号 ➜ ~ source ~/.zshrc➜ ~ pyi…

【前端】掌握HTML/CSS宽高调整:抓住问题根源,掌握黄金法则

一、宽高控制的「黄金法则」 问题根源&#xff1a;为什么设置了宽高没效果&#xff1f; <!-- 典型失败案例 --> <style>.problem-box {width: 200px;height: 100px;padding: 20px; /* 实际变成240x140px&#xff01; */border: 5px solid red; /* 最终250x150px&…

LuaJIT2.1 和 Lua5.4.8 性能对比

说明 最近在学习 LuaJIT&#xff0c;想看看把它接入到项目中使用&#xff0c;会提高多大的性能。 今天抽时间&#xff0c;简单地测试了一下 LuaJIT 2.2 和 Lua5.4.8 的性能。 测试平台&#xff1a; 系统&#xff1a;Windows 10 WSLCPU&#xff1a;Intel Core™ i7-8700 CPU…

Arduino学习-按键灯

哎&#xff0c;别笑&#xff0c;总比刷抖音强点吧 1、效果 2、代码 const int buttonPin2; const int ledPin13;int buttonState0;void setup() {// put your setup code here, to run once:pinMode(buttonPin,INPUT);pinMode(ledPin,OUTPUT); }void loop() {// put your mai…

强化学习鱼书(10)——更多深度强化学习的算法

&#xff1a;是否使用环境模型&#xff08;状态迁移函数P(s’|s,a)和奖 励函数r(s&#xff0c;a&#xff0c;V)&#xff09;。不使用环境模型的方法叫作无模型&#xff08;model-free&#xff09;的方法&#xff0c;使用环境模型的方法叫作有模型&#xff08;model-based&#…