Chapter 40 Socket网络编程

news2024/9/20 20:19:06

欢迎大家订阅【Python从入门到精通】专栏,一起探索Python的无限可能!

文章目录

  • 前言
  • 一、Socket网络编程
  • 二、Socket服务端编程
  • 三、Socket客户端编程
  • 四、服务端与客户端相互通讯


前言

在现代计算机网络中,Socket(套接字)是实现进程之间通信的重要工具。在网络应用中,Socket 充当了进程间数据传输的搬运工,负责进程之间的网络数据传输。无论是服务器还是客户端,二者通过 Socket 进行通信,形成了网络应用的基础。本章详细讲解了Socket服务端开发以及Socket客户端开发。


本篇文章参考:黑马程序员

一、Socket网络编程

Socket 是网络编程中用于建立和管理网络连接的一种抽象,主要用于服务端和客户端之间的通信。
①Socket服务端

  • 监听请求: 服务端负责等待并监听来自客户端的连接请求。
  • 接受连接: 每当有客户端连接时,服务端使用 accept() 方法接受该连接,并为该特定连接创建一个新的 Socket 对象。这个连接对象用于与连接的特定客户端进行通信。
  • 处理多个客户端: 服务端可以同时处理多个客户端的请求,每个连接都由一个独立的 conn 对象管理。

②Socket客户端

  • 发起连接: 客户端的作用是发起与服务端的连接请求。它通常只有一个主要的 Socket 对象,用于与服务端进行通信。
  • 一次一连接: 一般来说,客户端一次只会与一个服务端建立连接。

在这里插入图片描述

二、Socket服务端编程

①导包并创建socket对象
import socket
socket_server=socket.socket()

②绑定socket_server到指定IP和地址
socket_server.bind((host, port))

  • bind()方法:是 socket 对象的方法,用于将一个地址(主机名和端口号)绑定到一个 Socket 上,通常用于服务器端。
  • 参数(host, port): 一个元组,其中 host 通常是 IP 地址,port 是整数形式的端口号。

【示例】

# 绑定socket_server到指定IP和地址
socket_server.bind(("localhost",8888))
  • localhost:一个特殊的主机名,表示本地计算机。它允许服务端在本机上进行测试而不需要连接外部网络。
  • 8888:要绑定的端口号。端口号用于标识特定的服务或进程。在这个例子中,服务端将在本地的 8888 端口上监听来自客户端的连接请求。

③服务端开始监听端口
socket_server.listen(backlog)

  • listen方法:用于将 Socket 设置为被动模式,以便接收来自客户端的连接请求。
  • 参数backlog:为 int 整数,表示允许的连接请求数量。如果同时有多个客户端请求连接,超出该数量的请求将被拒绝。该参数是可选的,如果不指定,系统会自动设置一个合理的默认值。
    【示例】
#  服务端开始监听端口
socket_server.listen(1)   # listen()方法内接收一个整数传参数,表示接受的链接数量

④接收客户端连接,获得连接对象
socket_server.accept()
accept方法:一个阻塞方法,用于在服务器端接受客户端的连接请求。调用该方法后,如果没有客户端尝试连接,accept() 方法会阻塞并等待直到有一个客户端尝试连接。
该方法返回一个二元元组 (conn, address),其中:

  • conn:一个新的 Socket 对象,用于与连接的客户端进行通信。
  • address:客户端的地址(IP 地址和端口),提供了连接的客户端的信息。

【示例】

# 等待客户端链接
conn,address=socket_server.accept()
"""
上面这行代码等价于
result:tuple=socket_server.accept()
conn=result[0]
address=result[1]
"""

【分析】
accept方法返回的是二元元组 (conn, address),可以通过变量1,变量2=socket_server.accept()的形式直接接收二元元组内的两个元素。

⑤接收客户端发送的消息
conn.recv(bytes)

  • recv方法:一个阻塞方法,用于接收连接中发来的数据。如果接收到的数据小于指定的字节数,方法将返回已接收的数据;如果没有数据可接收,程序会等待,直到有数据到达为止。
  • 参数bytes: 一个 int 整数,指定要接收的最大字节数。

【注意】
recv方法通过conn调用而不是socket_server调用。因为conn是专用于与特定客户端进行通信的 Socket 对象,而conn是用于监听和接受连接的服务器 Socket。
【示例】

