sockets - 退出 0 不终止程序
问题描述
我正在使用 OCaml Unix 库中提供的高级网络连接功能在 OCaml 中开发客户端-服务器应用程序,遵循https://caml.inria.fr/pub/docs/oreilly-book/html/中提供的步骤书-ora187.html。这些功能是:
val open_connection : sockaddr -> in_channel * out_channel
val shutdown_connection : in_channel -> unit
val establish_server : (in_channel -> out_channel -> unit) -> sockaddr -> unit
我能够成功构建客户端和验证程序,但我无法使用exit
OCaml 函数终止服务器。
我的(最小)服务器代码如下:
let handle_service ic oc =
try while true do
...
if ... then raise Finish_interaction
done ;
with
| Finish_interaction -> raise Sys.Break
| _ -> ...
let main_server serv_fun =
if Array.length Sys.argv < 4 then ...
else try
let port = int_of_string Sys.argv.(1) in
...
let my_address = Unix.inet_addr_loopback in
Unix.establish_server serv_fun (Unix.ADDR_INET(my_address, port))
with
| Sys.Break -> exit 0 (* PROGRAM DOES NOT TERMINATE *)
| _ -> ...
let go_server () =
Unix.handle_unix_error main_server handle_service ;;
go_server ()
我可以成功捕获Sys.Break
异常,但是捕获该异常exit 0
后的代码什么也不做,服务器只是继续运行并等待另一个客户端连接。
OCaml 文档对以下内容进行了说明establish_server
:
函数 Unix.establish_server 永远不会正常返回。
我不知道这是否意味着我永远无法在没有用户交互的情况下终止程序(例如,通过 Ctrl + C)。
简而言之,如何终止我的服务器?客户端确实在之后终止,shutdown_connection
但服务器继续等待传入连接。顺便说一句,我正在使用 OCamlbuild 编译我的代码。
解决方案
从Unix.establish_server的文档中:
为每个连接创建一个新进程
我建议打印进程 ID ( Unix.getpid ()
) 以确保进程调用exit
是您所期望的(父进程)。
您可以检查的另一件事是程序没有卡在at_exit
回调的执行中。例如,以下程序在调用期间进入了一个无限循环exit
:
let () =
at_exit (fun () -> while true do () done);
print_endline "all is well!";
exit 0
(可能不是您遇到的问题,但可能对未来的访问者有用)
推荐阅读
- jenkins - 如何在从詹金斯运行 RobotFramework 时禁用 [WARN] 消息以记录到控制台
- c# - 如何将浮点数格式化为小数点后 6 位
- r - Colab + Plots - 有什么方法可以调整布局?
- python - 不稳定排列
- c# - 在 GetMethod 中处理泛型类型
- video.js - 无法将 VideoJS 组件添加到 ModalDialog
- vue.js - VuePress 没有使用 frontmatter-redirection 插件正确地从旧链接重定向到新链接
- java - Vaadin 14 中缺少 GridLayout
- javascript - 滚动捕捉中断平滑滚动
- java - 如何在 xml 定义中获取 ApplicationContext?