玩一会epoll,果然好玩
代码语言:javascript复制import select
import socket
import time
def svc():
EOL1 = b'nn'
EOL2 = b'nrn'
response = b'HTTP/1.0 200 OKrnDate: Mon, 1 Jan 1996 01:01:01 GMTrn'
response = b'Content-Type: text/plainrnContent-Length: 13rnrn'
response = b'Hello, world!'
# 创建套接字对象并绑定监听端口
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(('0.0.0.0', 8080))
serversocket.listen(1)
serversocket.setblocking(0)
# 创建epoll对象,并注册socket对象的 epoll可读事件
epoll = select.epoll()
epoll.register(serversocket.fileno(), select.EPOLLIN|select.EPOLLET)
try:
connections = {}
requests = {}
responses = {}
while True:
time.sleep(0.1)
# 主循环,epoll的系统调用,一旦有网络IO事件发生,poll调用返回。这是和select系统调用的关键区别
events = epoll.poll(1)
# 通过事件通知获得监听的文件描述符,进而处理
for fileno, event in events:
print("event {}".format(event))
# 注册监听的socket对象可读,获取连接,并注册连接的可读事件
if fileno == serversocket.fileno():
print("start accept fileno {}".format(fileno))
connection, address = serversocket.accept()
connection.setblocking(0)
epoll.register(connection.fileno(), select.EPOLLIN|select.EPOLLET)
connections[connection.fileno()] = connection
requests[connection.fileno()] = b''
responses[connection.fileno()] = response
elif event & select.EPOLLIN:
# 连接对象可读,处理客户端发生的信息,并注册连接对象可写
msg = connections[fileno].recv(1)
print("fileno {}, rec: {}".format(fileno, msg))
requests[fileno] = msg
if msg == b'':
epoll.modify(fileno, 0)
connections[fileno].shutdown(socket.SHUT_RDWR)
if EOL1 in requests[fileno] or EOL2 in requests[fileno]:
epoll.modify(fileno, select.EPOLLOUT)
print('-' * 40 'n' requests[fileno].decode()[:-2])
elif event & select.EPOLLOUT:
print("select.EPOLLOUT start")
# 连接对象可写事件发生,发送数据到客户端
byteswritten = connections[fileno].send(responses[fileno])
responses[fileno] = responses[fileno][byteswritten:]
if len(responses[fileno]) == 0:
epoll.modify(fileno, 0)
connections[fileno].shutdown(socket.SHUT_RDWR)
elif event & select.EPOLLHUP or event & (select.EPOLLIN
| select.EPOLLRDHUP):
print("select.EPOLLHUP start")
epoll.unregister(fileno)
connections[fileno].close()
del connections[fileno]
finally:
epoll.unregister(serversocket.fileno())
epoll.close()
serversocket.close()
serversocket.close()
def cli():
host = "localhost"
port = 8164
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
try:
while 1:
msg = input()
if msg == 'close':
s.close()
return
s.send(msg.encode())
# print(s.recv(1024))
finally:
s.close()
# svc()
# cli()
import sys
print(sys.argv)
if sys.argv[1] == 'cli':
cli()
else:
svc()