erlang获取一个5900——65535之间不重复的一个数据

2024-02-17 03:58

本文主要是介绍erlang获取一个5900——65535之间不重复的一个数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

有这样一个问题,我们要获取一个5900~65535之间的一个端口号。对于这个端口号必须是唯一出现的,不能重复,如果分配出去的端口号使用完了之后,还要进行相应的回收,等待下一次的分配。要使用erlang来实现,这个该如何实现呢?
我是这么来实现的,在我的实现当中要使用mnesia数据库。每分配一个端口号出去之后,就将分配的端口号记录在数据库中,并且在数据库中使用一项记录下一次可以分配并且使用的端口号的值。如果下一次请求分配的时候,就直接读取分配出去的那个端口号,然后更新这一项,往数据库中添加已经分配的这个端口号,等下一次如果再次分配的时候,就直接分配。
我的程序代码如下:
  1. %% vncport.erl
  2. %% Author: Sunny
  3. %% Created: 2011-7-25
  4. %% Description: get vncport
  5. -module(vncport).
  6. -date("2011.07.25").

  7. %%
  8. %% Include Files
  9. %%
  10. -include_lib("stdlib/include/qlc.hrl").
  11. -record(vnc_counter,
  12.                 {
  13.                 vncport_num,
  14.                 used_flag
  15.                 }).

  16. %%
  17. %% Exported Functions
  18. %%
  19. -export([init/0, stop/0]).
  20. -export([recovery_one_vncport/1]).
  21. -export([get_next_vncport/0]).

  22. %%
  23. %% Api Functions
  24. %%
  25. init() ->
  26.      mnesia:stop(),
  27.      mnesia:delete_schema([node()]),
  28.      mnesia:create_schema([node()]),
  29.      mnesia:start(),
  30.      mnesia:create_table(vnc_counter,[{attributes, record_info(fields, vnc_counter)}]),
  31.      F = fun(N) ->
  32.              insert_to_table(N)
  33.          end,
  34.      for(5908, 5910, F),
  35.      for(5915, 5917, F),
  36.      mnesia:dirty_update_counter(vnc_counter, mac_id, 5900).

  37. stop() ->
  38.     mnesia:stop().

  39. get_next_vncport() ->
  40.     Query = qlc:q([X#vnc_counter.used_flag || X <- mnesia:table(vnc_counter),
  41.                     X#vnc_counter.vncport_num =:= mac_id]),
  42.     F = fun() ->
  43.             qlc:e(Query)
  44.     end,
  45.     io:format("get the vncport which is not used~n"), %% degug info
  46.     {atomic, [Result]} = mnesia:transaction(F),
  47. %    spawn(fun() -> update_vnc_counter(Result) end),
  48.     update_vnc_counter(Result),
  49.     io:format("get the next vncport is:~p~n", [Result]), %% debug info
  50.     Result.

  51. recovery_one_vncport(N) ->
  52.     Row = {vnc_counter, N},
  53.     F = fun() ->
  54.         mnesia:delete(Row)
  55.     end,
  56.     Result = mnesia:transaction(F),
  57.     io:format("delete ~p successfully~n", [N]), %% debug info
  58.     Result.

  59. %%
  60. %% Local Functions
  61. %%
  62. update_vnc_counter(X) ->
  63.     io:format("spawn one process to update vnc_counter~n"), %% debug info
  64.     insert_to_table(X),
  65.     io:format("add one used vncport to vnc_counter successfully!~n"), %% debug info
  66.     if
  67.         X+1 > 65535 ->
  68.             N=5900;
  69.         X+1 =< 65535 ->
  70.             N=X+1
  71.     end,
  72.     io:format("now begin check whether in vnc_counter~n"), %% debug info
  73.     case check_in_vnc_counter(N) of
  74.         true ->
  75.             io:format("find ~p is in vnc_counter~n", [N]), %% debug info
  76.             NX = find_not_in_vnc_counter(N), %% find one not in vnc_counter
  77.             Row = #vnc_counter{vncport_num=mac_id, used_flag=NX};
  78.         false ->
  79.             io:format("find ~p is not in vnc_counter~n", [N]), %% debug info
  80.             Row = #vnc_counter{vncport_num=mac_id, used_flag=N}
  81.     end,
  82.     F = fun() ->
  83.             mnesia:write(Row)
  84.         end,
  85.     mnesia:transaction(F),
  86.     io:format("update vnc_counter over~n"), %% debug info
  87.     ok.

  88. check_in_vnc_counter(N) ->
  89.     io:format("check ~p is or not in vnc_counter~n", [N]), %% debug info
  90.     Query = qlc:q([X#vnc_counter.vncport_num || X <- mnesia:table(vnc_counter),
  91.                     X#vnc_counter.vncport_num =:= N]),
  92.     F = fun() ->
  93.             qlc:e(Query)
  94.     end,
  95.     Result = mnesia:transaction(F),
  96.     io:format("check result is:~p~n", [Result]), %% debug info
  97.     case Result of
  98.         {atomic, []} ->
  99.             Return = false;
  100.         {atomic, [_]} ->
  101.             Return = true
  102.     end,
  103.     Return.

  104. find_not_in_vnc_counter(N) ->
  105.     if
  106.         N+1 > 65535 ->
  107.             NX = 5900;
  108.         N+1 =< 65535 ->
  109.             NX = N+1
  110.     end,
  111.     case check_in_vnc_counter(NX) of
  112.         true ->
  113.             Result = find_not_in_vnc_counter(N+1);
  114.         false ->
  115.             Result = NX
  116.     end,
  117.     Result.

  118. insert_to_table(N) ->
  119.     Row = #vnc_counter{vncport_num=N, used_flag=yes},
  120.     F = fun() ->
  121.             mnesia:write(Row)
  122.         end,
  123.     mnesia:transaction(F).

  124. for(Max, Max, F) ->
  125.     [F(Max)];
  126. for(Min, Max, F) ->
  127.     [F(Min)|for(Min+1, Max, F)].
这个程序的执行结果是:
  1. 1> c(vncport).
  2. {ok,vncport}
  3. 2> vncport:init().
  4. 5900
  5. 3> vncport:get_next_vncport().
  6. get the vncport which is not used
  7. spawn one process to update vnc_counter
  8. add one used vncport to vnc_counter
  9. now begin check whether in vnc_counter
  10. check 5901 is or not in vnc_counter
  11. check result is:{atomic,[]}
  12. find 5901 is not in vnc_counter
  13. update vnc_counter over
  14. get the next vncport is:5900
  15. 5900
  16. 4> vncport:get_next_vncport().
  17. get the vncport which is not used
  18. spawn one process to update vnc_counter
  19. add one used vncport to vnc_counter
  20. now begin check whether in vnc_counter
  21. check 5902 is or not in vnc_counter
  22. check result is:{atomic,[5902]}
  23. find 5902 is in vnc_counter
  24. check 5903 is or not in vnc_counter
  25. check result is:{atomic,[5903]}
  26. check 5904 is or not in vnc_counter
  27. check result is:{atomic,[5904]}
  28. check 5905 is or not in vnc_counter
  29. check result is:{atomic,[5905]}
  30. check 5906 is or not in vnc_counter
  31. check result is:{atomic,[5906]}
  32. check 5907 is or not in vnc_counter
  33. check result is:{atomic,[5907]}
  34. check 5908 is or not in vnc_counter
  35. check result is:{atomic,[5908]}
  36. check 5909 is or not in vnc_counter
  37. check result is:{atomic,[5909]}
  38. check 5910 is or not in vnc_counter
  39. check result is:{atomic,[5910]}
  40. check 5911 is or not in vnc_counter
  41. check result is:{atomic,[]}
  42. update vnc_counter over
  43. get the next vncport is:5901
  44. 5901
  45. 5> vncport:get_next_vncport().
  46. get the vncport which is not used
  47. spawn one process to update vnc_counter
  48. add one used vncport to vnc_counter
  49. now begin check whether in vnc_counter
  50. check 5912 is or not in vnc_counter
  51. check result is:{atomic,[]}
  52. find 5912 is not in vnc_counter
  53. update vnc_counter over
  54. get the next vncport is:5911
  55. 5911
  56. 6> vncport:get_next_vncport().
  57. get the vncport which is not used
  58. spawn one process to update vnc_counter
  59. add one used vncport to vnc_counter
  60. now begin check whether in vnc_counter
  61. check 5913 is or not in vnc_counter
  62. check result is:{atomic,[5913]}
  63. find 5913 is in vnc_counter
  64. check 5914 is or not in vnc_counter
  65. check result is:{atomic,[5914]}
  66. check 5915 is or not in vnc_counter
  67. check result is:{atomic,[5915]}
  68. check 5916 is or not in vnc_counter
  69. check result is:{atomic,[5916]}
  70. check 5917 is or not in vnc_counter
  71. check result is:{atomic,[5917]}
  72. check 5918 is or not in vnc_counter
  73. check result is:{atomic,[]}
  74. update vnc_counter over
  75. get the next vncport is:5912
  76. 5912
  77. 7> vncport:get_next_vncport().
  78. get the vncport which is not used
  79. spawn one process to update vnc_counter
  80. add one used vncport to vnc_counter
  81. now begin check whether in vnc_counter
  82. check 5919 is or not in vnc_counter
  83. check result is:{atomic,[]}
  84. find 5919 is not in vnc_counter
  85. update vnc_counter over
  86. get the next vncport is:5918
  87. 5918
  88. 8> vncport:get_next_vncport().
  89. get the vncport which is not used
  90. spawn one process to update vnc_counter
  91. add one used vncport to vnc_counter
  92. now begin check whether in vnc_counter
  93. check 5920 is or not in vnc_counter
  94. check result is:{atomic,[]}
  95. find 5920 is not in vnc_counter
  96. update vnc_counter over
  97. get the next vncport is:5919
  98. 5919
  99. 9> vncport:get_next_vncport().
  100. get the vncport which is not used
  101. spawn one process to update vnc_counter
  102. add one used vncport to vnc_counter
  103. now begin check whether in vnc_counter
  104. check 5921 is or not in vnc_counter
  105. check result is:{atomic,[]}
  106. find 5921 is not in vnc_counter
  107. update vnc_counter over
  108. get the next vncport is:5920
  109. 5920
  110. 10>
可能输出的信息比较多些,但是对于本程序来说我们只要关注最后的那个数据就行了。
在我的程序中有一个小的技巧就是在init()函数中使用的
    mnesia:dirty_update_counter(vnc_counter, mac_id, 5900),
    我使用了这个来记录下一次要读取的可以使用的数据,原先使用文件的记录,发现那是有问题的,而且在程序中处理数据库可以使用spawn一个进程,这个是可以的,但是我不知道使用是不是一件好的事情。
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(676) | 评论(0) | 转发(0) |
0

上一篇:erlang 进制转换

下一篇:标准I/O的三种缓冲

相关热门文章
  • python 自动化测试平台 Robot ...
  • python 自动化测试平台 Robot ...
  • python snmp 自动化2-在python...
  • 自动化测试详细测试计划 模板...
  • python snmp 自动化3-修改pyth...
  • linux dhcp peizhi roc
  • 关于Unix文件的软链接
  • 求教这个命令什么意思,我是新...
  • sed -e "/grep/d" 是什么意思...
  • 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
评论热议

这篇关于erlang获取一个5900——65535之间不重复的一个数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/716603

相关文章

使用Python开发一个Ditto剪贴板数据导出工具

《使用Python开发一个Ditto剪贴板数据导出工具》在日常工作中,我们经常需要处理大量的剪贴板数据,下面将介绍如何使用Python的wxPython库开发一个图形化工具,实现从Ditto数据库中读... 目录前言运行结果项目需求分析技术选型核心功能实现1. Ditto数据库结构分析2. 数据库自动定位3

pandas数据的合并concat()和merge()方式

《pandas数据的合并concat()和merge()方式》Pandas中concat沿轴合并数据框(行或列),merge基于键连接(内/外/左/右),concat用于纵向或横向拼接,merge用于... 目录concat() 轴向连接合并(1) join='outer',axis=0(2)join='o

批量导入txt数据到的redis过程

《批量导入txt数据到的redis过程》用户通过将Redis命令逐行写入txt文件,利用管道模式运行客户端,成功执行批量删除以Product*匹配的Key操作,提高了数据清理效率... 目录批量导入txt数据到Redisjs把redis命令按一条 一行写到txt中管道命令运行redis客户端成功了批量删除k

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

Python获取浏览器Cookies的四种方式小结

《Python获取浏览器Cookies的四种方式小结》在进行Web应用程序测试和开发时,获取浏览器Cookies是一项重要任务,本文我们介绍四种用Python获取浏览器Cookies的方式,具有一定的... 目录什么是 Cookie?1.使用Selenium库获取浏览器Cookies2.使用浏览器开发者工具

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分