Python- socket编程

Python中的socket模块为网络通信提供了基础API,使我们能够在应用程序中实现低级的网络交互。使用socket编程,可以创建TCP、UDP和RAW sockets来进行数据通信。

以下是Python socket 编程的简要概述:

1. 核心概念

  • Socket: 通信的端点,通常用于建立多个系统之间的连接。
  • Bind: 将套接字与特定的IP地址和端口号关联。
  • Listen: 在套接字上监听传入的连接。
  • Accept: 接受传入的连接请求。
  • Connect: 初始化与服务器的连接。

2. 基本流程

服务器端:
  1. 创建套接字: socket.socket()
  2. 绑定套接字到地址: bind((host, port))
  3. 监听连接: listen()
  4. 接受连接: accept()
  5. 读取/发送数据: recv()/send()
  6. 关闭套接字: close()
客户端:
  1. 创建套接字: socket.socket()
  2. 连接到服务器: connect((host, port))
  3. 读取/发送数据: recv()/send()
  4. 关闭套接字: close()

3. 主要函数/方法

  • socket(): 创建新的socket对象。
  • bind(): 绑定地址到套接字。
  • listen(): 开始监听传入的连接。
  • accept(): 接受客户端连接,并返回(connection, address)。
  • connect(): 连接到远程地址。
  • recv(): 从套接字接收数据。
  • send(): 将数据发送到套接字。
  • close(): 关闭套接字。

4. TCP

一个简单的TCP服务器和客户端的示例。

TCP服务器
import socket
import jsondef start_server():# 创建socket对象server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 获取主机名称# host = socket.gethostname()host = "127.0.0.1"port = 12345# 绑定到端口server_socket.bind((host, port))# 设置最大连接数,超过后排队server_socket.listen(5)print("Server is listening...")while True:# 建立客户端连接client_socket, addr = server_socket.accept()print(f"Connection from {addr}")data = client_socket.recv(1024).decode('utf-8')json_data = json.loads(data)print(f"Received {json_data} from {addr}")client_socket.send(data.encode('utf-8'))client_socket.close()if __name__ == '__main__':start_server()
TCP客户端
import socket
import jsondef start_client():# 创建socket对象client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 获取本地主机名# host = socket.gethostname()host = "127.0.0.1"port = 12345print(host)# 连接到服务器client_socket.connect((host, port))message = {"name": "Alice","age": 30}json_message = json.dumps(message)# 发送数据client_socket.send(json_message.encode('utf-8'))# 接收数据,最多接收1024字节data = client_socket.recv(1024).decode('utf-8')json_data = json.loads(data)print(f"Received from server: {json_data}")client_socket.close()if __name__ == '__main__':start_client()

运行结果如下:

运行效果

5. UDP

与TCP不同,UDP是一个无连接的协议。使用UDP,不需要建立和断开连接。每个数据报都是一个独立的消息。

UDP 服务器
import sockets = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('127.0.0.1', 12345))
while True:data, addr = s.recvfrom(1024)print(f"Received {data.decode('utf-8')} from {addr}")s.sendto(data, addr)
UDP 客户端
import sockets = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:message = input("Enter message: ").encode('utf-8')s.sendto(message, ('127.0.0.1', 12345))data, addr = s.recvfrom(1024)print(f"Received {data.decode('utf-8')} from {addr}")

运行结果如下:

运行效果

6. ICMP

RAW sockets是一种低级的通信机制,允许我们直接发送和接收底层网络协议的数据包,如ICMP、IP等。在Python中使用RAW sockets通常需要root权限或适当的权限,因为它涉及到操作系统级的网络操作。

以下是使用RAW socket在Python中发送一个ICMP Echo Request(通常称为ping请求)的示例。注意,此代码是在Linux上工作的,因为Windows上的raw socket行为与Linux不同。

