一般的tcp服务器(阻塞)是使用的如下

[erlang] gen_tcp传输文件原型

http://www.cnblogs.com/bluefrog/archive/2012/09/10/2679040.html

server端

gen_tcp:listen(开始监听端口), 如
server(Port) ->
  case gen_tcp:listen(Port,[binary,{packet,0},
  {reuseaddr,true}, %% 
  {active,true}]) of
    {ok,Listen} ->
      spawn(fun()-> connect(Listen) end);
    {error,Why} ->
      io:format("~p~n",[Why])
  end.

然后gen_tcp:accept(等待客户端链接,如果成功就spawn一个进程继续等待),如

connect(Listen) ->
case gen_tcp:accept(Listen) of %% 等待暂停并等待一个连接
{ok,Socket} ->
spawn(fun() -> connect(Listen) end),
loop(Socket);
{error,Why} ->
io:format("~p~n",[Why])
end.

这里的gen_tcp:accept是阻塞的,就是说,如果没有client连接(也没有超时)就会一直等

这是erlang推荐使用方法,可是不是最高效的方法

还有一种非阻塞的调用一般如下

http://www.cnblogs.com/bicowang/p/3976129.html

使用 erlang OTP 模式编写非阻塞的 tcp 服务器

还是使用gen_tcp:listen(开始监听端口), 如

init([Port, Module]) ->
process_flag(trap_exit, true),
Opts = [binary, {packet, 2}, {reuseaddr, true},
{keepalive, true}, {backlog, 30}, {active, false}],
%% 使用 gen_tcp 模块启动套接字监听,这是一个阻塞动作
case gen_tcp:listen(Port, Opts) of
{ok, Listen_socket} -> %% 创建监听成功返回监听socket
%% 创建第一个接受连接的进程
%% prim_inet:async_accept/2开启异步监听
%% 之后有客户端连接时会向此进程发送一个异步消息inet_async到进程消息队列
%% Ref 存储接受进程的引用
{ok, Ref} = prim_inet:async_accept(Listen_socket, -1),
{ok, #state{listener = Listen_socket,
acceptor = Ref,
module = Module}};
{error, Reason} ->
{stop, Reason}
end.

上面接受客户端连接没有用gen_tcp:accept,使用了prim_inet:async_accept

当有客户端连接,会调用下面的函数

