python应用-socket网络编程(2)

     socket 是 Python 标准库中的一个模块,它提供了低级别的网络通信接口。使用 socket 模块,你可以创建客户端和服务器应用程序,以便在网络上进行数据交换。

接着上文我们介绍下socket模块其他的一些函数。

目录

gettimeout() 和settimeout()

socket.error套接字错误

inet_aton() 和inet_ntoa()

inet_pton()和inet_ntop()

socket.getsockopt()

socket.setsockopt()

socket.setblocking()

gethostname() 

gethostbyname(hostname) 

getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)

getnameinfo(sockaddr, flags) 

gettimeout() 和settimeout()

调用gettimeout()方法获取默认的套接字超时时间,调用settimeout()方法设定一个套接字超时时间。默认无超时时间,当设置超时时间后,当服务端启动socket套接字时,超过了超时时间没有客户端建立连接,会报错。

import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Waiting for a connection...')
print("Default socket timeout: %s" % server_socket.gettimeout())
server_socket.settimeout(10)
print("Current socket timeout: %s" % server_socket.gettimeout())

举例:设置超时时间10s,执行程序后,10s后程序会报错

Waiting for a connection...
Default socket timeout: None
Current socket timeout: 10.0
Traceback (most recent call last):File "/Users/htsc/Desktop/test.py", line 43, in <module>connection, client_address = server_socket.accept()File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/socket.py", line 293, in acceptfd, addr = self._accept()TimeoutError: timed out

socket.error套接字错误

在网络应用中,经常会遇到一方尝试连接,但另一方由于网络媒介失效或者其他

原因无法响应。Python的socket库提供了一个方法,能通过socket.error异常优雅地处理套接

字错误。

# 创建一个 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
server_address = ('localhost', 8080)
try:client_socket.connect(server_address)
except socket.error as e:print(f'客户端连接报错 {e}')
# 发送数据
try:message = 'hello world!'client_socket.sendall(message.encode())
except socket.error as e:print(f'客户端发送错误 {e}')

服务端没有启动时执行程序报错:

客户端连接报错 [Errno 61] Connection refused
客户端发送错误 [Errno 32] Broken pipe

inet_aton() 和inet_ntoa() 

inet_aton() 将十进制格式的 IPv4 地址转换为二进制格式。

inet_ntoa() 将二进制格式的 IPv4 地址转换回点分十进制格式的字符串。

print(socket.inet_aton('192.168.1.1'))
print(socket.inet_ntoa(b'\xc0\xa8\x01\x01'))
b'\xc0\xa8\x01\x01'
192.168.1.1

inet_pton()和inet_ntop()

同时支持IPv4和IPv6地址的转换。

socket.inet_pton(socket.AF_INET6, ip_str) 来转换IPv6地址的字符串为二进制格式,以及 socket.inet_ntop(socket.AF_INET6, packed_ip) 来转换二进制格式为IPv6地址的字符串。

print(socket.inet_pton(socket.AF_INET6,'A2DD:E543::A234:12AE'))
print(socket.inet_ntop(socket.AF_INET6,b'\xa2\xdd\xe5C\x00\x00\x00\x00\x00\x00\x00\x00\xa24\x12\xae'))'
b'\xa2\xdd\xe5C\x00\x00\x00\x00\x00\x00\x00\x00\xa24\x12\xae'
a2dd:e543::a234:12ae

socket.inet_pton(socket.AF_INET, ip_str) 来转换IPv4地址的字符串为二进制格式,以及 socket.inet_ntop(socket.AF_INET, packed_ip) 来转换二进制格式为IPv4地址的字符串。

print(socket.inet_pton(socket.AF_INET,'192.168.1.1'))
print(socket.inet_ntop(socket.AF_INET,b'\xc0\xa8\x01\x01'))
b'\xc0\xa8\x01\x01'
192.168.1.1

注意事项:

  • inet_aton() 和 inet_ntoa() 是非线程安全的,并且在多线程环境中使用时可能会出现问题。在多线程环境中,建议使用 inet_pton() 和 inet_ntop() 函数,它们提供了更好的错误处理和线程安全性。
  • inet_ntoa() 返回的字符串指针指向一个静态内存区域,因此每次调用都会覆盖上一次的结果。在多次调用 inet_ntoa() 时,需要注意不要依赖之前的结果。

socket.getsockopt()

是一个用于获取套接字选项值的函数。这个函数在 Python 的 socket 模块中定义,用于检索与套接字相关的各种参数和设置。

socket.getsockopt(level, option, buflen=0)

参数说明:

level:表示要获取的选项所在的协议层级。常见的值有:

socket.SOL_SOCKET:通用套接字选项。

socket.IPPROTO_IP:IP选项。

