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 放在…

python - ExcelWriter.book 无法设置属性 ‘book‘

问题描述 conda 环境使用python编辑excel&#xff0c;安装pandas依赖版本为2.2.1。 pandas2.2.1 以下代码片段报错&#xff1a; AttributeError: property book of OpenpyxlWriter object has no setter&#xff08;无法设置属性 book &#xff09; with pd.ExcelWriter(t…

进程控制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…

Linux提权--准备工作知识点工具

目录 知识点: 系列内容&#xff1a; 截至目前思路点总结如下&#xff1a; 思考点&#xff1a; 探针&漏扫工具网址 工具小总: 数据库提权工具网址: ---提权命令百科-- 演示案例&#xff1a; 知识点: 1、Linux 提权辅助项目-探针&漏扫 2、Linux 提权-配置 SUID …

模拟LinkedList实现的双向循环链表

1. 前言 前文我们分别实现了不带哨兵的单链表&#xff0c;带哨兵节点的双向链表&#xff0c;接着我们实现带哨兵节点的双向循环链表.双向循环链表只需一个哨兵节点&#xff0c;该节点的prev指针和next指针都指向了自身哨兵节点. 2. 实现双向循环链表的代码 例 : //模拟双向…

c++中的__declspec(dllexport) 和 __declspec(dllimport)

c中的__declspec(dllexport) 和 __declspec(dllimport) 1. __declspec(dllimport) __declspec(dllimport) 是Microsoft Visual C特有的修饰符&#xff0c;用于声明在动态链接库&#xff08;DLL&#xff09;中定义的函数和变量&#xff0c;以便在另一个模块中使用。它告诉编译…

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

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

IO流体系

一.分类 1.字节流 &#xff08;1&#xff09;.InputStream&#xff08;字节输入流&#xff09; 定义&#xff1a;操作本地文件的字节输入流&#xff0c;可以把本地文件中的数据读取到程序中 书写步骤&#xff1a;1.创建字节输入流对象&#xff0c;2.读数据&#xff0c;3.释放…

聊聊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 镜像…

Java23种设计模式-创建型模式之单例模式

单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a;通过单例模式的方法创建的类在当前进程中只有一个实例&#xff08;根据需要&#xff0c;也有可能一个线程中属于单例&#xff0c;如&#xff1a;仅线程上下文内使用同一个实例&#xff09;&#xff0c;该类负责创…

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

如有不对&#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;-…

2024人工智能/机器学习/machine learning/CV/NLP重点公式汇总(算法面试考试论文)

### CV # Diffusion Model 扩散模型http://deepnlp.org/equation/diffusion-model-forward-processhttp://deepnlp.org/equation/diffusion-model-forward-process-reparameterizationhttp://deepnlp.org/equation/diffusion-model-reverse-processhttp://deepnlp.org/equation…