tornado实现高性能无阻塞udp通信(1)——server端实现
来源:互联网 发布:unity3d真实地形制作 编辑:程序博客网 时间:2024/06/05 11:33
在高性能web架构中,往往需要在多个组件之间进行通信。很多人喜欢用HTTP协议进行通信(tornado官方也建议利用HTTP协议通信,将cpu占用高的计算任务交给后端服务器解决),但是在高并发的情况下TCP协议三次握手以及HTTP协议解析所带来的额外开销都是不容忽视的。其实在内网环境中网络环境相对稳定,所以我们完全可以利用UDP协议进行通信从而节约资源。下面就自己动手在tornado上实现无阻塞UDPSERVER。
先贴上UDPSERVER的代码:
class UDPServer(object): def __init__(self, io_loop=None): self.io_loop = io_loop self._sockets = {} # fd -> socket object self._pending_sockets = [] self._started = False def add_sockets(self, sockets): if self.io_loop is None: self.io_loop = IOLoop.instance() for sock in sockets: self._sockets[sock.fileno()] = sock add_accept_handler(sock, self._on_recive, io_loop=self.io_loop) def bind(self, port, address=None, family=socket.AF_UNSPEC, backlog=25): sockets = bind_sockets(port, address=address, family=family, backlog=backlog) if self._started: self.add_sockets(sockets) else: self._pending_sockets.extend(sockets) def start(self, num_processes=1): assert not self._started self._started = True if num_processes != 1: process.fork_processes(num_processes) sockets = self._pending_sockets self._pending_sockets = [] self.add_sockets(sockets) def stop(self): for fd, sock in self._sockets.iteritems(): self.io_loop.remove_handler(fd) sock.close() def _on_recive(self, data, address):print datadef bind_sockets(port, address=None, family=socket.AF_UNSPEC, backlog=25): sockets = [] if address == "": address = None flags = socket.AI_PASSIVE if hasattr(socket, "AI_ADDRCONFIG"): flags |= socket.AI_ADDRCONFIG for res in set(socket.getaddrinfo(address, port, family, socket.SOCK_DGRAM, 0, flags)): af, socktype, proto, canonname, sockaddr = res sock = socket.socket(af, socktype, proto) set_close_exec(sock.fileno()) if os.name != 'nt': sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) if af == socket.AF_INET6: if hasattr(socket, "IPPROTO_IPV6"): sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) sock.setblocking(0) sock.bind(sockaddr) sockets.append(sock) return socketsif hasattr(socket, 'AF_UNIX'): def bind_unix_socket(file, mode=0600, backlog=128): sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) set_close_exec(sock.fileno()) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setblocking(0) try: st = os.stat(file) except OSError, err: if err.errno != errno.ENOENT: raise else: if stat.S_ISSOCK(st.st_mode): os.remove(file) else: raise ValueError("File %s exists and is not a socket", file) sock.bind(file) os.chmod(file, mode) sock.listen(backlog) return sockdef add_accept_handler(sock, callback, io_loop=None): if io_loop is None: io_loop = IOLoop.instance() def accept_handler(fd, events): while True: try: data, address = sock.recvfrom(2500) except socket.error, e: if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN): return raise callback(data, address) io_loop.add_handler(sock.fileno(), accept_handler, IOLoop.READ)
代码结构与tornado官方TCPSERVER相似,由bind()方法添加监听地址,调用start()方法时将socket加入到监听队列,add_sockets()函数将生成的socket与相应的回调函数注册到ioloop中。一旦该socket可读之后便会调用该回调函数_on_recive(),在这里为了简单起见仅仅把收到数据输出出来。
下面写一个简单的UDPCLIENT来验证一下我们UDPSERVER
import socketaddress = ('127.0.0.1',8888)s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)msg = 'hehehe's.sendto(msg,address)s.close()
运行一遍看看结果:
左边是server端,可以看到server已经成功收到了client所发送的数据,server也就算是完工了。然而光有接受端还是不足以完成最开始的设想——利用udp实现告诉通信,还需要有一个异步udpclient,所以下一篇将会实现一个基于tornado的异步udpclient。
ps:csdn的编辑器实在不好用,本来想在代码中写注释方便读懂代码的,结果搞不定排版,等什么时候搞定这个编辑器之后再补上吧。
0 0
- tornado实现高性能无阻塞udp通信(1)——server端实现
- tornado实现高性能无阻塞udp通信(2)——实现异步udp客户端
- 利用IO完成端口实现高性能的UDP或TCP通信
- coro+io::select实现无阻塞server (测试server)
- 基于STM32的无协议栈实现UDP通信
- MPI非阻塞通信使用、性能分析与实现原理
- ACE+gSOAP实现高性能WebService Server
- Udp实现通信DEMO
- UDP通信C++实现
- python实现UDP通信
- C++实现UDP通信。。
- Java实现UDP通信
- Android实现UDP通信
- Qt-----实现Udp通信
- UDP通信实现
- socket实现UDP通信
- Java实现UDP通信
- C#实现UDP通信
- 统一资源管理与调度平台(系统)介绍
- 萬惡WITH為首之Javascript
- Ext JS 4 类体系(Class System)
- pat advanced 1071 Speech Patterns
- 用sed与awk整理文件名
- tornado实现高性能无阻塞udp通信(1)——server端实现
- #小脚本#把海词dict.cn的生词变成vce格式的测试题目
- HDU1172 猜数字
- spring容器原理之浅析
- LeetCode OJ:Multiply Strings
- 数学问题2,求Pow(x, n)
- 数学问题3:两个大数相乘
- Distinct Subsequences
- 函数的升级(下)