import socket
import struct
import timedef checksum(data):s = 0n = len(data) % 2for i in range(0, len(data)-n, 2):s += (data[i] + (data[i+1] << 8))if n:s += data[i+1]while (s >> 16):s = (s & 0xFFFF) + (s >> 16)s = ~s & 0xFFFFreturn sdef create_icmp_echo_request():icmp_type = 8icmp_code = 0icmp_checksum = 0icmp_identifier = 1icmp_sequence_number = 1# ICMP headerheader = struct.pack("!BBHHH", icmp_type, icmp_code, icmp_checksum, icmp_identifier, icmp_sequence_number)data = struct.pack("!d", time.time())icmp_checksum = checksum(header + data)header = struct.pack("!BBHHH", icmp_type, icmp_code, icmp_checksum, icmp_identifier, icmp_sequence_number)return header + datadef main():target_host = "172.20.7.84" icmp_proto = socket.getprotobyname('icmp')# Create a raw sockets = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp_proto)s.sendto(create_icmp_echo_request(), (target_host, 0))# Wait for a replywhile True:data, addr = s.recvfrom(1024)if addr[0] == target_host:print(data)print(f"Received reply from {addr[0]}")breakif __name__ == "__main__":main()

这只是一个简单的示例,它发送一个ICMP请求并等待一个响应。在生产环境中使用RAW sockets时,需要处理更多的边缘情况和错误,以及考虑多种协议和包格式。

7. 错误处理

在socket编程中,特别是在网络中,总是可能发生各种错误。为了编写健壮的应用程序,应该捕获socket.error异常并据此采取适当的行动。

8. 高级

除了基础的socket编程,Python还提供了更高级的工具和模块,例如selectorsasyncio,用于处理多并发连接或异步IO。

总之,socket编程是计算机网络和分布式系统中的一个基本概念。Python提供了一个强大而简单的API来处理套接字,使得网络编程变得相对容易。


以下是关于ICMP示例程序的几点说明:

(1)当在Python中使用struct.pack方法,表示正在执行结构化的打包操作,将多个数据项打包成一个字节串。它通常用于处理二进制数据和底层的数据结构,例如网络协议。

在ICMP示例代码段中:

header = struct.pack("!BBHHH", icmp_type, icmp_code, icmp_checksum, icmp_identifier, icmp_sequence_number)

我们逐一解析这行代码:

  1. !: 这是字节顺序标记。感叹号!表示网络字节顺序,也就是大端字节序。在网络通讯中,大端字节序是常用的标准。

  2. BBHHH: 这是格式字符串,它告诉struct.pack如何打包接下来的数据。

    • B: 无符号字符(1个字节)
    • H: 无符号短整数(2个字节)

    因此,BBHHH表示打包了2个1字节的无符号字符和3个2字节的无符号短整数,总共8个字节。

  3. 后面的参数列表(icmp_type, icmp_code, icmp_checksum, icmp_identifier, icmp_sequence_number)是要打包的实际数据。这些数据的顺序和大小应该与格式字符串BBHHH匹配。

具体到ICMP头部的内容:

  • icmp_type: ICMP消息的类型(1字节)
  • icmp_code: 与ICMP类型相关的特定代码(1字节)
  • icmp_checksum: 对整个ICMP数据包计算得到的校验和(2字节)
  • icmp_identifier: 用于唯一标识此请求的标识符,通常是发送进程的PID(2字节)
  • icmp_sequence_number: 该请求的序列号,通常是从0开始递增的(2字节)

通过struct.pack,这些数据被格式化和打包成一个连续的8字节的字节串,然后可以直接发送到网络上。

(2)在下面的代码片段中,使用struct.pack来将一个双精度浮点数(即Python中的float)打包为一个二进制格式的字符串。这样的操作常用于将高级的数据类型转换为可以在网络上发送或在二进制文件中存储的格式。

data = struct.pack("!d", time.time())

让我们逐步解析这段代码:

  1. struct.pack: 这是Python中的struct模块提供的函数,用于将给定的数据格式化(或打包)为一个二进制字符串。

  2. "!d": 这是一个格式字符串,它告诉struct.pack函数如何格式化后续的数据。

    • !: 指定字节顺序为网络字节顺序(也就是大端字节序)。

    • d: 表示一个双精度浮点数。这通常占用8个字节。

  3. time.time(): 这是Python中time模块的一个函数,返回当前时间的时间戳,类型为float。这表示从某个固定的起点(通常是1970年1月1日0点,称为Unix纪元)到现在的秒数。

这段代码的目的是将当前的时间戳转换为一个8字节的二进制字符串。这在网络编程中很有用,尤其是当我们想在数据包中包含一个时间戳,以便在接收端可以解码并使用它。例如,在ICMP的ping工具中,发送时间戳可以帮助计算往返时间(RTT)。

