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

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

import socket
import errno
import threading
import time


# 多线程

EOL1 = b'\n\n'
EOL2 = b'\n\r\n'
body = '''Hello, world!

from the5fire 《Django 企业开发实战》

- 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

你可能感兴趣的:(windows和linux中socket的非阻塞模式error:EWOULDBLOCK 和EAGAIN)