Using elisp to debug network applications

2019-02-09

Categories: notes Tags: Emacs elisp network

Exploring network capabilities of Unix-like systems, I found it very convenient to use Emacs Lisp to quickly test my C code. There is useful command in projectile-mode projectile-run-ielm that runs new interactive elisp shell session for current project.

Here is some elisp snippets that I use nowadays.

Process filter function

A process filter function is a function that processes the standard output from the associated process. Here is an example function, which convert \0 characters widely used to separate messages, to newlines to make output more human-readable:

(defun listen-filter (proc str)
         (when (buffer-live-p (process-buffer proc))
         (with-current-buffer (process-buffer proc)
           (let ((moving (= (point) (process-mark proc))))
             (save-excursion
               (goto-char (process-mark proc))
               (insert (replace-regexp-in-string"" "\n" str))
               (set-marker (process-mark proc) (point)))
             (if moving (goto-char (process-mark proc)))))))

Process buffer

A process buffer is an ordinary Emacs buffer that stores the output from the process and can be used to kill it’s process.

I want to see the last appended lines *lsn* buffer which contains process output:

(defun tail-f-lsn()
  (let ((msg-window (get-buffer-window "*lsn*")))
    (if msg-window
        (with-current-buffer (window-buffer msg-window)
          (set-window-point msg-window (point-max))))))

Make the *lsn* buffer stick to the end:

(add-hook 'post-command-hook 'tail-f-lsn)

Create TCP client

Finally, create simple TCP client with following command:

(make-network-process :name "cl"
                      :host "10.0.0.2"
                      :service 5000
                      :family 'ipv4
                      :filter 'listen-filter
                      :buffer "*lsn*")

Working with client process

Monitor process:

(process-status (get-process "cl"))

Kill process:

(delete-process "cl")

Send data:

(process-send-string "cl" "test\0")

See also

  1. so: Simple tcp client example
  2. alchemist-server.el which provides some interesting networking samples in ELisp.