A 77 lines echo server in clojure

  写着玩的,不使用任何网络框架从头构建的echo server,总共77行。

 1 ;;Author:dennis (killme2008@gmail.com)
 2 (ns webee.network
 3    (:import (java.nio.channels Selector SocketChannel ServerSocketChannel SelectionKey)
 4             (java.net InetSocketAddress)
 5             (java.nio ByteBuffer)
 6             (java.io IOException)))
 7 
 8 (declare reactor process-keys accept-channel read-channel)
 9 
10 (defn bind [^InetSocketAddress addr fcol]
11   (let [selector (Selector/open)
12         ssc      (ServerSocketChannel/open)
13         ag  (agent selector)]
14     (do
15       (.configureBlocking ssc false)
16       (.. ssc (socket) (bind addr 1000))
17       (.register ssc selector SelectionKey/OP_ACCEPT)
18       (send-off ag reactor fcol)
19       ag)))
20 
21 (defn- reactor [^Selector selector fcol]
22   (let [sel (. selector select 1000)]
23     (if (> sel 0)
24       (let [sks (. selector selectedKeys)]
25         (do 
26           (dorun (map (partial process-keys selector fcol) sks))
27           (.clear sks))))
28     (recur selector fcol)))
29   
30 (defn- process-keys [^Selector selector ^SelectionKey fcol sk]
31   (try
32     (cond 
33       (.isAcceptable sk) (accept-channel sk  selector fcol)
34       (.isReadable sk) (read-channel sk selector fcol)    
35     )
36     (catch Throwable e (.printStackTrace e))))
37 
38 (defn- accept-channel [^SelectionKey sk ^Selector selector fcol]
39    (let [^ServerSocketChannel ssc (. sk channel)
40          ^SocketChannel sc (. ssc accept)
41          created-fn (:created fcol)]
42      (do 
43        (.configureBlocking sc false) 
44        (.register sc selector SelectionKey/OP_READ)
45        (if created-fn
46          (created-fn sc)))))
47 
48 (defn- close-channel [^SelectionKey sk ^SocketChannel sc fcol]
49   (let [closed-fn (:closed fcol)]
50     (do 
51        (.close sc)
52        (.cancel sk)
53        (if closed-fn 
54          (closed-fn sc)))))
55      
56 (defn-  read-channel [^SelectionKey sk ^Selector selector fcol]
57    (let [^SocketChannel sc (. sk channel)
58          ^ByteBuffer buf (ByteBuffer/allocate 4096)
59          read-fn (:read fcol)]
60      (try
61        (let [n (.read sc buf)]
62          (if (< n 0)
63              (close-channel sk sc fcol)
64              (do (.flip buf)
65                  (if read-fn
66                    (read-fn sc buf)))))
67        (catch IOException e
68          (close-channel sk sc fcol)))))
69 
70 ;;Bind a tcp server to localhost at port 8080,you can telnet it.
71 (def server
72   (bind 
73     (new InetSocketAddress 8080)
74     {:read #(.write %1 %2)
75      :created #(println "Accepted from" (.. % (socket) (getRemoteSocketAddress)))
76      :closed  #(println "Disconnected from" (.. % (socket) (getRemoteSocketAddress)))
77      }))

文章转自庄周梦蝶  ,原文发布时间 2011-01-15

时间: 2024-10-29 08:37:09

A 77 lines echo server in clojure的相关文章

ACE Reactor的Echo Server

相对完整的修改版本   1 /************************************************************************   2 * @file: echo.cpp                                                      3 * @author: dennis  4 * @revise: dennis <killme2008@gmail.com> http://www.blogjava.ne

用winsock和iocp api打造一个echo server

这里用到了一些技术点,比如平台调用.反射,多线程等,当然还有iocp和winsock的api,及 GCHandle,SafeHandle,Marshal类的使用等,不过相当多的东西,我上篇帖子讲的都很细了,如果对 winsock api不了解可以查阅MSDN.也没什么技术难点,说几个细节的地方吧. 1..net自带的System.Threading.NativeOverlapped类型是完全按照win32的Overlapped结构实现的, 因为我们在WSASend和WSAReceive的时候想要

libevent echo server example

libevent is an API that allows you to easily write non-blocking networking apps. It abstracts the differences between poll, select, kqueue, epoll and /dev/poll allowing you to automatically take advantage of the best mechanism provided by the OS you

基于Sql Server 2008的分布式数据库的实践(五)

原文 基于Sql Server 2008的分布式数据库的实践(五) 程序设计 ----------------------------------------------------------------------------------------------------------------- Index.php----选择界面,并且实现学生和老师的注册 sql_ini.php----SQL配置文件 ./student----学生的后台 ./admin----老师的后台 -------

Acronis Server备份Linux系统

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://chenguang.blog.51cto.com/350944/1344521 Acronis Server备份Linux系统 前段时间用Acronis Disk Director Suite解决了Thinkpad笔记本在win7的分区问题(http://chenguang.blog.51cto.com/350944/180687),今天这篇博文为大家展示如何使用Acronis

python实现的udp协议Server和Client代码实例_python

直接上代码:Server端: 复制代码 代码如下:  #!/usr/bin/env python # UDP Echo Server -  udpserver.py import socket, traceback  host = '' port = 54321  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((

运维经验分享(七)-- Linux Shell之ChatterServer服务控制脚本第三次优化

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dgd2010.blog.51cto.com/1539422/1677214 运维经验分享作为一个专题,目前共7篇文章 <运维经验分享(一)-- Linux Shell之ChatterServer服务控制脚本> <运维经验分享(二)-- Linux Shell之ChatterServer服务控制脚本二次优化> <运维经验分享(三)-- 解决Ubuntu下cro

不能连接数据库-weblogic部署web项目报:连接数据库失败,请检查系统数据库连接配置

问题描述 weblogic部署web项目报:连接数据库失败,请检查系统数据库连接配置 2C youngtop.sys.exception.YoungtopException: 系统错误:youngtop.sys.exception.YoungtopException: 数据库操作错误:errcode=17002sqlstate=08006java.sql.SQLRecoverableException: IO 错误: Software caused connection abort: socke

Shell脚本实现的基于SVN的代码提交量统计工具

  这篇文章主要介绍了Shell脚本实现的基于SVN的代码提交量统计工具,本文直接给出实现脚本代码,需要的朋友可以参考下 最近没啥事,就用bash写了一个基于svn的代码统计小工具. 可以指定统计的目录,默认递归统计子目录. 目前还没有屏蔽指定目录的功能.哈 代码比较粗糙.不过先晒出来. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 3