(3)下面这段代码使用socket模块的getprotobyname方法来查询指定协议名的协议号。具体来说,它查询“icmp”协议的协议号。

icmp_proto = socket.getprotobyname('icmp') 

让我们详细了解这段代码:

  1. socket: 这是Python的标准库之一,它提供了套接字编程的工具和函数。

  2. getprotobyname: 这个函数的作用是返回与给定的协议名称关联的协议号。

  3. 'icmp': 这是传递给getprotobyname函数的参数,代表互联网控制消息协议(ICMP)。

当这个函数被调用时,它会查找系统的协议配置文件(通常是/etc/protocols)来找到与“icmp”匹配的协议号。通常,ICMP的协议号为1,所以函数通常会返回1

为什么这个是重要的?当创建原始套接字(raw socket)用于发送或接收ICMP消息时,我们需要告诉系统正在使用哪种协议。icmp_proto这个变量保存的值(即ICMP的协议号)就是这个目的。当创建一个原始套接字并指定ICMP协议时,系统就知道我们要处理ICMP数据包。

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

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

相关文章

分布式事务入门

文章目录 分布式事务问题本地事务分布式事务演示分布式事务问题 理论基础CAP定理一致性可用性分区容错矛盾 BASE理论 SeataSeata的架构部署TC服务微服务集成seata 动手实践XA模式两阶段提交Seata的XA模型实现XA模式 AT模式Seata的AT模型流程梳理脏写问题实现AT模式 TCC模式流程…

github小记(一):清除github在add或者commit之后缓存区

github清除在add或者commit之后缓存区 前言1. 第一步之后想要撤销2. 第二步之后想要撤销a. 改变一下rrr.txt的内容b. 想提交本地文件的test文件夹c. 我后悔了突然不想提交了 前言 github自用 一般github上代码提交顺序&#xff1a; 第一步&#xff1a; git add . or git ad…

0基础学习VR全景平台篇 第107篇:全景图调色和细节处理(上,地拍)

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 今天教给大家的课程是地拍全景图调色和细节处理&#xff0c;下面我们就开始吧&#xff01; 1.把照片快速导入LR软件 选择【图库】模块 打开软件后&#xff0c;点击【导入】按…

【Ceph Block Device】块设备挂载使用

文章目录 前言创建pool创建user创建image列出image检索image信息调整image大小增加image大小减少image大小 删除image从pool中删除image从pool中“延迟删除”image从pool中移除“延迟删除的image” 恢复image恢复指定pool中延迟删除的image恢复并重命名image 映射块设备格式化i…

总结四:数据库(MySQL)面经

文章目录 一、SQL1、介绍一下数据库分页2、介绍一下SQL中的聚合函数3、表跟表是怎么关联的?4、说一说你对外连接的了解&#xff1f;5、说一说数据库的左连接和右连接&#xff1f;6、SQL中怎么将行转成列&#xff1f;7、谈谈你对SQL注入的理解&#xff1f;8、将一张表的部分数据…

苍穹外卖(一)

苍穹外卖项目介绍 项目介绍 本项目&#xff08;苍穹外卖&#xff09;是专门为餐饮企业&#xff08;餐厅、饭店&#xff09;定制的一款软件产品&#xff0c;包括 系统管理后台 和 小程序端应用 两部分。其中系统管理后台主要提供给餐饮企业内部员工使用&#xff0c;可以对餐厅…

提升市场调研和竞品分析效率:利用Appium实现App数据爬取

市场调研和竞品分析通常需要获取大量的数据&#xff0c;而手动收集这些数据往往耗时且容易出错。而利用Appium框架&#xff0c;我们可以轻松地实现自动化的App数据爬取&#xff0c;这种方法不仅可以节省时间和人力成本&#xff0c;还可以提高数据的准确性和一致性。 Appium是一…

springboot单独在指定地方输出sql

一般线上项目都是将日志进行关闭&#xff0c;因为mybatis日志打印&#xff0c;时间长了&#xff0c;会占用大量的内存&#xff0c;如果我想在我指定的地方进行打印sql情况&#xff0c;怎么玩呢&#xff01; 下面这个场景&#xff1a; 某天线上的项目出bug了&#xff0c;日志打印…

网线接法aaa