socket.IPPROTO_TCP:TCP选项。

option:表示要获取的选项的名称。例如 socket.SO_REUSEADDR 用于确定套接字地址是否可以在关闭后立即重用,socket.SO_SNDBUF 和 socket.SO_RCVBUF 分别用于获取发送和接收缓冲区的大小等。

buflen:表示获取选项值的缓冲区的长度。在某些情况下,这个参数可能是可选的,并且默认值为0,表示自动分配足够的空间来存储选项值。

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#发送缓冲区大小
print(client_socket.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF))

socket.setsockopt()

用于修改套接字的设置选项值,比上面的setsockopt()方法,多一个value参数,传入要修改的选项值。

举例:修改发送缓冲区大小

# 创建一个 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print(client_socket.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF))
#修改发送缓冲区大小 传入value参数=1024102
client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF,1024102)
print(client_socket.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF))

socket.setblocking()

默认情况下,TCP套接字处于阻塞模式中。

阻塞模式:在阻塞模式下,套接字操作(如发送和接收数据)将等待直到操作完成或发生错误。比如调用recv() 方法并且没有数据可读,程序将会挂起(即暂停执行),直到有数据可读或者连接关闭。

非阻塞模式:参数为 False,则套接字被设置为非阻塞模式。在非阻塞模式下,套接字操作会立即返回,而不会等待操作完成。比如recv() 方法可能会返回一个空字符串,或者引发一个异常(如 socket.error),具体取决于操作系统的行为。

举例:

  • 客户端连接设置为阻塞模式
# 创建一个 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#设置为阻塞模式
client_socket.setblocking(True)
#client_socket.settimeout(0.5)
# 连接到服务器
server_address = ('localhost', 8080)
client_socket.connect(server_address)
print('等待接收数据')
data = client_socket.recv(1024)
print(f'Received {len(data)} bytes {data.decode()}')

执行后程序显示:等待接收数据

  • 客户端设置为非阻塞模式:

以上代码将client_socket.setblocking(True)改为client_socket.setblocking(False)设置为非阻塞模式。重新执行程序后会报错:

BlockingIOError: [Errno 36] Operation now in progress

这个错误是在使用非阻塞套接字(non-blocking socket)时常见的错误之一。当你尝试在一个非阻塞套接字上执行一个需要等待的操作(比如读取或写入数据),而这个操作不能立即完成时,就会抛出这个错误。

在非阻塞模式下,套接字操作不会等待直到数据可用或操作完成。相反,它们会立即返回,并可能抛出 BlockingIOError 异常来表明操作不能立即完成。这意味着你需要检查操作是否成功,并在需要时重试。

gethostname() 

用于获取当前主机名。

import socket
print(socket.gethostname())
192.168.1.8

gethostbyname(hostname) 

用于解析主机名,返回相应的IP地址。这个函数只支持 IPv4 地址。

print(socket.gethostbyname('www.baidu.com'))
print(socket.gethostbyname('localhost'))
180.101.50.242
127.0.0.1

getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)

用于解析主机名和服务名,并返回相应的套接字地址信息。它支持 IPv4 和 IPv6 地址,并可以根据需要选择适当的协议。

函数的参数包括:

  • host:主机名或 IP 地址,以字符串形式给出。
  • port:服务名或端口号,以字符串或整数形式给出。为字符串,通常代表一个服务名(如 "http" 或 "ftp");为整数,代表一个具体的端口号(比如80 或者443)。
  • family:地址族,用于指定 IP 地址版本。常见的值包括 socket.AF_INET(IPv4)、socket.AF_INET6(IPv6)和 socket.AF_UNSPEC(不指定,让系统选择)。默认值为 0,表示让系统选择。
  • socktype:套接字类型,指定使用的套接字类型。常见的值有 socket.SOCK_STREAM(流套接字,如 TCP)和 socket.SOCK_DGRAM(数据报套接字,如 UDP)。默认值为 0,表示让系统选择。
  • proto:协议类型。通常可以设置为 0,让系统根据 family 和 socktype 选择合适的协议。
  • flags:标志位,用于控制地址信息的获取方式。例如,socket.AI_PASSIVE 用于获取用于绑定的地址,socket.AI_CANONNAME 用于获取主机名的规范形式等。

举例:分别获取百度域名443端口的一些地址信息

print(socket.getaddrinfo('www.baidu.com',443,family=socket.AF_INET6,type=socket.SOCK_STREAM))
print(socket.getaddrinfo('www.baidu.com',443,family=socket.AF_INET,type=socket.SOCK_DGRAM))
#结果
[(<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('240e:e9:6002:15a:0:ff:b05c:1278', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('240e:e9:6002:15c:0:ff:b015:146f', 443, 0, 0))]
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_DGRAM: 2>, 17, '', ('180.101.50.188', 443)), (<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_DGRAM: 2>, 17, '', ('180.101.50.242', 443))]

