Emacs Lisp网络连接 - 如何处理进程对象?

Tho*_*ten 6 emacs network-programming elisp process object

假设有一个TCP服务器启动并运行在localhost:8080上,在另一个理解列表的Lisp方言中.现在我在Elisp中打开一个网络连接

setq pserv (open-network-stream plisp "test1.l" "localhost" 8080)
Run Code Online (Sandbox Code Playgroud)

并成功将开放网络流程对象分配给变量pserv.但接下来,接下来,如何使用此流程对象向服务器发送请求?我想要做的是将列表发送到评估的其他服务器(作为数据的代码)并返回结果.

在上面的语句中,"test1.l"是与进程关联的Emacs缓冲区,因此结果应该打印在该缓冲区中.如果我把nil放在那里并且进程与任何缓冲区没有关系怎么办 - 如何从Elisp或进程对象访问服务器结果(也可能是列表形式)?

Elisp手册似乎认为这些知识是理所当然的,但我在这里有点迷失.每个提示都将不胜感激.

Tho*_*mas 10

客户端/服务器通信通过异步进程处理.这意味着,遗憾的是,您没有"发送"功能,您将数据传递给服务器并返回服务器的回复.原因是网络通信速度很慢,并且会阻止Emacs中的所有其他操作,这是一个单线程程序.

要将数据发送到您的服务器,请使用(process-send-string process string).第一个参数是您的网络连接,Emacs将其视为异步进程.由于您已将该子进程对象存储在变量中pserv,因此您可以编写:

(process-send-string pserv "(my data (can be (in) (list) form))")
Run Code Online (Sandbox Code Playgroud)

将字符串发送到服务器.

要读取服务器的回复,请使用进程过滤器函数,该函数是使用服务器发回给您的任何内容调用的回调函数.所以你首先必须定义这样一个回调函数,比如说:

(defun handle-server-reply (process content)
   "Gets invoked whenever the server sends data to the client."
   ...)
Run Code Online (Sandbox Code Playgroud)

此函数有两个参数,即网络进程和服务器发送的内容数据.但是有一个棘手的问题:服务器回复可以分成子内容.也就是说,当handle-server-reply被调用时,content参数可能只包含服务器回复的部分内容.稍后可以通过更多内容再次调用它.所以一定要正确处理.

要将您的函数声明为回调,请使用:

(set-process-filter pserv 'handle-server-reply)
Run Code Online (Sandbox Code Playgroud)

与往常一样,字符编码可以是皮塔饼,因此请查看以下两个函数并确定是否需要它们:

(set-process-filter-multibyte pserv t)
(set-process-coding-system pserv 'utf-8 'utf-8)
Run Code Online (Sandbox Code Playgroud)

确保分配过程过滤器功能之前设置这些.

您可能还有兴趣调查网络连接的状态,例如,处理连接意外关闭的情况.为此,您可以使用所谓的sentinel函数,这是另一种类型的回调,通过它您可以了解进程状态的变化:

(set-process-sentinel pserv 'sentinel-function)

(defun sentinel-function (process event)
  "Gets called when the status of the network connection changes."
   ...)
Run Code Online (Sandbox Code Playgroud)

event参数包含有关连接状态更改方式的信息.

我认为之前已经指出了Emacs 流程文档.这绝对值得一读.


cjm*_*cjm 5

在 Emacs 中,网络连接被视为异步子进程。因此,有关向子流程发送输入或从子流程读取输出的说明也适用于此处。

要将某些内容发送到服务器,请参阅进程的输入,要读取结果,请参阅进程的输出

信息以字符串形式通过网络传输,因此您可能需要在从服务器接收数据后使用read或。read-from-string请参阅输入函数