Emacs Lisp 程序可以打开流(TCP)与数据报(UDP)网络连接(see 数据报),与本机或其他机器上的进程通信。
Lisp 对网络连接的处理与子进程十分相似,均使用进程对象表示。但与之通信的进程并非 Emacs 的子进程,没有进程 ID,你也无法终止它或向其发送信号。你只能收发数据。delete-process 会关闭连接,但不会终止对端程序;该程序需自行决定如何处理连接关闭。
Lisp 程序可以通过创建网络服务器监听连接。网络服务器同样由一类进程对象表示,但与网络连接不同,网络服务器本身从不传输数据。当它收到连接请求时,会创建一个新的网络连接以代表刚建立的连接。(该网络连接会从服务器继承部分信息,包括进程属性表。)之后网络服务器继续监听更多连接请求。
网络连接与服务器通过调用 make-network-process 创建,参数为关键字/值对列表,例如使用 :server t 创建服务器进程,或 :type 'datagram 创建数据报连接。See 底层网络访问 查看详情。你也可以使用下文介绍的 open-network-stream 函数。
为区分不同类型的进程,process-type 函数对网络连接或服务器返回符号 network,对串口连接返回 serial,对管道连接返回 pipe,对真实子进程返回 real。
process-status 函数对网络连接返回 open、closed、connect、stop 或 failed。对网络服务器,状态始终为 listen。除 stop 外,这些值均不会出现在真实子进程中。See 进程信息。
你可以通过调用 stop-process 与 continue-process 暂停或恢复网络进程的运行。对服务器进程,暂停意味着不再接受新连接。(最多会缓存 5 个连接请求,待服务器恢复后处理;你可以提高该上限,除非受操作系统限制—详见 make-network-process 的 :server 关键字,make-network-process。)对网络流连接,暂停意味着不处理输入(到达的输入会等待连接恢复)。对数据报连接,部分数据包可能被缓存,但输入可能丢失。你可以使用 process-command 判断网络连接或服务器是否暂停;非 nil 表示已暂停。
Emacs 可以创建加密网络连接,内置支持 GnuTLS 传输层安全库;详见 GnuTLS 项目页面。若你的 Emacs 编译时启用了 GnuTLS 支持,则函数 gnutls-available-p 会被定义并返回非 nil。更多详情参见 see Overview in The Emacs-GnuTLS manual。open-network-stream 函数可根据可用支持透明处理加密连接的创建细节。
该函数打开一个 TCP 连接(支持可选加密),返回代表该连接的进程对象。
参数 name 指定进程对象的名称。会根据需要自动修改以保证唯一。
参数 buffer 是与该连接关联的缓冲区。连接的输出会插入该缓冲区,除非你指定了自定义过滤器函数处理输出。若 buffer 为 nil,表示该连接不关联任何缓冲区。
参数 host 与 service 指定连接目标;host 为主机名(字符串),service 为已定义的网络服务名(字符串)或端口号(整数如 80,或整数字符串如 "80")。
剩余参数 parameters 为关键字/值对,主要与加密连接相关:
:nowait boolean若非 nil,尝试建立异步连接。
:noquery query-flag将进程查询标志初始化为 query-flag。See 退出前询问确认。
:coding coding用于设置网络进程使用的编码系统,优先于绑定 coding-system-for-read 或 coding-system-for-write。See make-network-process 查看详情。
:type type连接类型。可选值:
plain普通未加密连接。
tlssslTLS(传输层安全)连接。
nilnetwork先建立普通连接,若提供了参数 ‘:success’ 与 ‘:capability-command’,则尝试通过 STARTTLS 升级为加密连接。若失败则保留未加密连接。
starttls与 nil 类似,但 STARTTLS 失败时断开连接。
shellShell 连接。
:always-query-capabilities boolean若非 nil,即使是 ‘plain’ 连接也始终查询服务器能力。
:capability-command capability-command查询主机能力的命令。可以是字符串(直接发送给服务器)或函数(接收一个参数:连接时服务器的 “欢迎信息(greeting)”,返回字符串)。
:end-of-command regexp:end-of-capability regexp匹配命令结束或能力查询命令 capability-command 结束的正则表达式。后者默认使用前者的值。
:starttls-function function接收一个参数(对 capability-command 的响应)的函数,返回 nil 或激活 STARTTLS 的命令(若支持)。
:success regexp匹配 STARTTLS 协商成功的正则表达式。
:use-starttls-if-possible boolean若非 nil,即使 Emacs 无内置 TLS 支持也尝试 opportunistic STARTTLS 升级。
:warn-unless-encrypted boolean若非 nil,若最终连接类型未加密则向用户发出警告。这对 IMAP 等协议很有用,多数用户期望此类网络流量加密。
原因可能是 STARTTLS 升级失败,将 :return-list 设为非 nil 可捕获遇到的错误。
:client-certificate list-or-t ¶可以是格式为 (key-file cert-file) 的列表,指定证书密钥文件与证书文件本身;或为 t,表示通过 auth-source 查询该信息(see auth-source in Emacs auth-source Library)。仅用于 TLS 或 STARTTLS。若未指定 :client-certificate 时希望自动查询 auth-source,可将 network-stream-use-client-certificates 自定义为 t。
:return-list cons-or-nil该函数的返回值。若省略或为 nil,返回进程对象。否则返回格式为 (process-object . plist) 的 cons,其中 plist 可包含以下关键字:
:greeting string-or-nil若非 nil,为主机返回的欢迎字符串。
:capabilities string-or-nil若非 nil,为主机的能力字符串。
:type symbol连接类型:‘plain’ 或 ‘tls’。
:error symbol描述 STARTTLS 升级过程中遇到错误的字符串。
:shell-command string-or-nil若连接 type 为 shell,该参数会被解释为格式字符串(see 自定义格式字符串)并执行以建立连接。可用格式符为 ‘%s’(主机名)与 ‘%p’(端口号)。例如,若想先通过 ssh 连接 ‘gateway’ 再建立普通连接,该参数可设为类似 ‘ssh gateway nc %s %p’。