Eurasia/文件及socket
来自站长百科
模板:Eurasia top 框架提供了专门的文件 IO 接口,用来提高系统性能。而 socket 则是一种特殊的文件
文件[ ]
使用 core.file(fileno) 接口对已打开的文件描述符(fileno)进行高效操作。
#!/usr/bin/python2.6 #-*- coding: utf-8 -*- # epoll 不支持本地磁盘文件 patch 成 poll from eurasia.pyev import * mainloop = default_loop(EVBACKEND_POLL).loop import os, sys from eurasia import core from traceback import print_exc from eurasia.web import httpserver # 打开调试输出 core.excepthook = lambda: print_exc(file=sys.stderr) def handler(httpfile): httpfile.start_response('200 OK') # 文件读取 fileno = os.open('test.txt', os.O_RDONLY|os.O_NONBLOCK) f = core.file(fileno) s = f.read() os.close(fileno) httpfile.sendall(s) httpfile.close() httpd = httpserver(':8080', handler) httpd.start() mainloop()
- eurasia 默认使用的 epoll 等后端无法处理磁盘文件,需要 patch 成 select 或 poll
- 使用 os.open('test.txt', os.O_NONBLOCK|...) 和 os.close(fileno) 来打开和关闭文件
在 unix 下,管道、socket、设备等等都是文件,都可以使用 core.file() 接口。
from os import popen from eurasia.core import file ... lsdir = popen('ls -alh') fd = file(lsdir.fileno()) files = fd.readlines() ... mainloop()
- epoll 支持管道,无须 patch
文件对象接口列表[ ]
- file.recv() 不能和 file.read()、file.readline() 混用
- file.send() 不能和 file.sendall() 混用
socket[ ]
使用框架自带的 socket2 以替代 socket 标准库。
# from socket import socket, AF_INET, SOCK_STREAM from eurasia.socket2 import socket, AF_INET, SOCK_STREAM ... sock = socket(AF_INET, SOCK_STREAM) sock.connect(('www.google.com', 80)) sock.sendall('GET / HTTP/1.0\r\n\r\n') data = sock.read() ...
- socket2.socket 不仅是 socket 也是 file 对象,可以使用 read()/readline()/sendall() 等接口
- socket2.socket 对象用于创建客户端 socket
- 出于性能考虑应总是使用 socket2
通过 socket2.install() 替换标准库。
from eurasia import socket2 socket2.install() # 这时标准库 socket 模块已经变成 socket2 import urllib # urllib 将使用 socket2 模块 ... fd = urllib.urlopen('http://www.google.com/') data = fd.read() ...
TCP服务器[ ]
使用 server(addr, handler) 创建标准的 tcp 服务器。
这是一个 echo 服务。
# 文件名:test.py from eurasia.server import server, mainloop def handler(sock, addr, serv): data = sock.readline() while data.strip() != 'quit': sock.sendall(data) data = sock.readline() sock.close() tcpd = server(':8080', handler) tcpd.start() mainloop()
- handler 接受的三个参数,分别是:
- 客户端连接 sock,socket2.socket 对象
- 客户端地址 addr,tuple 类型,比如 ('192.168.0.101', 20000)
- 服务器对象 serv,也就是 server 本身
执行脚本,启动服务器。
$/usr/bin/python2 test.py
使用 telnet 连接到服务器,进行测试(输入 quit 退出测试)。
$telnet 127.0.0.1 8080