如何将pythontcpudp服务器框架改写为一个长尾词的?

2026-04-02 01:391阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1078个文字,预计阅读时间需要5分钟。

如何将pythontcpudp服务器框架改写为一个长尾词的?

事件驱动IO本质上是将基本的IO操作(例如读写)转化为程序需要处理的事件。例如,当数据在某个socket上被接收后,它会触发一个receive事件,从而将基本的I/O操作转化为程序需要处理的事件。

事件驱动IO本质上来讲就是将基本IO操作(比如读和写)转化为你程序需要处理的事件。例如当数据在某个socket上被接受后它会转换成一个receive

事件驱动I/O本质上来讲就是将基本I/O操作(比如读和写)转化为你程序需要处理的事件。 例如当数据在某个socket上被接受后它会转换成一个 receive 事件然后被你定义的回调方法或函数来处理。 作为一个可能的起始点一个事件驱动的框架可能会以一个实现了一系列基本事件处理器方法的基类开始

class EventHandler:

def fileno(self):

Return the associated file descriptor

raise NotImplemented(must implement)

def wants_to_receive(self):

Return True if receiving is allowed

return False

def handle_receive(self):

Perform the receive operation

pass

def wants_to_send(self):

Return True if sending is requested

return False

def handle_send(self):

Send outgoing data

pass

这个类的实例作为插件被放入类似下面这样的事件循环中

import select

def event_loop(handlers):

while True:

wants_recv [h for h in handlers if h.wants_to_receive()]

wants_send [h for h in handlers if h.wants_to_send()]

can_recv, can_send, _ select.select(wants_recv, wants_send, [])

for h in can_recv:

h.handle_receive()

for h in can_send:

h.handle_send()

事件循环的关键部分是 select() 调用它会不断轮询文件描述符从而激活它。 在调用 select() 之前事件循环会询问所有的处理器来决定哪一个想接受或发生。 然后它将结果列表提供给 select() 。然后 select() 返回准备接受或发送的对象组成的列表。 然后相应的 handle_receive() 或 handle_send() 方法被触发。

编写应用程序的时候EventHandler 的实例会被创建。例如下面是两个简单的基于UDP网络服务的处理器例子

import socket

import time

class UDPServer(EventHandler):

def __init__(self, address):

self.sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

self.sock.bind(address)

def fileno(self):

return self.sock.fileno()

def wants_to_receive(self):

return True

class UDPTimeServer(UDPServer):

def handle_receive(self):

msg, addr self.sock.recvfrom(1)

self.sock.sendto(time.ctime().encode(ascii), addr)

class UDPEchoServer(UDPServer):

def handle_receive(self):

msg, addr self.sock.recvfrom(8192)

self.sock.sendto(msg, addr)

if __name__ __main__:

handlers [ UDPTimeServer((,14000)), UDPEchoServer((,15000)) ]

event_loop(handlers)

测试这段代码试着从另外一个Python解释器连接它

如何将pythontcpudp服务器框架改写为一个长尾词的?

>>> from socket import *

>>> s socket(AF_INET, SOCK_DGRAM)

>>> s.sendto(b,(localhost,14000))

0

>>> s.recvfrom(128)

(bTue Sep 18 14:29:23 2012, (127.0.0.1, 14000))

>>> s.sendto(bHello,(localhost,15000))

5

>>> s.recvfrom(128)

(bHello, (127.0.0.1, 15000))

>>>

实现一个TCP服务器会更加复杂一点因为每一个客户端都要初始化一个新的处理器对象。 下面是一个TCP应答客户端例子

class TCPServer(EventHandler):

def __init__(self, address, client_handler, handler_list):

self.sock socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

self.sock.bind(address)

self.sock.listen(1)

self.client_handler client_handler

self.handler_list handler_list

def fileno(self):

return self.sock.fileno()

def wants_to_receive(self):

return True

def handle_receive(self):

client, addr self.sock.accept()

# Add the client to the event loops handler list

self.handler_list.append(self.client_handler(client, self.handler_list))

class TCPClient(EventHandler):

def __init__(self, sock, handler_list):

self.sock sock

self.handler_list handler_list

self.outgoing bytearray()

def fileno(self):

return self.sock.fileno()

def close(self):

self.sock.close()

# Remove myself from the event loops handler list

self.handler_list.remove(self)

def wants_to_send(self):

return True if self.outgoing else False

def handle_send(self):

nsent self.sock.send(self.outgoing)

self.outgoing self.outgoing[nsent:]

class TCPEchoClient(TCPClient):

def wants_to_receive(self):

return True

def handle_receive(self):

data self.sock.recv(8192)

if not data:

self.close()

else:

self.outgoing.extend(data)

if __name__ __main__:

handlers []

handlers.append(TCPServer((,16000), TCPEchoClient, handlers))

event_loop(handlers)

TCP例子的关键点是从处理器中列表增加和删除客户端的操作。 对每一个连接一个新的处理器被创建并加到列表中。当连接被关闭后每个客户端负责将其从列表中删除。 如果你运行程序并试着用Telnet或类似工具连接它会将你发送的消息回显给你。并且它能很轻松的处理多客户端连接。

