`
bachmozart
  • 浏览: 111632 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

gen_tcp async accept大致流程

阅读更多
erlang 调用 gen_tcp:accept时是会阻塞的,包括后续的gen_tcp:recv也是,但是这个阻塞实际是在erlang这边 receive等待driver返回消息,并不是阻塞在driver上,driver是不能阻塞的,这个mryufeng老大也很早就跟我说过,当时没明白,现在终于理解了

看下erlang 这边是如何做的
accept0(L, Time) when is_port(L), is_integer(Time) ->
    case async_accept(L, Time) of
	{ok, Ref} ->
	    receive 
		{inet_async, L, Ref, {ok,S}} ->
		    accept_opts(L, S);
		{inet_async, L, Ref, Error} ->
		    Error
	    end;
	Error -> Error
    end.

async_accept(L, Time) ->
    case ctl_cmd(L,?TCP_REQ_ACCEPT, [enc_time(Time)]) of
	{ok, [R1,R0]} -> {ok, ?u16(R1,R0)};
	Error -> Error
    end.

可以看到prim_inet调用 ctl_cmd实际是通过port_control调用driver,这个是会立即返回的,但只是返回这个调用的成功/失败状态,而实际的accept后的结果是通过receive得到的,格式:
{inet_async, L, Ref, {ok,S}}   S就是conn fd对应的port

那么driver里是怎么处理的呢,其实想让accept不阻塞肯定是使用的nonblocking + event notify 机制,也就是select/epoll之类的,看下

tcp_inet_ctl函数里的TCP_REQ_ACCEPT分支
if (desc->inet.state == TCP_STATE_ACCEPTING) {
    //这个还没弄明白
} else if (desc->inet.state == TCP_STATE_MULTI_ACCEPTING) {
    ...
}else{
    ...
}

进入这个分支首先是对当前连接状态的一个判断,accept之前的状态是LISTEN,所以肯定执行的是else部分代码
 s = sock_accept(desc->inet.s, (struct sockaddr*) &remote, &n);
	    if (s == INVALID_SOCKET) {
		if (sock_errno() == ERRNO_BLOCK) {
		    ErlDrvMonitor monitor;
		    if (driver_monitor_process(desc->inet.port, driver_caller(desc->inet.port),
					       &monitor) != 0) { 
			return ctl_xerror("noproc", rbuf, rsize);
		    }
		    enq_async_w_tmo(INETP(desc), tbuf, TCP_REQ_ACCEPT, timeout, &monitor);
		    desc->inet.state = TCP_STATE_ACCEPTING;
		    sock_select(INETP(desc),FD_ACCEPT,1);
		    if (timeout != INET_INFINITY) {
			driver_set_timer(desc->inet.port, timeout);
		    }
		} else {
		    return ctl_error(sock_errno(), rbuf, rsize);
		}
	    } else {
            }

这段代码首先调用了sock_accept,这个封装的宏也是为了跨平台的通用,其实linux上就是accept,由于之前创建socket时已经设置描述字为非阻塞了,所以这个会立即返回-1,就是INVALID_SOCKET,并且errno全局变量的值是11,EWOULDBLOCK,sock_errno也是为了通用
后面的driver_monitor_process是监控调用者erlang进程,然后enq_async_w_tmo实际是保存当前异步请求到一个队列中,核心的是调用sock_select这个函数,并且根据timeout设置了定时器,看下sock_select实现,实际最终调用的是erl_driver.h中定义的
int driver_select(ErlDrvPort port, ErlDrvEvent event, int mode, int on)

实际就是注册当前关心的事件 socket/pipe 读写等事件,由emulator通过 epoll/select 进行event notify,回调的是driver里定义的ready_input/ready_output函数,这里对应的就是
static int tcp_inet_input(tcp_descriptor* desc, HANDLE event)

这个函数无非就是调用accept,然后返回连接描述字,最终通过tcp_inet_copy里的
 /* The new port will be linked and connected to the original caller */
    port = driver_create_port(port, owner, "tcp_inet", (ErlDrvData) copy_desc);

创建了一个新的port返回给erlang端调用,处理后续连接描述字的读写事件

看完这些能对gen_tcp driver异步工作的机制有个大概了解,细节实现还有非常多的地方需要研究,erl_driver.h的实现回头也需要一起看一下


















分享到:
评论
3 楼 huanlong78 2010-02-09  
想学习 , Erlang 苦于无门啊. 想找个师傅 带下 ..
2 楼 bachmozart 2009-10-07  
mryufeng 写道
加油 已经在路上了。


谢谢老大滴鼓励,还有很多的细节没弄懂,我会继续努力滴
1 楼 mryufeng 2009-10-07  
加油 已经在路上了。

相关推荐

    cmsdk_ahb_to_apb_async.v

    cmsdk_ahb_to_apb_async.v

    TCP_ASYNC_SERVER.rar_异步 tcp

    本示例“TCP_ASYNC_SERVER.rar”关注的是异步TCP服务器的实现,这是一种利用Winsock库在Windows平台上构建的高效通信模型。异步TCP服务器不同于同步服务器,因为它能够在处理一个连接的同时接收新的连接请求,从而...

    TCP.rar_TCP IP_c# TCP_tcp_异步TCP

    在C#中,可以通过事件驱动的异步模式(如`BeginConnect`/`EndConnect`,`BeginReceive`/`EndReceive`)或者使用`async`/`await`关键字配合`Task`来实现异步操作。 在这个项目中,`TCP.rar`可能包含了以下部分: 1....

    Tcp.rar_CSharp tcp_tcp_tcp 服务器

    6. **多线程或async/await**:在服务器端,为了处理多个并发连接,通常会使用多线程或者C#的async/await关键字配合Task类实现异步处理,这样可以在不阻塞主线程的情况下处理多个客户端请求。 通过这个示例项目,...

    MODBUS TCP.rar_C#MODBUS TCP_modbus TCP_modbus-tcp c_modbus_tcp_t

    标题中的“MODBUS TCP.rar_C#MODBUS TCP_modbus TCP_modbus-tcp c_modbus_tcp_t”表明这个压缩包文件包含的是关于C#语言实现MODBUS TCP通信的相关资源。MODBUS TCP是一种基于MODBUS协议的网络通信协议,常用于工业...

    Python_gen_async

    在Python编程语言中,"Python_gen_async" 涉及的核心概念是生成器(Generators)和异步编程。这两个特性极大地提升了Python处理大量数据和并发任务的能力。 生成器(Generators)是Python中一种特殊的迭代器,允许...

    Modbus TCP Client_c#modbus_tcp_modbusTCP_源码

    MODBUS TCP Client_c#modbus_tcp_modbusTCP_源码是一个关于使用C#编程语言实现MODBUS TCP协议的客户端程序的示例项目。MODBUS是一种广泛应用于工业自动化领域的通信协议,它允许设备之间进行简单的数据交换。在C#...

    TCP_client.zip_C# TCP client_TCP client_c#tcp client

    此外,C#中的异步编程模型(async/await)也能用于TCP客户端,以实现非阻塞的IO操作,提高程序的响应性。例如,可以将Connect、Read和Write方法改写为异步版本: ```csharp async Task ConnectAsync() { await ...

    gen_server:Erlang 的 gen_server 的(不完整的)OcamlAsync 实现

    而在OCaml语言中,尽管有着自己的并发库如Async,但直接移植或模仿Erlang的gen_server概念可以为OCaml开发者带来更丰富的工具选择。本文将深入探讨如何在OCaml/Async环境下实现类似gen_server的功能,并对这一过程...

    vb_socket_tcp

    在VB(Visual Basic)编程环境中,`vb_socket_tcp`是一个涉及网络通信的重要概念,它主要基于TCP(Transmission Control Protocol)协议来实现客户端和服务器之间的数据交换。TCP是一种面向连接的、可靠的传输层协议...

    TCP.UDP_gaojibiancheng.rar_TCP-UDP_c# tcp/udp_tcp/udp_visual c

    4. **并发处理**:如何在TCP和UDP中处理多个并发连接,包括线程池、异步编程模型(如C#的async/await)和事件驱动编程。 5. **网络安全性**:涉及TCP和UDP在网络安全方面的考量,如SSL/TLS加密通信。 6. **性能...

    TCP.rar_c# tcp通讯_tcp_基于TCP协议_通讯协议 TCP

    TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在C#中实现TCP通信,开发者可以使用.NET框架提供的System.Net.Sockets命名空间中的TcpClient和...

    tcp.rar_C# 监听端口_C++ TCP 监听_tcp 监听_端口监听

    在IT领域,网络通信是不可或缺的一部分,而TCP(Transmission Control Protocol)作为一种面向连接的、可靠的传输层协议,广泛用于各种应用程序。本资料“tcp.rar”包含了一段C#语言实现的端口监听代码,以及可能...

    C#通过TCP传输文件.rar_C#网口传输_tcp_tcp传输文件c#_文件传输_服务端与

    在实际应用中,为了提高效率和用户体验,可以考虑使用异步编程模型,例如使用BeginAcceptTcpClient/EndAcceptTcpClient和BeginSend/EndReceive等异步方法,或者使用async/await语法。同时,考虑到文件大小和网络状况...

    async_fifo.v.rar_FIFO verilog_async fifo_async_fifo.v_fifo veri

    《异步FIFO在Verilog中的实现——深入解析async_fifo.v》 在数字系统设计中,FIFO(First-In-First-Out,先进先出)存储器是一种常用的缓冲数据结构,它能够有效地解决数据传输速率不匹配的问题。在Verilog硬件描述...

    async_fifo.rar_async fifo_async_fifo

    《深入理解Async FIFO:原理与应用》 在计算机系统中,FIFO(First In First Out,先进先出)是一种常见的数据结构,广泛应用于缓存、队列和数据传输等领域。而Async FIFO,即异步FIFO,是FIFO的一种特殊形式,它在...

    Python库 | meilisearch_python_async-0.14.0-py3-none-any.whl

    《Python库meilisearch_python_async-0.14.0-py3-none-any.whl详解》 在Python的世界里,库是开发者的重要工具,它们提供了丰富的功能,简化了编程工作。本文将深入探讨名为“meilisearch_python_async”的Python库...

    vb_soket_TCPIP.zip_VB TCP_VB tcp 多_vb tcpip_vb udp_vb开发soket_TCP

    9. **网络编程概念**:理解IP地址、端口号、套接字(Socket)等网络编程基本概念,以及TCP/UDP通信的工作流程。 10. **异步编程**:VB提供了异步编程模型,如Async/Await关键字,使得在处理网络通信时可以避免阻塞...

    Async-fifo.rar_Tested_async FIFO VHDL_async fifo_asynchronous fi

    在"Async_fifo_vhdl"标签中,我们可以推测这个压缩包可能包含了一个用VHDL编写的异步FIFO实现。VHDL是一种硬件描述语言,它允许设计者用代码来描述数字系统的逻辑行为,然后可以被综合工具转换为具体的电路布局。一...

    dispatch_barrier_(a)sync

    异步和同步的栅栏函数都有以下特点: 1、通过dispatch_barrier_(a)sync添加的block会等待前边所有...ispatch_barrier_async将自己的任务插入到queue之后,不会等待自己的任务结束,它会继续把后面的任务插入到queue。

Global site tag (gtag.js) - Google Analytics