You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Erlang整数后匹配字符串及服务器添加时间戳改造技术咨询

我来帮你搞定Erlang服务器的这两个需求——时间戳功能和先匹配整数再匹配字符串的消息解析,直接上实用的实现方案:

实现Erlang服务器的时间戳功能与消息解析逻辑

一、先匹配整数再匹配字符串的消息解析

你需要先把收到的二进制消息拆解成命令、整数参数和字符串参数,Erlang的二进制模式匹配是处理这类场景的绝佳工具。我们可以写一个通用的解析函数,来处理这种"命令 + 整数 + 字符串"的格式:

parse_message(<<"read ", IntBin/binary, " ", StrBin/binary>>) ->
    try
        Int = binary_to_integer(IntBin),
        {read, Int, StrBin}
    catch
        _:_ -> {invalid_message, <<"read command requires integer + string">>}
    end;
parse_message(<<"up ", IntBin/binary, " ", StrBin/binary>>) ->
    try
        Int = binary_to_integer(IntBin),
        {up, Int, StrBin}
    catch
        _:_ -> {invalid_message, <<"up command requires integer + string">>}
    end;
parse_message(Other) ->
    {unknown_command, Other}.

这个函数会尝试把命令后的第一个参数转成整数,剩下的部分作为字符串参数,如果转换失败会返回错误信息,方便后续给客户端反馈。

二、添加时间戳功能

Erlang提供了erlang:system_time/1来获取高精度时间戳,你可以根据需求选择精度(比如millisecond或microsecond)。我们可以把时间戳集成到日志记录和业务处理中:

  1. 获取可读时间戳的工具函数:
get_timestamp() ->
    % 生成YYYY-MM-DD HH:MM:SS.ms格式的可读时间戳
    {Date, Time} = calendar:local_time(),
    {Hour, Min, Sec} = Time,
    Ms = erlang:system_time(millisecond) rem 1000,
    lists:flatten(io_lib:format("~p ~2..0w:~2..0w:~2..0w.~3..0w", [Date, Hour, Min, Sec, Ms])).

这个函数返回的字符串适合直接写到日志里,或者返回给客户端展示操作时间。

  1. 在业务逻辑中集成时间戳:
    比如修改你的update和read函数,加入时间戳的记录和使用:
update(Socket, IntParam, StrParam) ->
    Timestamp = get_timestamp(),
    % 记录带时间戳的操作日志
    error_logger:info_msg("[~s] Executing update with int: ~w, str: ~w", [Timestamp, IntParam, StrParam]),
    % 这里写你的业务更新逻辑,比如把时间戳和参数一起存储
    % 示例:给客户端返回带时间戳的响应
    gen_tcp:send(Socket, <<"Updated at ", (list_to_binary(Timestamp))/binary, ", params: ", integer_to_binary(IntParam), " ", StrParam/binary>>).

read(Socket, IntParam, StrParam) ->
    Timestamp = get_timestamp(),
    error_logger:info_msg("[~s] Reading with int: ~w, str: ~w", [Timestamp, IntParam, StrParam]),
    % 读取逻辑...
    gen_tcp:send(Socket, <<"Read at ", (list_to_binary(Timestamp))/binary, ", result: ...">>).

三、整合到server_loop主循环

现在把解析函数和时间戳功能整合到你的原有循环里,修改后的server_loop会先解析消息,再分发到对应的处理函数,同时处理异常情况:

server_loop(Socket) ->
    inet:setopts(Socket, [{active, once}]),
    receive
        {tcp, Socket, Data} ->
            case parse_message(Data) of
                {read, IntParam, StrParam} ->
                    read(Socket, IntParam, StrParam),
                    server_loop(Socket);
                {up, IntParam, StrParam} ->
                    update(Socket, IntParam, StrParam),
                    server_loop(Socket);
                {invalid_message, ErrMsg} ->
                    gen_tcp:send(Socket, <<"Error: ", ErrMsg/binary>>),
                    server_loop(Socket);
                {unknown_command, Cmd} ->
                    error_logger:warning_msg("Unknown command received: ~w", [Cmd]),
                    gen_tcp:send(Socket, <<"Unknown command">>),
                    server_loop(Socket)
            end;
        {tcp_closed, Socket} ->
            error_logger:info_msg("Client socket closed"),
            ok;
        {tcp_error, Socket, Reason} ->
            error_logger:error_msg("TCP error occurred: ~w", [Reason]),
            ok
    end.

额外提示

  • 如果你的消息格式不是空格分隔(比如固定长度的整数),可以调整parse_message里的二进制匹配规则,比如<<"up", IntBin:4/binary, StrBin/binary>>(假设整数占4字节),但空格分隔的方式更灵活通用。
  • 如果你需要纯数字格式的时间戳(比如存储到数据库),直接用erlang:system_time(millisecond)返回整数即可,不需要转换为字符串。
  • 新增的tcp_closed和tcp_error处理能让你的服务器更健壮,避免异常退出。

内容的提问来源于stack exchange,提问作者Dranna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:30:36