data=conn.recv(1024).decode("UTF-8")
  • recv()方法接收的参数为缓冲区大小,一般给1024即可。
  • recv()方法的返回值为一个字节数组,即bytes对象,不是字符串,可以通过decode()方法进行UTF-8编码,将字节数组转换为字符串对象。

⑥回复客户端信息
conn.send(data)

  • send方法:用于将数据发送给连接的客户端
  • 参数data: 一个字节序列(bytes 对象),表示要发送的数据。
    【示例】
# 通过conn(客户端当次连接对象),调用send方法可以回复消息
conn.send(msg.encode("UTF-8"))

在这个示例中,conn.send() 方法接收的参数是通过 encode(“UTF-8”) 将字符串转换为字节后的结果。这样,客户端才能正确接收和处理该信息。

⑦关闭连接
conn(客户端当次连接对象)和socket_server对象调用close方法,关闭连接。
conn.close()
socket_server.close()

⑧测试
下载网络调试助手作为客户端进行测试。
下载地址:https://github.com/nicedayzhu/netAssist/releases
在这里插入图片描述
服务端代码示例:

# 导包
import socket
# 创建socket对象
socket_server=socket.socket()
# 绑定socket_server到指定IP和地址
socket_server.bind(("localhost",8888))
#  服务端开始监听端口
socket_server.listen(1)   # listen()方法内接收一个整数传参数,表示接受的链接数量

# 等待客户端链接
conn,address=socket_server.accept()
print(f"接收到了客户端的链接,客户端信息为{address}")

while True:
    # 接收客户端连接,获得连接对象
    data=conn.recv(1024).decode("UTF-8")
    print(f"客户端发来的消息:{data}")
    
    # 通过conn(客户端当次连接对象),调用send方法可以回复消息
    msg=input("请输入回复客户端的信息:")
    if msg=='exit':
        break
    conn.send()

# 关闭连接
conn.close()
socket_server.close()

运行服务端代码
在这里插入图片描述
双击打开安装好的网络调试助手netAssist
在这里插入图片描述
配置netAssist相关环境,点击“开始连接”
在这里插入图片描述
连接成功
在这里插入图片描述
客户端发送消息
在这里插入图片描述
服务端成功接收消息
在这里插入图片描述
输入 “exit”,代码中的 break 语句会被执行,从而终止当前的循环,服务端会停止向客户端发送消息,并最终结束程序。

三、Socket客户端编程

①导包并创建socket对象
import socket
socket_client=socket.socket()

②连接到服务端
socket_client.connect((host, port))
connect()方法:一个阻塞方法,用于客户端连接到服务器。如果服务器没有响应,connect() 会阻塞,直到连接成功或发生超时。
【示例】

# 绑定socket_server到指定IP和地址
socket_client.connect(("localhost",8888))

③发送消息
socket_client.send(data)

# 发送消息
socket_client.send("你好呀".encode("UTF-8"))

④接收服务端消息
socket_client.recv(bytes)

# 接收返回信息
recv_data=socket_client.recv(1024)   # 1024为缓冲区大小,一般给1024即可

⑤关闭链接
socket_client.close()

四、服务端与客户端相互通讯

服务端示例代码:

# 导包
import socket
# 创建socket对象
socket_server=socket.socket()
# 绑定socket_server到指定IP和地址
socket_server.bind(("localhost",8888))
#  服务端开始监听端口
socket_server.listen(1)   # listen()方法内接收一个整数传参数,表示接受的链接数量

# 等待客户端链接
conn,address=socket_server.accept()
print(f"接收到了客户端的链接,客户端信息为{address}")

while True:
    # 接收客户端连接,获得连接对象
    data=conn.recv(1024).decode("UTF-8")
    print(f"客户端发来的消息:{data}")
    
    # 通过conn(客户端当次连接对象),调用send方法可以回复消息
    msg=input("请输入回复客户端的信息:")
    if msg=='exit':
        break
    conn.send()

# 关闭连接
conn.close()
socket_server.close()

客户端示例代码:

# 导包
import socket
# 创建socket对象
socket_client=socket.socket()
# 绑定socket_server到指定IP和地址
socket_client.connect(("localhost",8888))
# 发送消息
socket_client.send("你好呀".encode("UTF-8"))
while True:
    # 发送消息
    msg = input("请输入要给服务端发送的消息:")
    if msg == 'exit':
        break
    socket_client.send(msg.encode("UTF-8"))
    # 接收返回消息
    recv_data = socket_client.recv(1024)        # 1024是缓冲区的大小,一般1024即可。 同样recv方法是阻塞的
    print(f"服务端回复的消息是:{recv_data.decode('UTF-8')}")
