socket使用epoll的一个问题
代码如下,使用epoll创建的一个异步socket的服务器(代码基本为http://scotdoyle.com/python-epoll-howto....中的Example 3,只不过加了一些日志打印)
import os
import select
import socket
import logging
import time
eventmasks = {
"EPOLLERR": 8,
"EPOLLET": 2147483648,
"EPOLLHUP": 16,
"EPOLLIN": 1,
"EPOLLMSG": 1024,
"EPOLLONESHOT": 1073741824,
"EPOLLOUT": 4,
"EPOLLPRI": 2,
"EPOLLRDBAND": 128,
"EPOLLRDNORM": 64,
"EPOLLWRBAND": 512,
"EPOLLWRNORM": 256,
}
eventmask_ids = {
1: "EPOLLIN",
2: "EPOLLPRI",
4: "EPOLLOUT",
8: "EPOLLERR",
16: "EPOLLHUP",
64: "EPOLLRDNORM",
128: "EPOLLRDBAND",
256: "EPOLLWRNORM",
512: "EPOLLWRBAND",
1024: "EPOLLMSG",
1073741824: "EPOLLONESHOT",
2147483648: "EPOLLET"
}
formatter = "[%(asctime)-15s] [%(levelname)s] %(message)s"
logging.basicConfig(level=logging.DEBUG, format=formatter)
EOL1 = b'\n\n'
EOL2 = b'\n\r\n'
response = b'HTTP/1.0 200 OK\r\nDate: %s\r\n'
response += b'Content-Type: text/plain\r\nContent-Length: %s\r\n\r\n%s'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("0.0.0.0", 9999))
s.listen(1024)
s.setblocking(0)
epoll = select.epoll()
s_fileno = s.fileno()
epoll.register(s, select.EPOLLIN)
try:
connections = {}
request_data = {}
response_data = {}
actions = {}
while True:
events = epoll.poll(24)
for fileno, event in events:
logging.debug(">>>>>" * 12)
logging.debug("Event file number is %s and event mask is %s(%s)", fileno, bin(event), eventmask_ids.get(event, 0))
if fileno == s_fileno:
# create new socket connection from client
conn, address = s.accept()
conn.setblocking(0)
c_fileno = conn.fileno()
logging.debug("Connection from client%s file number is %s", address, c_fileno)
epoll.register(c_fileno, select.EPOLLIN)
connections[c_fileno] = conn
request_data[c_fileno] = b""
response_data[c_fileno] = b""
actions[c_fileno] = []
elif event & select.EPOLLIN:
logging.info("Recive data epoll socket file number is %s, actions are: %s", fileno, actions[fileno])
actions[fileno].append("recv")
# data come in
data_piece = connections[fileno].recv(1024)
# logging.debug("Recive client data piece is:\n%s", data_piece)
request_data[fileno] += data_piece
if EOL1 in request_data[fileno] or EOL2 in request_data[fileno]:
resp = str(os.environ)
response_data[fileno] = response % (time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime()), len(resp), resp)
epoll.modify(fileno, select.EPOLLOUT)
# logging.debug("Data from client is: \n%s", request_data[fileno])
if request_data[fileno] == b"":
logging.error("Recive empty data")
epoll.unregister(fileno)
connections[fileno].close()
elif event & select.EPOLLOUT:
actions[fileno].append("send")
# send data to client
# logging.warn("Full connections are %s", connections)
logging.info("Send data epoll socket file number is %s", fileno)
send_bytes = connections[fileno].send(response_data[fileno])
response_data[fileno] = response_data[fileno][send_bytes:]
if len(response_data[fileno]) == 0:
actions[fileno].append("shutdown")
epoll.modify(fileno, 0)
logging.info("I will shutdown socket(%s), actions are: %s", connections[fileno], actions[fileno])
connections[fileno].shutdown(socket.SHUT_RDWR)
del response_data[fileno]
elif event & select.EPOLLHUP:
actions[fileno].append("close")
logging.info("Close data epoll scoket file number is %s, actions are: %s", fileno, actions[fileno])
# connection close by client
epoll.unregister(fileno)
connections[fileno].close()
del connections[fileno]
del actions[fileno]
logging.debug("<<<<<" * 12)
finally:
logging.error("Exception happend, closing server...")
epoll.unregister(s_fileno)
epoll.close()
s.close()
运行以后可以访问,但使用压测软件测试会抛出[Errno 107] Transport endpoint is not connected
这样的异常
压测命令为siege -c 100 -i -b --delay=0 --time=1s http://172.17.0.1:9999
,而压测结果显示可用100%
** SIEGE 3.0.5
** Preparing 100 concurrent users for battle.
The server is now under siege...
Lifting the server siege... done.Transactions: 868 hits
Availability: 100.00 %
Elapsed time: 0.93 secs
Data transferred: 1.49 MB
Response time: 0.09 secs
Transaction rate: 933.33 trans/sec
Throughput: 1.60 MB/sec
Concurrency: 87.33
Successful transactions: 868
Failed transactions: 0
Longest transaction: 0.12
Shortest transaction: 0.01
关于[Errno 107] Transport endpoint is not connected这个错误,应该是tcp连接并没有建立,但是,我上面的代码和日志显示连接已经建立,为什么还会抛出这个异常
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论