返回结果list中每个元组解释如下:

这个五元组的意义如下:

第一个切片:2表示 IPv4 协议(socket.AF_INET)

30表示 IPv6 协议(socket.AF_INET6)

第二个切片: 1表示流套接字(socket.SOCK_STREAM),通常用于 TCP 连接。2表示数据报套接字(Socket.SOCK_DGRAM:)

第三个切片:6:这是 TCP 的协议号,17是UDP的协议号

第四个切片: 主机的规范名称,可能为空字符串,

第五个切片:('93.184.216.34', 80):这是实际的 IP 地址和端口号,可以用这些信息来创建套接字并进行连接。

getnameinfo(sockaddr, flags) 

是 getaddrinfo() 的逆操作,它将套接字地址信息转换为主机名和服务名。

参数解释:

sockaddr:套接字地址的元组。对于 IPv4,它通常是一个 (host, port) 的形式,其中 host 是 IP 地址(字符串形式),port 是端口号(整数形式)。

flags:标志位,用于控制解析的方式。例如,socket.NI_NUMERICHOST 和 socket.NI_NUMERICSERV 可以用来强制返回数字形式的主机名和服务名,而不是尝试解析它们。

getnameinfo 函数返回一个包含两个元素的元组:(host, serv),其中 host 是主机名(字符串形式),serv是服务名或端口号(字符串形式)。如果 IP 地址没有与之关联的主机名(即它没有被反向解析),getnameinfo 可能会返回 IP 地址本身作为主机名。

print(socket.getnameinfo(('180.101.50.242', 443),socket.NI_NUMERICSERV))
('180.101.50.242', '443')

共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”

-----指水滴不断地滴,可以滴穿石头;

-----比喻坚持不懈,集细微的力量也能成就难能的功劳。

----感谢读者的阅读和学习,谢谢大家。

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

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

相关文章

0422empAJAX项目

数据库字段&#xff1a; 多条件查询&#xff1b; 分页查询&#xff1b; 添加图片&#xff1b; ajax离职操作&#xff1b; 删除选项&#xff0c;点击离职操作后仍然可实现删除选项

项目部署总结

1、安装jdk 第一步&#xff1a;上传jdk压缩安装包到服务器 第二步&#xff1a;将压缩安装包解压 tar -xvf jdk-8uXXX-linux-x64.tar.gz 第三步&#xff1a;配置环境变量 编辑/etc/profile文件&#xff0c;在文件末尾添加以下内容&#xff1a; export JAVA_HOME/path/to/j…

鉴权到底做什么

两种方案&#xff1a; 将 token 放在 cookie 里&#xff1b;将 token 放在请求头里&#xff0c;用 Authorization 字段。 无论对于前端还是后端而言&#xff0c;这两种方案都是各有利弊的&#xff0c;下面稍微讲几点&#xff0c;实际开发中根据需求来选用即可。 将 token 放在…

进程控制5 - exit()退出+子进程被收养+僵死进程

我们应当知道的是&#xff0c;在用fork创建子进程后&#xff0c;父子进程的执行的先后顺序是不定的&#xff0c;这时&#xff0c;我们可以用wait函数&#xff0c;wait()会暂停当前进程的执行&#xff0c;直到有信号到来或者子进程结束。总的来说&#xff0c;wait()的作用就是阻…

C语言编译的优化等级应该选哪个?O0、O1、O2还是O3

在使用IDE开发STM32程序时&#xff0c;IDE一般都会提供优化等级设置的选项&#xff0c;例如下图中KEIL软件优化等级的设置。 从上图中也可以看出&#xff0c;设置不同的优化等级&#xff0c;实际上是修改了编译器的编译参数。这个编译器是由ARM公司提供的C/C编译器armclang或者…

微信小程序Vue+nodejs+uniapp课堂教学辅助在线学习系统

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 后台主要实现功能&#xff1a;一、用户的管理(用户的信息管理) 二、 课程的管理&#xff08;课程发布&#xff0c;课后成绩的查看&#xff0c…

DAY 5

1. 2. #include <iostream>using namespace std; class Person {string name;int *age;public:Person():name("zhangsan"),age(new int (18)){cout << "Person的无参函数" << endl;}Person(string name,int *age):name("zhangsan&q…

水稻病害检测(YOLO数据集,多分类,稻瘟病、纹枯病、褐斑病、枯心病、霜霉病、水稻细菌性条纹斑病、稻苞虫)

是自己利用LabelImg工具进行手工标注&#xff0c;数据集制作不易&#xff0c;请尊重版权&#xff08;稻瘟病、纹枯病、褐斑病、枯心病、霜霉病、水稻细菌性条纹斑病、稻苞虫&#xff09; 如果需要yolv8检测模型和数据集放在一起的压缩包&#xff0c;可以关注&#xff1a;最新最…

聊聊Flink:Docker搭建Flink

一、准备工作 查看下Docker和Docker Compose版本&#xff0c;确保你安装了这些软件。 在 Flink 官网上下载 Flink 的 Docker 镜像。您可以使用以下命令从 Docker Hub 中下载&#xff1a; docker pull flink:1.18.0-scala_2.12 此命令将下载 Flink 1.18.0 版本的 Docker 镜像…

电商架构:系统设计+表设计

如有不对&#xff0c;请指正 欢迎评论区交流 需要哪些系统 商品系统、订单系统、权限系统、审核系统等。 商品系统 订单系统 审核系统 权限系统 参考 基于电商中台架构-商品系统设计(一) 附件

2024年【流动式起重机司机】报名考试及流动式起重机司机复审模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【流动式起重机司机】报名考试及流动式起重机司机复审模拟考试&#xff0c;包含流动式起重机司机报名考试答案和解析及流动式起重机司机复审模拟考试练习。安全生产模拟考试一点通结合国家流动式起重机司机考试…

电脑已经有了一个Windows10,再多装一个Windows10组成双系统

前言 前段时间已经讲过一次双Windows系统的安装教程&#xff0c;但是小白重新去看了一下&#xff0c;发现写的内容太多&#xff0c;怕小伙伴看了之后一脸萌。 所以今天咱们就重新再来讲讲&#xff1a;在同一台机器上安装Windows10双系统的教程。 注意哦&#xff01;这里的Wi…

Android优化RecyclerView图片展示:Glide成堆加载批量Bitmap在RecyclerView成片绘制Canvas,Kotlin(b)

Android优化RecyclerView图片展示&#xff1a;Glide成堆加载批量Bitmap在RecyclerView成片绘制Canvas&#xff0c;Kotlin&#xff08;b&#xff09; 对 Android GridLayoutManager Glide批量加载Bitmap绘制Canvas画在RecyclerView&#xff0c;Kotlin&#xff08;a&#xff09;-…

【GitHub】主页简历优化

【github主页】优化简历 写在最前面一、新建秘密仓库二、插件卡片配置1、仓库状态统计2、Most used languages&#xff08;GitHub 常用语言统计&#xff09;使用细则 3、Visitor Badge&#xff08;GitHub 访客徽章&#xff09;4、社交统计5、打字特效6、省略展示小猫 &#x1f…

求解约瑟夫问题

思路&#xff1a; 我们要创建两个指针 有一个指针pcur指向头结点&#xff0c;该pcur作为报数的指针&#xff0c;还有一个指针ptail指向尾结点&#xff0c;作为记录pcur的地址 每报数为m时&#xff0c;pcur指向下一个元素的地址&#xff0c;ptail销毁报数为m的地址&#xff0…

制糖工业智能工厂数字孪生可视化平台,推进制糖产业数字化转型

制糖工业智能工厂数字孪生可视化平台&#xff0c;推进制糖产业数字化转型。随着信息技术的快速发展&#xff0c;数字化转型已成为各行各业的重要趋势。在糖果加工制造领域&#xff0c;智能工厂数字孪生可视化平台的出现&#xff0c;为行业数字化转型注入了新的活力。 糖果加工制…

算法训练营day25

零、回溯算法理论 参考链接13.1 回溯算法 - Hello 算法 (hello-algo.com) 1.尝试与回退 之所以称之为回溯算法&#xff0c;是因为该算法在搜索解空间时会采用“尝试”与“回退”的策略。当算法在搜索过程中遇到某个状态无法继续前进或无法得到满足条件的解时&#xff0c;它会…

python应用-socket网络编程(1)

目录 1 先简单回顾下客户端和服务端通信的知识 2 服务端常用函数 3 客户端常用函数 4 服务端和客户端都用的函数 5 示例介绍客户端和服务端通信过程 6 建立服务端套接制 7 创建服务端函数socket.create_server() 8 创建客户端套接字 9 客户端连接函数socket.create_co…

基于Springboot的甘肃旅游服务平台(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的甘肃旅游服务平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

学习周报:文献阅读+Fluent案例+有限体积法理论学习

目录 摘要 Abstract 文献阅读&#xff1a;基于物理信息神经网络的稀疏数据油藏模拟 文献摘要 文章讨论|结论 各方程和原理简介 PINN简介 域分解 实验设置 单相油藏问题 油水两相问题 Fluent实例&#xff1a;Y型弯管中的流体混合分析 几何建模部分 网格划分 求解器设…