# 关闭链接
socket_client.close()

先启动服务端再启动客户端。
服务端接收到客户端发来的信息并回复客户端。
在这里插入图片描述
客户端接收到服务端发来的信息并回复服务端。
在这里插入图片描述
输入 “exit”,代码中的 break 语句会被执行,从而终止当前的循环,服务端会停止向客户端发送消息,并最终结束程序。

在这里插入图片描述

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

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

相关文章

【题解】—— LeetCode一周小结33

🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 【题解】—— 每日一道题目栏 上接:【题解】—— LeetCode一周小结32 12.实现一个魔法字典 题目链接:676. 实现一个魔…

Kettle根据时间戳同步数据实现

1 Kettle总体步骤 更多数据实时同步方案,请参考笔者的另一篇博文:大数据时代,数据实时同步解决方案的思考—最全的数据同步总结 由于Kettle自身的特殊性以及在多个步骤中kettle自身处理数据库事务的特殊性,尝试了很多种方案&…

win11内存占用高的解决办法

win11莫名奇妙的总是内存爆满,真的抽象,16g根本不够用。尝试各种方法看看能不能解决… 方法一 关闭快速启动 win11系统,自带快速开机功能,可能用较大内存,关闭看看。控制面板找到电源设置关闭快速启动。 如果没找到要…

C++ | Leetcode C++题解之第345题反转字符串中的元音字母

题目&#xff1a; 题解&#xff1a; class Solution { public:string reverseVowels(string s) {auto isVowel [vowels "aeiouAEIOU"s](char ch) {return vowels.find(ch) ! string::npos;};int n s.size();int i 0, j n - 1;while (i < j) {while (i < …

Leetcode JAVA刷刷站(48)旋转图像

一、题目概述 二、思路方向 要在原地顺时针旋转一个 n x n 的二维矩阵 90 度&#xff0c;你可以通过一系列交换操作来实现。这里的关键在于理解旋转后的矩阵与原矩阵之间的元素对应关系。 假设原矩阵为 matrix&#xff0c;其中 matrix[i][j] 表示第 i 行第 j 列的元素。旋转 90…

【每日一题 | 数据结构】压缩矩阵存储算法

题型方法讲解 首先明确&#xff0c;压缩矩阵存储算法是408考试中的重点、难点、高频考点&#xff0c;甚至曾经达成了连续五年考到程度&#xff0c;让同学们感到恐惧。很多同学都会把这类题型当成一个记公式的题&#xff0c;其实不然&#xff0c;这个视频将会告诉你如何用推导的…

485总线常开+常闭,8路C型继电器输出模块DAM-3018CA

阿尔泰科技 型号&#xff1a;DAM-3018CA 概述&#xff1a; DAM-3018CA为8路C型继电器输出模块&#xff0c;每通道具有LED指示灯指示&#xff0c;RS485通讯接口&#xff0c;带有标准ModbusRTU协议。配备良好的人机交互界面&#xff0c;使用方便&#xff0c;性能稳定。 产品图…

Leetcode JAVA刷刷站(50)Pow(x, n)

一、题目概述 二、思路方向 方法1&#xff1a;递归&#xff08;考虑正负n&#xff09; 这种方法利用递归的思想&#xff0c;将问题分解为更小的子问题。同时&#xff0c;考虑到n可能是负数&#xff0c;我们可以先处理n的符号&#xff0c;然后将问题转化为正数幂的问题。 publi…

24/8/15算法笔记 复习_决策树

#手动计算决策树到底是如何实现分类的 p1 (y N).mean() p2 (y Y).mean()p1 * np.log2(1/p1) p2*np.log2(1/p2)X[真实用户] y x X[日志密度].unique()#.unique() 是一个方法&#xff0c;它返回一个数组&#xff0c;包含 X[日志密度] 列中所有不同的值。 x.sort()#排序 print…

读零信任网络:在不可信网络中构建安全系统21读后总结与感想兼导读

