您的位置:首页 > 运维架构 > Linux

windows和linux中socket的非阻塞模式error:EWOULDBLOCK 和EAGAIN

2020-03-28 20:04 1271 查看

在学习socket编程的时候,测试了非阻塞模式下产生的错误(window环境)
先放上全部代码:

import socket
import errno
import threading
import time

# 多线程

EOL1 = b'\n\n'
EOL2 = b'\n\r\n'
body = '''Hello, world!<h1>from the5fire 《Django 企业开发实战》</h1> - from {thread_name}'''
response_params = [
'HTTP/1.0 200 OK',
'Date: Sun, 27 may 2018 01:01:01 GMT',
'Content-Type: text/html; charset=utf-8',
'Content-Length: {length}\r\n',
body
]
response = '\r\n'.join(response_params)

def handle_connection(conn, addr):
print('oh, new conn',conn, addr)
import time
time.sleep(5)
request = b""
while EOL1 not in request and EOL2 not in request:
request += conn.recv(1024)
print(request)
current_thread = threading.currentThread()
current_length = len(body.format(thread_name=current_thread.name).encode())
print(current_thread.name)
conn.send(response.format(thread_name=current_thread.name,length=current_length).encode())
conn.close()

def main():
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(('127.0.0.1', 8000))
serversocket.listen(5)
print('http://127.0.0.1:8000')
serversocket.setblocking(0)

try:
i = 0
while True:
try:
conn, address = serversocket.accept()
except socket.error as e:
print(e)
print(e.args)
print(errno.EAGAIN)
if e.args[0] != errno.EAGAIN:
raise
continue
i += 1
print(i)
t = threading.Thread(target=handle_connection, args=(conn, address), name='thread-%s' % i)
t.start()
finally:
serversocket.close()

if __name__ == '__main__':
main()

原本的构思是:把socket设置为非阻塞,在accept时要是产生异常(errno.EAGAIN)属于正常现象,跳过异常并且无限循环直到接收到请求,如果遇到其它异常则终止程序

然而程序只运行了一遍就终止了:

D:\ProgramData\Anaconda3\python.exe D:/0A_shangke/0001Python/Django/01/WSGI2.py
Traceback (most recent call last):
http://127.0.0.1:8000
[WinError 10035] 无法立即完成一个非阻止性套接字操作。
File "D:/0A_shangke/0001Python/Django/01/WSGI2.py", line 65, in <module>
(10035, '无法立即完成一个非阻止性套接字操作。', None, 10035, None)
main()
11
File "D:/0A_shangke/0001Python/Django/01/WSGI2.py", line 48, in main
conn, address = serversocket.accept()
File "D:\ProgramData\Anaconda3\lib\socket.py", line 212, in accept
fd, addr = self._accept()
BlockingIOError: [WinError 10035] 无法立即完成一个非阻止性套接字操作。

Process finished with exit code 1

输出为:

[WinError 10035] 无法立即完成一个非阻止性套接字操作。
(10035, '无法立即完成一个非阻止性套接字操作。', None, 10035, None)
11

分别对应:
print(e)
print(e.args)
print(errno.EAGAIN)

查看源代码,发现10035对应的错误是WSAEWOULDBLOCK,而EAGAIN的值是11

由此可得出结论:
这是因为在windows中,非阻塞模式抛出的异常是WSAEWOULDBLOCK,在linux环境下抛出的异常才是EAGAIN

测试:同样一份代码,在linux中能够正确执行(如果必要的话在开头加上#coding=utf-8)
抛出的错误为

[Errno 11] Resource temporarily unavailable
  • 点赞
  • 收藏
  • 分享
  • 文章举报
土豆大番薯 发布了8 篇原创文章 · 获赞 0 · 访问量 213 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: