A simple elisp TCP echo server.


For Emacs22 or later (requires server-socket).

(defvar echo-server-port 10000
    "port of the echo server")
(defvar echo-server-clients '() 
    "alist where KEY is a client process and VALUE is the string")

(defun echo-server-start nil
    "starts an emacs echo server"
    (unless (process-status "echo-server")
      (make-network-process :name "echo-server" :buffer "*echo-server*" :family 'ipv4 :service echo-server-port :sentinel 'echo-server-sentinel :filter 'echo-server-filter :server 't) 
      (setq echo-server-clients '())
  (defun echo-server-stop nil
    "stop an emacs echo server"
    (while  echo-server-clients
      (delete-process (car (car echo-server-clients)))
      (setq echo-server-clients (cdr echo-server-clients)))
    (delete-process "echo-server")
  (defun echo-server-filter (proc string)   
    (let ((pending (assoc proc echo-server-clients))
      ;;create entry if required
      (unless pending
        (setq echo-server-clients (cons (cons proc "") echo-server-clients))
        (setq pending  (assoc proc echo-server-clients)))
      (setq message (concat (cdr pending) string))
      (while (setq index (string-match "\n" message))
        (setq index (1+ index))
        (process-send-string proc (substring message 0 index))
        (echo-server-log  (substring message 0 index) proc)
        (setq message (substring message index)))
      (setcdr pending message))
  (defun echo-server-sentinel (proc msg)
   (when (string= msg "connection broken by remote peer\n")
    (setq echo-server-clients (assq-delete-all proc echo-server-clients))
    (echo-server-log (format "client %s has quit" proc))))
  ;;from server.el
  (defun echo-server-log (string &optional client)
      "If a *echo-server* buffer exists, write STRING to it for logging purposes."
    (if (get-buffer "*echo-server*")
        (with-current-buffer "*echo-server*"
          (goto-char (point-max))
          (insert (current-time-string)
                  (if client (format " %s:" client) " ")
          (or (bolp) (newline)))))


Is there a better way to accept outputs than the above lame 1 second timer?

Cool! What is it? 😊 – MathiasDahl

It echoes every line, try telnet localhost 10000 – PierreGaston

In other words, this is a way to communicate with emacs using telnet? Well, that could be handy sometimes. – MathiasDahl

Well, it’s a standard protocol – see RFC 862, or RFC 862 in SpanishPierreGaston

How do you make an echo-socket? – Naveen

(setq client-process
     (open-network-stream "echo-client"
                          "*echo-client*" "localhost" echo-server-port))
      (process-send-string client-process "hello world\n")

Thanks to PierreGaston