1. 基本信息 零信任网络&#xff1a;在不可信网络中构建安全系统 道格巴斯&#xff08;Doug Barth&#xff09; 著 人民邮电出版社,2019年8月出版 1.1. 读薄率 书籍总字数252千字&#xff0c;笔记总字数73194字。 读薄率73194252000≈29.5% 这个读薄率是最高的吧&#x…

客户端登录逻辑

将网关服务器发送的数据通过信号传递给 TcpMgr 中定义的槽函数 void LoginDialog::initHttpHandlers() {// 注册获取登录回包逻辑m_handlers.insert(ReqId::ID_LOGIN_USER, [this](QJsonObject jsonObj){int error jsonObj["error"].toInt();if(error ! ErrorCodes:…

Superset BI封装自定义组件(堆叠柱状图)

目录 前言 封装步骤 一、创建组件文件夹 二、预设组件信息 三、使用组件 往期回顾 前言 Superset 是一个现代化的、易于使用的、轻量级的数据可视化工具&#xff0c;它允许用户通过简单的点击操作来创建和分享图表。如果你想在 Superset 中创建自定义组件&#xff0c;你…

银河麒麟服务器操作系统Kylin-Server-V10-SP3-2403-Release-20240426-x86_64安装步骤

银河麒麟服务器操作系统 Kylin-Server-V10-SP3-2403-Release-20240426-x86_64安装步骤 一、准备工作1. 下载ISO镜像2. 制作安装介质3. 设置BIOS 二、安装过程1. 启动系统2. 选择安装语言3. 选择安装配置4. 配置root密码与创建用户5. 开始安装6. 重启系统7. 同意许可协议 三、系…

mac/win视频编辑软件Premiere Pro Pr安装装下载

目录 一、PR软件介绍 1.1 PR软件概览 1.2 独特优势 1.3 应用场景 二、安装与硬件要求 2.0下载 2.1 安装步骤 2.2 硬件要求 三、使用方法 3.1 基础操作 3.2 编辑技巧 3.3 高级功能 一、PR软件介绍 1.1 PR软件概览 Adobe Premiere Pro&#xff08;简称PR&#xff0…

项目推荐——一款开源、免费、轻量级的项目工时管理系统

平台介绍 无鱼工时管理系统&#xff0c;是一款轻量级工时记录和管理工具&#xff0c;包括项目管理&#xff0c;工时上报&#xff0c;工时日报&#xff0c;工时统计等功能。 无鱼工时管理系统可通过员工工时上报的方式&#xff0c;来记录项目所花费的工时&#xff0c;帮助企业…

机器学习:一元线性回归模型

目录 前言 一、讲在前面 1.data.csv&#xff1a; 2.完整代码&#xff1a; 3.运行结果&#xff1a; 二、实现步骤 1.导入库 2.导入数据 3.绘制散点图&#xff08;这步可以省略&#xff09; 4.求特征和标签的相关系数 5.建立并训练线性回归模型 6.检验模型 7.获取线…

Element-06.案例

一.目标 实现下面这个页面&#xff0c;表格中的数据使用axois异步加载数据 二.实现步骤 首先在vue项目的views文件夹中新建一个tlias文件夹&#xff0c;用来存储该案例的相关组件。员工页面组件&#xff08;EmpView.vue&#xff09;和部门页面组件&#xff08;DeptView.vue&…

[数据集][目标检测]电力场景轭式悬架锈蚀分类数据集6351张2类别

数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;6351 分类类别数&#xff1a;2 类别名称[corrosion,good] 每个类别图片数&#xff1a; corrosion 图片数&#xff1a;310 good 图片数&#xff1a;6041 …

ChatGLM-6B 主要代码分析 RotaryEmbedding

ChatGLM-6B 主要代码分析 RotaryEmbedding flyfish 图片链接地址 传统的 Transformer 位置编码&#xff08;Positional Encoding&#xff09;被称为绝对位置编码 &#xff0c;而 Rotary Embedding 被称为相对位置编码 &#xff0c;主要是因为它们编码位置信息的方式不同&am…

python创建项目环境及项目打包

目录 创建项目环境conda创建环境常用命令创建项目虚拟环境创建虚拟环境激活虚拟环境安装第三方库 pyinstaller 打包常用参数组合 嵌入式打包下载嵌入式版本的python配置环境无参调用可完善 nuitka打包 创建项目环境 conda创建环境常用命令 conda create -n py310 python3.10.…