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

文件对象接口列表[ ]

Eursia socket 1.jpg

  • 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

参考来源[ ]

http://code.google.com/p/eurasia/wiki/eurasia_3_1_userguide

模板:Eurasia