A 77 lines echo server in clojure

    xiaoxiao2023-12-20  141

    写着玩的,不使用任何网络框架从头构建的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
    最新回复(0)