我的erlang TCP服务器
不解释,直接贴代码。
1) socket_options.hrl
-record(socket_options, {port=8024, loop, name, ip=any, nodelay=false, backlog=128, listen=null, active_sockets=0} ).
2) test_server.erl
-module(test_server). -export([start/0, stop/0, looper/1]). -include("socket_options.hrl"). %开启服务 start()-> test_socket_server:start(#socket_options{loop = {?MODULE, looper}}). %关闭服务 stop()-> test_socket_server:stop(). looper(Socket) -> inet:setopts(Socket, [{active, once}]), receive {tcp, Socket, Data} -> io:format("Got packet: ~p~n", [Data]), gen_tcp:send(Socket, Data), looper(Socket); {tcp_closed, Socket}-> io:format("Socket ~p closed~n", [Socket]); {tcp_error, Socket, Reason} -> io:format("Error on socket ~p reason: ~p~n", [Socket, Reason]) end.
3) test_socket_server.erl
-module(test_socket_server). -export([start/0, start/1, stop/0, stop/1]). -export([init/1, handle_call/3, handle_cast/2, terminate/2, code_change/3, handle_info/2]). -include("socket_options.hrl"). -define(RECBUF_SIZE, 8192). start() -> gen_server:start(?MODULE, [], []). start(InitArg = #socket_options{name = Name}) -> case Name of undefined -> gen_server:start({local,?MODULE}, ?MODULE, InitArg, []); _ -> gen_server:start({local,Name}, ?MODULE, InitArg, []) end. stop() -> gen_server:cast(?MODULE, stop). stop(Name) when is_atom(Name) -> gen_server:cast(Name, stop); stop(Pid) when is_pid(Pid) -> gen_server:cast(Pid, stop); stop(_State = #socket_options{name = Name}) -> stop(Name). %回调函数 %init(State = #socket_options{ip = Ip, port = Port, backlog = Backlog, nodelay = NoDelay}) -> init(State = #socket_options{port = Port, backlog = Backlog, nodelay = NoDelay}) -> BaseOpts = [binary, {reuseaddr, true}, {packet, 0}, {backlog, Backlog}, {recbuf, ?RECBUF_SIZE}, {active, false}, {nodelay, NoDelay}], listen(Port, BaseOpts, State). %%监听 handle_call(_Msg, _Caller, State) -> {noreply, State}. handle_info(_Msg, Library) -> {noreply, Library}. terminate(Reason, #socket_options{listen = Listen}) -> io:format("socket close,~p~n",[Reason]), gen_tcp:close(Listen). %%关闭Listen code_change(_OldVsn, State, _Extra) -> State. handle_cast({accepted, _Pid}, State = #socket_options{active_sockets = ActiveSockets, listen = Listen, loop = Loop}) -> NewState = State#socket_options{active_sockets = 1 + ActiveSockets}, test_socket_server_acceptor:start_link(self(), Listen, Loop), {noreply, NewState}; handle_cast(stop, Name) -> %io:format("关闭服务器!~n"), {stop, normal , Name}. listen(Port, Opts, State) -> case gen_tcp:listen(Port, Opts) of {ok, Listen} -> test_socket_server_acceptor:start_link(self(), Listen, State#socket_options.loop), NewState = State#socket_options{listen = Listen}, {ok, NewState}; {error, Reason} -> {stop, Reason} end.
4) test_socket_server_acceptor.erl
-module(test_socket_server_acceptor). -export([start_link/3, init/3]). start_link(Server, Listen, Loop) -> proc_lib:spawn_link(?MODULE, init, [Server, Listen, Loop]). init(Server, Listen, Loop) -> case catch gen_tcp:accept(Listen) of {ok, Socket} -> gen_server:cast(Server, {accepted, self()}), call_loop(Loop, Socket); {error, closed} -> exit(normal); {error, timeout} -> init(Server, Listen, Loop); {error, esslaccept} -> exit(normal); _ -> exit({error, accept_failed}) end. call_loop({M, F}, Socket) -> io:format("socket call_loop,~n"), M:F(Socket); call_loop({M, F, [A1]}, Socket) -> M:F(Socket, A1); call_loop({M, F, A}, Socket) -> erlang:apply(M, F, [Socket | A]); call_loop(Loop, Socket) -> Loop(Socket).
下一步是想在此基础上写一个聊天室什么的,不过我目前我想先实践完OTP实战这本书。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
世界顶级科技公司参与组建意在遏制勒索软件的工作组
几个世界顶级科技公司正在支持建立新的行业工作组,旨在限制勒索软件组织获得经济利益的能力,遏制勒索软件的发展,针对这些组织与背后攻击者的经济进行打击。 本周,来自于Amazon、Cisco、FireEye、McAfee、Microsoft与其他数十家公司的高级管理人员加入了由美国司法部(DOJ)牵头,由欧洲刑警组织和英国国家犯罪局参与的,打击勒索软件犯罪的国际工作组,以调查勒索软件的全球犯罪网络。 该国际工作组敦促美国政府查找、挫败并逮捕勒索软件的运营者列为美国网络安全防御的优先事项,将勒索软件认定为国家安全威胁。 据《华尔街日报》报道,美国司法部也组建了自己的工作组来应对勒索软件,并在行业广泛地建立了合作伙伴关系。据称,司法部的内部备忘录呼吁制定针对勒索软件整个犯罪生态系统的战略,包括起诉攻击者、阻断正在进行的攻击、遏制支撑攻击的服务等。 根据安全公司Emsisoft报道,2020年将近2400个美国政府、医疗机构和学校都成为了勒索软件的受害者。 工作组指出,防治勒索软件的成本远远超出了勒索赎金。尽管勒索软件也是利益驱动犯罪,在传统意义上也是非暴力的,但从没有影响攻击者的正常生活。 衡...
- 下一篇
Docker - 仓库(8)
一. 初始Docker 仓库 在之前几篇文章中,使用过很多镜像创建实例,但是大家有没有发现以下几个问题 ●拉取的镜像只在当前服务器,只能本地使用 ●多个服务器部署同一个应用时,会拉取多次镜像 ●应用集群节点数过多,同一时间去拉取会消耗很大的网络出口带宽 ●命名规范性,一台服务器上部署多个应用模块,则命名需要很强的规范性 ●不便管理,一台服务器上部署多个项目模块时,无法对每个项目的模块进行区分 Yum仓库,当本地需要去拉取依赖包时只需要进行认证、配置就可以直接下载。而Docker 仓库,就是与Yum起到相同功能的角色,一个是解决系统环境依赖包问题,一个是解决镜像管理、拉取问题 二.Docker 仓库软件介绍 ● 第三方远程仓库 Docker Hub、阿里云、网易云仓库,镜像存储在第三方云上 ● Docker Repository Docker自身提供的一款私有仓库,没有Web Ui管理页面 ● 开源技术实现 Harbor,提供丰富的Api操作接口以及完善的Web UI功能 本文着重介绍"Harbor"仓库的实现 三.Harbor仓库的部署与使用 3.1Harbor官网...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7设置SWAP分区,小内存服务器的救世主
- Linux系统CentOS6、CentOS7手动修改IP地址
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS8编译安装MySQL8.0.19