以前不是很了解Erlang网络编程中流量控制,现在做一下笔记。
Erlang中Socket设置了{active, true}之后,接收到的网络消息会通过{tcp, Socket, Data}的格式主动发送给进程,这样做有个弊处就是没有做流量控制。要是有个客户端疯狂发包过来,服务器不做处理就等着堆溢出。
在《Programming Erlang》的14.2里面,介绍可以使用 {active, once} 来做控制。
{ok, Listen} = gen_tcp:listen(Port, [..,{active, once}...]),
{ok, Socket} = gen_tcp:accept(Listen),
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Data} ->
... do something with the data ...
%% when you're ready enable the next message
inet:setopts(Sock, [{active, once}]),
loop(Socket);
{tcp_closed, Socket} ->
...
end.
不过
锋爷认为这种做法会影响性能,因为每次接收信息都要调用一次 inet:setopts(Sock, [{active, once}]) 。
既然这样,那就先使用{active, true},如果判断到接收到的消息包太多,再改成 {active, once}。我写了个简单的代码:
listen_socket(Socket, Mode) ->
receive
{tcp, Socket, Bin} ->
process_req(Bin),
{message_queue_len, MsgQueueSize} = erlang:process_info(self(), message_queue_len),
if
(MsgQueueSize > 500) and (Mode =:= active_true) ->
io:format("Queue size is ~p~n", [MsgQueueSize]),
inet:setopts(Socket, [{active, once}]),
listen_socket(Socket, active_once);
(MsgQueueSize < 10) and (Mode =:= active_once) ->
io:format("Queue size is ~p~n", [MsgQueueSize]),
inet:setopts(Socket, [{active, true}]),
listen_socket(Socket, active_true);
true ->
io:format("Queue size is ~p~n", [MsgQueueSize]),
listen_socket(Socket, Mode)
end;
判断当前进程消息队列的数量,大于500时被动接收,小于10时再次改为主动接收。
打开服务器后,客户端使用阻塞方式({active, false})连续来发送2000个消息包给服务器,很快服务器端的消息累计达到500以上,此时{active, once}被设置,数据包开始在系统底层堆积,很快就看到客户端的gen_tcp:send调用被阻塞,直到服务器设置{active, true}后,堆积的消息被加载到内存消息队列中,gen_tcp:send恢复正常发送。
可见当{active, once}被设置后,若消息队列中还有数据包,则系统底层的数据包会被堆积,起到了流量控制的作用。
分享到:
相关推荐
本程序是一个利用Delphi进行Socket通信的示例,包含了源代码,并且可以直接运行。 在Delphi中,Socket通信主要涉及两个关键组件:TServerSocket和TClientSocket。它们是VCL(Visual Component Library)库中的网络...
2. **客户端连接:** 在客户端程序中创建TClientSocket,设置Host和Port属性为服务器的信息,然后将Active设为True,客户端尝试连接。 3. **连接建立:** 当ServerSocket的OnAccept事件触发时,说明客户端已经连接...
4. 启动和停止服务器:在应用程序运行时,调用`TIdTCPServer.Active := True`启动服务器监听,`TIdTCPServer.Active := False`则会停止监听。 5. 安全性和错误处理:为了确保系统的稳定性和安全性,需要考虑SSL/TLS...
Socket通信是一种基于TCP/IP协议族实现的网络通信方式,它允许两台计算机通过网络进行双向通信。在Delphi编程环境中,Socket通信常被用于构建服务器和客户端应用,以实现数据的实时交换。在这个Demo中,我们看到有...
Server.Active := True; finally Server.Free; end; end; procedure TForm1.HandleServerExecute(AContext: TIdContext); var Data: string; begin Data := AContext.Connection.IOHandler.ReadLn; A...
本实例将深入探讨如何使用Delphi进行TCP/IP Socket通信,这对于构建分布式系统、实现客户端与服务器之间的数据交换具有极大的价值。 TCP/IP协议栈是互联网的核心,它定义了不同设备如何在网络中交换数据。TCP(传输...
在这个“delphi socket通讯 demo”中,我们将深入探讨如何使用Delphi 7中的TServerSocket和TClientSocket组件进行套接字通信。 首先,让我们了解什么是套接字(Socket)。套接字是操作系统提供的一个接口,允许程序...
对于服务器端,设置 TServerSocket 的 Active 属性为 True 来启动监听。 4. **数据交换**: 通过 Socket 组件的 SendData 和 ReceiveData 方法来发送和接收数据。注意,发送的数据需要先转换成字符串或二进制格式。 5...
Server.Active := True; end; procedure TForm1.ServerExecute(AContext: TIdContext); var Data: string; begin Data := AContext.Connection.IOHandler.ReadLn(); ShowMessage('Received: ' + Data); ...
使用TIdTCPServer组件时,需要设置其Active属性为True,指定监听的Port,并绑定到IP地址。 3. **连接Socket**:客户端程序通过TIdTCPClient组件连接到服务器的指定端口。连接成功后,客户端和服务端就可以通过...
在Delphi中,可以使用TServerSocket组件来创建服务器,将其Active属性设置为True以启动监听。TServerSocket组件会在指定的端口上等待连接请求。我们还需要一个TClientSocket组件来模拟客户端,用于建立与服务器的...
2. 开启监听,调用 `Active := True`。 3. 在 `OnExecute` 事件中,处理客户端的连接和数据交换。 4. 关闭连接,如果需要,可以在适当时候断开客户端连接。 在学习这个基础示例时,初学者会了解到如何设置Socket...
- 绑定端口:设置TServerSocket的Active属性为True后,它会监听指定的Port,等待客户端连接。 - 连接事件:当有新的客户端连接时,触发OnAccept事件。此时,可以在事件处理函数中创建新的线程来处理该连接。 2. ...
2. **启动服务器**:调用TIdTCPServer的Active属性设为True,服务器开始监听。在OnExecute事件中,我们可以编写代码来接收和发送数据。 3. **客户端连接**:在客户端,使用TIdTCPClient组件,设置Server属性为...
在编写程序时,首先要对TServerSocket(在服务器端)与TClientSocket(在客户端)进行实例化。对于TServerSocket的对象,主要设置其服务类型(ServerType)与端口(Port)的属性,然后编写“OnClientRead”事件...
- 连接到服务器,设置Active为True。 - 在OnConnect事件中,表示连接成功,可以开始发送和接收数据。 - 发送数据到服务器,可以通过TClientSocket的Write方法。 - 在OnDataAvailable事件中,读取服务器返回的...
在示例代码中,我们可能会看到TServerSocket的属性如`Active`被设置为True,使得服务器处于监听状态;`Port`属性则指定服务器监听的端口号,通常需要根据实际需求进行设定。 2. **TClientSocket组件**:对应于...
- 异步模式:如果需要在用户界面线程之外处理网络操作,可以设置Socket组件的Active属性为True,并在OnExecute事件中处理数据读写。 - 数据格式:由于网络通信是字节流,因此需要定义数据的序列化和反序列化方式,如...
本篇将深入探讨如何在Delphi 7环境中利用Socket进行服务端和客户端的开发。Delphi 7是一款经典的面向对象的 Pascal 编程工具,它内置了强大的VCL(Visual Component Library)框架,使得Socket编程变得相对简单。 ...