本文共计1078个文字,预计阅读时间需要5分钟。

如何将pythontcpudp服务器框架改写为一个长尾词的?

事件驱动IO本质上是将基本的IO操作(例如读写)转化为程序需要处理的事件。例如,当数据在某个socket上被接收后,它会触发一个receive事件,从而将基本的I/O操作转化为程序需要处理的事件。

事件驱动IO本质上来讲就是将基本IO操作(比如读和写)转化为你程序需要处理的事件。例如当数据在某个socket上被接受后它会转换成一个receive

事件驱动I/O本质上来讲就是将基本I/O操作(比如读和写)转化为你程序需要处理的事件。 例如当数据在某个socket上被接受后它会转换成一个 receive 事件然后被你定义的回调方法或函数来处理。 作为一个可能的起始点一个事件驱动的框架可能会以一个实现了一系列基本事件处理器方法的基类开始

class EventHandler:

def fileno(self):

Return the associated file descriptor

raise NotImplemented(must implement)

def wants_to_receive(self):

Return True if receiving is allowed

return False

def handle_receive(self):

Perform the receive operation

pass

def wants_to_send(self):

Return True if sending is requested

return False

def handle_send(self):

Send outgoing data

pass

这个类的实例作为插件被放入类似下面这样的事件循环中

import select

def event_loop(handlers):

while True:

wants_recv [h for h in handlers if h.wants_to_receive()]

wants_send [h for h in handlers if h.wants_to_send()]

can_recv, can_send, _ select.select(wants_recv, wants_send, [])

for h in can_recv:

h.handle_receive()

for h in can_send:

h.handle_send()

事件循环的关键部分是 select() 调用它会不断轮询文件描述符从而激活它。 在调用 select() 之前事件循环会询问所有的处理器来决定哪一个想接受或发生。 然后它将结果列表提供给 select() 。然后 select() 返回准备接受或发送的对象组成的列表。 然后相应的 handle_receive() 或 handle_send() 方法被触发。

编写应用程序的时候EventHandler 的实例会被创建。例如下面是两个简单的基于UDP网络服务的处理器例子

import socket

import time

class UDPServer(EventHandler):

def __init__(self, address):

self.sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

self.sock.bind(address)

def fileno(self):

return self.sock.fileno()

def wants_to_receive(self):

return True

class UDPTimeServer(UDPServer):

def handle_receive(self):

msg, addr self.sock.recvfrom(1)

self.sock.sendto(time.ctime().encode(ascii), addr)

class UDPEchoServer(UDPServer):

def handle_receive(self):

msg, addr self.sock.recvfrom(8192)

self.sock.sendto(msg, addr)

if __name__ __main__:

handlers [ UDPTimeServer((,14000)), UDPEchoServer((,15000)) ]

event_loop(handlers)

测试这段代码试着从另外一个Python解释器连接它

如何将pythontcpudp服务器框架改写为一个长尾词的?

>>> from socket import *

>>> s socket(AF_INET, SOCK_DGRAM)

>>> s.sendto(b,(localhost,14000))

0

>>> s.recvfrom(128)

(bTue Sep 18 14:29:23 2012, (127.0.0.1, 14000))

>>> s.sendto(bHello,(localhost,15000))

5

>>> s.recvfrom(128)

(bHello, (127.0.0.1, 15000))

>>>

实现一个TCP服务器会更加复杂一点因为每一个客户端都要初始化一个新的处理器对象。 下面是一个TCP应答客户端例子

class TCPServer(EventHandler):

def __init__(self, address, client_handler, handler_list):

self.sock socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

self.sock.bind(address)

self.sock.listen(1)

self.client_handler client_handler

self.handler_list handler_list

def fileno(self):

return self.sock.fileno()

def wants_to_receive(self):

return True

def handle_receive(self):

client, addr self.sock.accept()

# Add the client to the event loops handler list

self.handler_list.append(self.client_handler(client, self.handler_list))

class TCPClient(EventHandler):

def __init__(self, sock, handler_list):

self.sock sock

self.handler_list handler_list

self.outgoing bytearray()

def fileno(self):

return self.sock.fileno()

def close(self):

self.sock.close()

# Remove myself from the event loops handler list

self.handler_list.remove(self)

def wants_to_send(self):

return True if self.outgoing else False

def handle_send(self):

nsent self.sock.send(self.outgoing)

self.outgoing self.outgoing[nsent:]

class TCPEchoClient(TCPClient):

def wants_to_receive(self):

return True

def handle_receive(self):

data self.sock.recv(8192)

if not data:

self.close()

else:

self.outgoing.extend(data)

if __name__ __main__:

handlers []

handlers.append(TCPServer((,16000), TCPEchoClient, handlers))

event_loop(handlers)

TCP例子的关键点是从处理器中列表增加和删除客户端的操作。 对每一个连接一个新的处理器被创建并加到列表中。当连接被关闭后每个客户端负责将其从列表中删除。 如果你运行程序并试着用Telnet或类似工具连接它会将你发送的消息回显给你。并且它能很轻松的处理多客户端连接。