![(https://img-blog.csdnimg.cn/d2901403dbd44feaa8f7be669ddcf2fc.png) 加粗样式 在这里插入图片描述

论文阅读笔记(Clover: 计算与存储被动分离的分布式键值存储系统)

关于Disaggregating Persistent Memory and Controlling Them Remotely: An Exploration of Passive Disaggregated Key-Value Stores这篇论文的笔记 原文链接 提出背景 传统的分布式存储系统中&#xff0c;每个节点都会包含计算和存储两个部分&#xff0c;一个节点既可以访…

HDLbits: Lemmings3

Lemmings又多了一种状态&#xff1a;dig&#xff0c;我按照上一篇文章里大神的思路又多加了两种状态&#xff1a;LEFT_DIGGING与RIGHT_DIGGING&#xff0c;写出了如下的代码&#xff1a; module top_module(input clk,input areset, // Freshly brainwashed Lemmings walk …

nginx windows安装部署,代理转发配置

一、安装 1、nginx官网下载 windows版本 nginx官网 下载后解压到本地 2、在nginx的配置文件是conf目录下的nginx.conf&#xff0c;默认配置的nginx监听的端口为80&#xff0c;如果本地电脑的80端口有被占用&#xff0c;如果本地80端口已经被使用则修改成其他端口。如下&…

HDLbits: Lfsr5

我的错误写法&#xff0c;半成品&#xff0c;完全错误&#xff1a; module top_module(input clk,input reset, // Active-high synchronous reset to 5h1output [4:0] q ); dff dff_1(clk, 0 ^ q[0],q[4]);dff dff_2(clk, q[4] ,q[3]);dff dff_3(clk, q[3] ^ q[0] ,q[2]);…

通讯网关软件020——利用CommGate X2Mysql实现Modbus TCP数据转储Mysql

本文介绍利用CommGate X2MYSQL实现从Modbus TCP设备读取数据并转储至MYSQL数据库。CommGate X2MYSQL是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;实现从Modbus TCP设备读取数据并转储至M…

2023年电工(初级)证考试题库及电工(初级)试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年电工&#xff08;初级&#xff09;证考试题库及电工&#xff08;初级&#xff09;试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#…

【网络安全】「漏洞原理」(二)SQL 注入漏洞之理论讲解

前言 严正声明&#xff1a;本博文所讨论的技术仅用于研究学习&#xff0c;旨在增强读者的信息安全意识&#xff0c;提高信息安全防护技能&#xff0c;严禁用于非法活动。任何个人、团体、组织不得用于非法目的&#xff0c;违法犯罪必将受到法律的严厉制裁。 【点击此处即可获…

软件设计师学习笔记12-数据库的基本概念+数据库的设计过程+概念设计+逻辑设计

1.数据库的基本概念 1.1数据库的体系结构 1.1.1常见数据库 ①集中式数据库 数据是集中的&#xff1b;数据管理是集中的 ②C/S结构 客户端负责数据表服务&#xff1b;服务器负责数据库服务&#xff1b;系统分前后端&#xff1b;ODBC、JDBC ③分布式数据库 物理上分布、逻…

Unity可视化Shader工具ASE介绍——5、ASE快捷键和常用节点介绍

大家好&#xff0c;我是阿赵。   继续介绍Unity可视化Shader插件ASE。这次来说一些常用节点的快捷键&#xff0c;顺便介绍一些常用的节点。   用过UE引擎的朋友可能会发现&#xff0c;ASE的整体用法和UE的材质节点编辑器非常的像&#xff0c;甚至连很多节点的快捷键都和UE的…

【iOS】Fastlane一键打包上传到TestFlight、蒲公英

Fastlane一键打包上传到TestFlight、蒲公英 前言一、准备二、探索一、Fastlane配置1、Fastlane安装2、Fastlane更新3、Fastlane卸载4、查看Fastlane版本5、查看Fastlane位置6、Fastlane初始化 二、Fastlane安装蒲公英插件三、Fastlane文件编辑1、Gemfile文件2、Appfile文件3、F…

Jetson Orin NX 开发指南(8): Mavros 的安装与配置

一、前言 由于 Jetson 系列开发板常作为自主无人机的机载电脑&#xff0c;而无人机硬件平台如 PX4 和 ArduPilot 等通过 MAVLink 进行发布无人机状态和位姿等信息&#xff0c;要实现机载电脑与 MAVLink 的通信&#xff0c;必须借助 Mavros 功能包&#xff0c;因此&#xff0c;…