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
目录
相关文章
java.net.SocketException: Unexpected end of file from server
java.net.SocketException: Unexpected end of file from server
|
8月前
|
SQL
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
69 0
|
NoSQL PHP Redis
Laravel Predis Error while reading line from the server.
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_21158419/article/details/53610445 问题...
3974 0
|
4月前
|
Oracle Java 关系型数据库
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
如果遇到"exec format error"问题,文章建议先检查Linux操作系统是32位还是64位,并确保安装了与系统匹配的JDK版本。如果系统是64位的,但出现了错误,可能是因为下载了错误的JDK版本。文章提供了一个链接,指向Oracle官网上的JDK 17 Linux版本下载页面,并附有截图说明。
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
|
7月前
|
Unix Docker 容器
使用docker 启动naocs 报错出现:standard_init_linux.go:241: exec user process caused "exec format error"
```markdown Error in Docker container startup: &quot;standard_init_linux.go:241: exec user process caused \&quot;exec format error\&quot;&quot;. Occurred at 2024-06-29 09:26:19.910, followed by a failed hook with a syslog delivery error at 09:27:20.193. Seeking solutions from experts. ```
|
Python
python报错——check_hostname requires server_hostname
python报错——check_hostname requires server_hostname
316 0
python报错——check_hostname requires server_hostname
Python遇到的坑--ValueError: check_hostname requires server_hostname
原因:这个其实跟选用的python版本的关系不大,主要原因是因为每次使用 pip install 命令下载插件的时候,下载的都是最新的版本,比如下载requests插件,它会自动的将依赖的urllib3这个插件也安装,然后依赖的插件版本太高,就导致了这个报错的问题。
Python遇到的坑--ValueError: check_hostname requires server_hostname
|
存储
通过echo_server带你入门brpc!
前文我们介绍过如何编译安装brpc(brpc最新安装上手指南),今天通过echo_server来介绍一下brpc的基本使用方法与细节。
900 0
|
安全 程序员 C++
《gen_server.erl源码》
erlang程序员研究OTP,如同C++程序员研究STL一样重要。
《gen_server.erl源码》
|
开发工具 分布式计算 Hadoop
hadoop_异常_01_ Unable to determine address of the host-falling back to "localhost" address java.net.UnknownHostException: rayner
一、异常现象 安装好hadoop之后,执行格式化namenode命令时,抛出以下异常: 18/03/21 21:02:10 WARN net.DNS: Unable to determine local hostname -falling back to "localhost" java.
1742 0