一个例子走近 Python Socket 编程:模拟各种常见的 WinError 情况

Python 一个 例子 个例 走近


一、引言

最近在工作中使用 Python 写了一个测试用的小工具,大概作用是这样的:

这个小工具作为一个服务端,对客户端发起的请求信息,做一些处理,然后将返回的报文同步或者异步的返回回去。

对于这个小工具来说,其主要作为被请求服务的服务端进行工作。而在这个小工具的开发过程中,我经常会遇到诸如 Python Socket 编程的 [WinError XXXXX]之类的错误。

遇到的多了,我发现,与其遇到一个 WinError 错误然后去搜索原因,不如我们自己写一个简单的基于 TCP 的服务端客户端通信程序,来自己把这些 WinError 错误的情况给模拟出来,这样,我们也会对这些 WinError 错误有更加深刻的理解。

说做就做,先上一份最简单的使用 Python Socket 编程实现的的服务端客户端通信程序。然后,我们在这份代码基础上,进行各种操作,去模拟实现一些常见的 WinError 错误。

二、C&S 代码

这里,直接上代码吧:

1. 代码

服务端程序

"""
Client side
Author: Wang Ying
Last modified: July 30 2019
"""
from socket import socket, AF_INET, SOCK_STREAM
# Create socket
tcpSerSocket = socket(AF_INET, SOCK_STREAM)
# Bind ip & port
address = ('127.0.0.1', 9999)
tcpSerSocket.bind(address)
# Begin listen
tcpSerSocket.listen(5)
while True:
# Receive client's connect, newSocket is served for client.
# tcpSerSocket wait for another client's connect.
newSocket, clientAddr = tcpSerSocket.accept()
while True:
# Receive client data
recvData = newSocket.recv(1024)
# if data length is 0, just break
if len(recvData) > 0:
print('recv:', recvData)
else:
break
# Send some data to client
sendData = input("send:")
newSocket.send(bytes(sendData.encode('utf-8')))
# Close the client socket
newSocket.close()
# Stop listen
tcpSerSocket.close()

客户端程序

"""
Client side
Author: Wang Ying
Last modified: July 30 2019
"""
from socket import socket, AF_INET, SOCK_STREAM
# Create socket
tcpClientSocket = socket(AF_INET, SOCK_STREAM)
# Connect to server
serAddr = ('127.0.0.1', 9999)
tcpClientSocket.connect(serAddr)
while True:
# Prompt input
sendData = input("send:")
if sendData == 'bye':
break
if len(sendData) > 0:
tcpClientSocket.send(bytes(sendData.encode('utf-8')))
else:
break
# Receive server data
recvData = tcpClientSocket.recv(1024)
print('recv:', recvData)
# Close socket
tcpClientSocket.close()

2. 分析

对于 Socket 编程来说,什么语言都是一样的,Python 也不例外。在这个例子中:

服务端程序绑定了一个 9999 端口,然后监听客户端 socket 的连接。这里的两层 while 循环,外层是用来遍历多个客户端的连接请求的,内层是用来实现与客户端交互接收发送数据的。

客户端程序连接服务端端口,然后进入一个循环,用于给服务端发送数据。

这里,首先运行服务端程序,然后再运行客户端程序,客户端先发送消息,服务端收到,然后服务端再发送消息给客户端,客户端收到,客户端又可以继续给服务端发送消息…直到,客户端输入 bye,然后跳出循环,关闭客户端的 socket 连接,这一过程也就结束了。

1

这是一个非常简单的服务端客户端通信程序,我们可以根据此程序来模拟各种 WinError 错误。接下来就开始吧:)

三、实验

[WinError 10061] 由于目标计算机积极拒绝,无法连接

我们刚才说到,运行这套程序,需要先运行服务端程序,然后再运行客户端程序,这是因为服务端监听在先,然后客户端再去连接。

那么,如果服务端程序并没有先启动,此时客户端就运行了,会出现什么错误呢?
2
总结下:

一旦客户端启动的时候,服务端并没有在客户端想要连接的 IP 和端口号上进行监听,那么就会出现 [WinError 10061] 由于目标计算机积极拒绝,无法连接 的错误。

[WinError 10054] 远程主机强迫关闭了一个现有的连接

我们先运行服务端程序,然后运行客户端程序,再然后紧接着强制性将客户端程序杀掉(不让其正常的关闭 socket 连接),此时会出现什么错误呢?

3
这个错误很好理解,连接上的 socket 连接被对方强制性中断(非正常 close 掉的),就会出现这个报错。

可能会有网友觉得,这里是客户端强制杀掉,那么我杀掉服务端又会报什么错呢?哈哈,大家可以自行尝试下,答案是不会报错:)个中原因,可以自行思考,这里只提示一句,一个客户端只连接一个服务端,但是一个服务端,是要连接零个一个或者多个客户端的。

总结下:

当客户端连接上服务端后,客户端程序强制性杀掉,此时服务端就会报错 [WinError 10054] 远程主机强迫关闭了一个现有的连接

[WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次

我们这回稍微修改一下客户端程序的代码,尝试下让客户端不去 connect 服务端的 socket 连接,而是 bind(就像服务端一样),修改如下:
client.py

tcpClientSocket.connect(serAddr)
# 修改为
tcpClientSocket.bind(serAddr)

会出现什么问题呢?

4
其实这个也很好理解,毕竟同一个端口被两个程序所监听,肯定会出现端口占用问题。

总结下:

一个端口已经被占用了,然后另一个程序想要去使用它,就会出现错误 [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次

[WinError 10038] 在一个非套接字上尝试了一个操作

我们这回接着魔改代码,这回我们修改服务端程序的代码:
server.py

 while True:
...
# 2. 这里调用 close,导致下一次循环 recv 的
# 时候会使用一个已经关闭了的 socket 连接
# 进行数据接收
newSocket.close()
# 1. 原本应该是跳出循环后才关闭 socket,我们现在
# 在接收到客户端的返回之后,就立即关闭。模拟关
# 闭 socket 之后再接收 socket 数据的场景。
# newSocket.close()

我们修改的地方就是 server.py,将原来的 close 函数放到了循环内部,导致 close 之后调用一次 recv。让我们先运行服务端程序,然后再运行客户端程序来看看会发生什么:
1
我们发现,在服务端程序运行到 recv 的时候会出现 [WinError 10038] 在一个非套接字上尝试了一个操作 的错误,其实这个很好理解,因为毕竟你已经把这个 socket 连接关闭了,然后你又想使用它来接收数据。

总结一下:

当你关闭了一个 socket 连接(close),然后又使用那个 socket 对象接收数据(recv),就会出现报错[WinError 10038] 在一个非套接字上尝试了一个操作

。。。未完待续,等待持续更新

如果在后续工作中,遇到了其他的有意思的错误信息,我也还会过来持续更新:)

四、总结

学习 Python 本就是一个很快乐的事情,比它更快乐的,那就是使用 Python 的过程。

Python 之路,路漫漫却不枯燥~~~
To be Stronger:)

版权声明
本文为[曾经去过跨越一个小时的地方]所创,转载请带上原文链接,感谢
https://wangying.blog.csdn.net/article/details/97828465

  1. 利用Python爬虫获取招聘网站职位信息
  2. Using Python crawler to obtain job information of recruitment website
  3. Several highly rated Python libraries arrow, jsonpath, psutil and tenacity are recommended
  4. Python装饰器
  5. Python实现LDAP认证
  6. Python decorator
  7. Implementing LDAP authentication with Python
  8. Vscode configures Python development environment!
  9. In Python, how dare you say you can't log module? ️
  10. 我收藏的有关Python的电子书和资料
  11. python 中 lambda的一些tips
  12. python中字典的一些tips
  13. python 用生成器生成斐波那契数列
  14. python脚本转pyc踩了个坑。。。
  15. My collection of e-books and materials about Python
  16. Some tips of lambda in Python
  17. Some tips of dictionary in Python
  18. Using Python generator to generate Fibonacci sequence
  19. The conversion of Python script to PyC stepped on a pit...
  20. Python游戏开发,pygame模块,Python实现扫雷小游戏
  21. Python game development, pyGame module, python implementation of minesweeping games
  22. Python实用工具,email模块,Python实现邮件远程控制自己电脑
  23. Python utility, email module, python realizes mail remote control of its own computer
  24. 毫无头绪的自学Python,你可能连门槛都摸不到!【最佳学习路线】
  25. Python读取二进制文件代码方法解析
  26. Python字典的实现原理
  27. Without a clue, you may not even touch the threshold【 Best learning route]
  28. Parsing method of Python reading binary file code
  29. Implementation principle of Python dictionary
  30. You must know the function of pandas to parse JSON data - JSON_ normalize()
  31. Python实用案例,私人定制,Python自动化生成爱豆专属2021日历
  32. Python practical case, private customization, python automatic generation of Adu exclusive 2021 calendar
  33. 《Python实例》震惊了,用Python这么简单实现了聊天系统的脏话,广告检测
  34. "Python instance" was shocked and realized the dirty words and advertisement detection of the chat system in Python
  35. Convolutional neural network processing sequence for Python deep learning
  36. Python data structure and algorithm (1) -- enum type enum
  37. 超全大厂算法岗百问百答(推荐系统/机器学习/深度学习/C++/Spark/python)
  38. 【Python进阶】你真的明白NumPy中的ndarray吗?
  39. All questions and answers for algorithm posts of super large factories (recommended system / machine learning / deep learning / C + + / spark / Python)
  40. [advanced Python] do you really understand ndarray in numpy?
  41. 【Python进阶】Python进阶专栏栏主自述:不忘初心,砥砺前行
  42. [advanced Python] Python advanced column main readme: never forget the original intention and forge ahead
  43. python垃圾回收和缓存管理
  44. java调用Python程序
  45. java调用Python程序
  46. Python常用函数有哪些?Python基础入门课程
  47. Python garbage collection and cache management
  48. Java calling Python program
  49. Java calling Python program
  50. What functions are commonly used in Python? Introduction to Python Basics
  51. Python basic knowledge
  52. Anaconda5.2 安装 Python 库(MySQLdb)的方法
  53. Python实现对脑电数据情绪分析
  54. Anaconda 5.2 method of installing Python Library (mysqldb)
  55. Python implements emotion analysis of EEG data
  56. Master some advanced usage of Python in 30 seconds, which makes others envy it
  57. python爬取百度图片并对图片做一系列处理
  58. Python crawls Baidu pictures and does a series of processing on them
  59. python链接mysql数据库
  60. Python link MySQL database