Eurasia/文件及socket
查看全部词条命名空间:Main
模板: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
