41.14 网络连接

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 函数对网络连接返回 openclosedconnectstopfailed。对网络服务器,状态始终为 listen。除 stop 外,这些值均不会出现在真实子进程中。See 进程信息

你可以通过调用 stop-processcontinue-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 manualopen-network-stream 函数可根据可用支持透明处理加密连接的创建细节。

Function: open-network-stream name buffer host service &rest parameters

该函数打开一个 TCP 连接(支持可选加密),返回代表该连接的进程对象。

参数 name 指定进程对象的名称。会根据需要自动修改以保证唯一。

参数 buffer 是与该连接关联的缓冲区。连接的输出会插入该缓冲区,除非你指定了自定义过滤器函数处理输出。若 buffernil,表示该连接不关联任何缓冲区。

参数 hostservice 指定连接目标;host 为主机名(字符串),service 为已定义的网络服务名(字符串)或端口号(整数如 80,或整数字符串如 "80")。

剩余参数 parameters 为关键字/值对,主要与加密连接相关:

:nowait boolean

若非 nil,尝试建立异步连接。

:noquery query-flag

将进程查询标志初始化为 query-flag。See 退出前询问确认

:coding coding

用于设置网络进程使用的编码系统,优先于绑定 coding-system-for-readcoding-system-for-write。See make-network-process 查看详情。

:type type

连接类型。可选值:

plain

普通未加密连接。

tls
ssl

TLS(传输层安全)连接。

nil
network

先建立普通连接,若提供了参数 ‘:success’ 与 ‘:capability-command’,则尝试通过 STARTTLS 升级为加密连接。若失败则保留未加密连接。

starttls

nil 类似,但 STARTTLS 失败时断开连接。

shell

Shell 连接。

: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)。仅用于 TLSSTARTTLS。若未指定 :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

若连接 typeshell,该参数会被解释为格式字符串(see 自定义格式字符串)并执行以建立连接。可用格式符为 ‘%s’(主机名)与 ‘%p’(端口号)。例如,若想先通过 ssh 连接 ‘gateway’ 再建立普通连接,该参数可设为类似 ‘ssh gateway nc %s %p’。