%% 注意这里 ListSock 以及 Ref 做了匹配,只有匹配了才是该监听口接收的连接
handle_info({inet_async, ListSock, Ref, {ok, CliSocket}},
#state{listener=ListSock, acceptor=Ref, module=Module} = State) ->
try
case set_sockopt(ListSock, CliSocket) of
ok -> ok;
{error, Reason} -> exit({set_sockopt, Reason})
end, %% 接收新的客户端连接,启动一个新的客户端状态机进程,动态添加到 tcp_client_sup 客户端监控树
{ok, Pid} = tcp_server_app:start_client(), %% 绑定 CliSocet 到客户端进程 Pid, 这样CliSocket接收数据都会被转化成Pid代表进程的邮箱消息
gen_tcp:controlling_process(CliSocket, Pid),
%% Instruct the new FSM that it owns the socket. Module:set_socket(Pid, CliSocket), %% Signal the network driver that we are ready to accept another connection
%% 重新设置异步监听下一个客户端连接的消息,设置新的监听引用
%% 必须重新设置才能监听到 {inet_async,S,Ref,Status} 消息
case prim_inet:async_accept(ListSock, -1) of
{ok, NewRef} -> ok;
{error, NewRef} -> exit({async_accept, inet:format_error(NewRef)})
end, %% 更新新的监听引用
{noreply, State#state{acceptor=NewRef}}
catch exit:Why ->
error_logger:error_msg("Error in async accept: ~p.\n", [Why]),
{stop, Why, State}
end;

这里的Ref和上面的相互对应(也和client连接使用的CliSocket对应),就是当有一个client连接,就会有inet_async消息命中

后面使用对应的进程进行处理。

非阻塞tcp服务器与阻塞的tcp服务器对比的更多相关文章

  1. TCP同步与异步及阻塞模式,多线程+阻塞模式,非阻塞模式简单介绍

    首先我简单介绍一下同步TCP编程 与异步TCP编程. 在服务端我们通常用一个TcpListener来监听一个IP和端口.客户端来一个请求的连接,在服务端可以用同步的方式来接收,也可以用异步的方式去接收 ...

  2. SSL/TLS/WTLS原理(密钥协商的形象化比喻:验证服务器的身份,用服务器的公钥协商加密格式,然后再加密具体的消息,TCP传递SSL处理后的数据)good

    一 前言 首先要澄清一下名字的混淆: 1 SSL(Secure Socket Layer)是netscape公司设计的主要用于web的安全传输协议.这种协议在WEB上获得了广泛的应用. 2 IETF( ...

  3. 客户端程序通过TCP通信传送"小文件"到服务器

    客户端程序通过TCP通信传送"小文件"到服务器 [c#源码分享]客户端程序通过TCP通信传送"小文件"到服务器 源码  (不包含通信框架源码,通信框架源码请另行 ...

  4. 五十五、linux 编程——TCP 连接和关闭过程及服务器的并发处理

    55.1 TCP 连接和关闭过程 55.1.1 介绍 建立连接的过程就是三次握手的过程:客户端发送 SYN 报文给服务器,服务器回复 SYN+ACK 报文,客户机再发送 ACK 报文. 关闭连接的过程 ...

  5. 高并发服务器建议调小 TCP 协议的 time_wait 超时时间。

    1. [推荐]高并发服务器建议调小 TCP 协议的 time_wait 超时时间. 说明:操作系统默认 240 秒后,才会关闭处于 time_wait 状态的连接,在高并发访问下,服 务器端会因为处于 ...

  6. 网络编程释疑之:单台服务器上的并发TCP连接数可以有多少

    曾几何时我们还在寻求网络编程中C10K问题的解决方案,但是现在从硬件和操作系统支持来看单台服务器支持上万并发连接已经没有多少挑战性了.我们先假设单台服务器最多只能支持万级并发连接,其实对绝大多数应用来 ...

  7. 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理

    · 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...

  8. C# TCP应用编程二 同步TCP应用编程

    不论是多么复杂的TCP 应用程序,双方通信的最基本前提就是客户端要先和服务器端进行TCP 连接,然后才可以在此基础上相互收发数据.由于服务器需要对多个客户端同时服务,因此程序相对复杂一些.在服务器端, ...

  9. C# TCP应用编程三 异步TCP应用编程

    利用TcpListener和TcpClient类在同步方式下接收.发送数据以及监听客户端连接时,在操作没有完成之前一直处于阻塞状态,这对于接受.发送数据量不大的情况或者操作勇士较短的情况下是比较方便的 ...

随机推荐

  1. java消息队列--ActiveMQ

    1.下载安装ActiveMQ ActiveMQ官网下载地址:http://activemq.apache.org/download.html ActiveMQ 提供了Windows 和Linux.Un ...

  2. Elasticsearch.安装(单节点)

    Elasticsearch.安装(单节点) 环境Linux 7.x jdk 1.8 elasticsearch 5.x 环境目录结构(根目录多了两个文件夹): /resources    /** 存放 ...

  3. 北京大学Cousera学习笔记--7-计算导论与C语言基础--基本数据类型&变量&常量

    1.整形数据 1.基本型(int 4B).短整型(short 2B).长整型(long 4B)  VC环境下 sizeof运算符用于计算某种类型的对象在内存中所占的字节数 ,用法:size(int) ...

  4. 请求http页面的相关过程

    http请求从TCP建立三次握手后进行,客户端按照规定的格式向服务器发送http请求,服务器在接收到这个请求之后,首先要对其进行解析,发掘出客户端所需要的相关资源,然后经过相应的业务逻辑处理,找到这个 ...

  5. Vue学习之路---No.3(分享心得,欢迎批评指正)

    同样的,我们先来回顾一下昨天学习的内容: 1.利用v-once来组织双向绑定 2.filter{}过滤器的使用(详情请看上一章) 3.computed(计算属性),利用computed属性实现filt ...

  6. linux 命令 jps 和 goassess

    jps (Java Virtual Machine Process Status Tool)  是java提供的一个显示当前所有java进程pid的命令,适合在linux/unix平台上简单察看当前j ...

  7. 对接 第三方物流APP 手机版

    昨天因为bibi项目要对接 物流信息 开始找了快递鸟文档,但是要填写申请APP,必须要注册公司才可以,这样非常麻烦.下面的第三方物理接口,绝对让你满意. https://m.kuaidi100.com ...

  8. Log4j2 简介

    介绍 Log4j2是Log4j的升级版,与之前的版本Log4j 1.x相比.有重大的改进,修正了Logback固有的架构问题的同事,改进了许多Logback所具有的功能. 特性 一.API 分离 Lo ...

  9. C#导出文本内容到word文档源码

    将做工程过程中较好的代码片段珍藏起来,下面的代码内容是关于C#导出文本内容到word文档的代码,希望能对小伙伴们也有好处.<%@ Page Language="C#" Aut ...

  10. JavaScript笔记1———js的一些常识

    一.什么是js? js是一种运行于解释器中的解释型脚本语言. 二.js的组成部分? 1.ECMAScript-----这是js的核心 2.DOM-----让js可以对网页进行操作(例:对页面元素的增. ...