共计 1777 个字符,预计需要花费 5 分钟才能阅读完成。
UDP 是一个比较常用的传输层协议,erlang 标准库中提供了 gen_dup 模块,要掌握 UDP 协议,我们首先要熟悉这个模块。
函数
首先看这个模块的几个公共函数:
open <> close
send <> recv
connect
controlling_process
fdopen
open 和 close 比较好理解,就是在某个端口上打开一个 socket,以及关闭某个 socket。
send 就是通过某个 socket,往某个地址的某个端口发送 packet。recv 就是接受某个 socket 中一定长度的数据。
connect 就有点奇怪了,我们知道 UDP 协议是无连接的。事实上这个函数并没有文档,不是暴露给普通用户使用的。
controlling_process 是为某个 socket 赋予一个新的归属进程。在 erlang 里,有很多的进程,他们之间相互传递消息来通信,socket 从外界接收到的消息,自然也要先传递到某个进程里,才可以进入 erlang 的世界。归属进程的作用就是接收 socket 的消息。
fdopen 这个函数也没有文档,作用是从某个文件描述符来打开一个 socket。
选项
open,也就是打开一个 socket 的时候需要传入 Option 设置,有下列选项:
list | binary | {mode, list | binary} 以列表还是字符串的形式接收 Packet。
{ip, Address} 当 host 有多个网络接口的时候,选择其中一个。
{ifaddr, Address} 和 {ip, Address} 一样的。
{fd, integer() >= 0} 如果有 socket 不是使用 gen_udp 来打开的,那么就可能需要设置一个文件描述符。
inet6 | inet | local 设置 socket 的类型。
{udp_module, module()} 覆盖默认的 udp 模块。
{multicast_if, Address} 为多播 socket 设置本地设备。
{multicast_loop, true | false} 为真时,多播的 packets 会循环地返回到本地 socket。
{multicast_ttl, Integer} 多播的 TTL,默认是 1.
{add_membership, {MultiAddress, InterfaceAddress}} 加入多播群。
{drop_membership, {MultiAddress, InterfaceAddress}} 离开多播群。
{active, true | false | once | N} 如果为真,socket 收到的所有消息会发送到归属进程。如果为假,就需要显式调用 recv;once 是收到消息后,就会发送到进程,但会变为 false。数值是指接收多少条数据。
{buffer, Size} 用户层级的缓冲区大小。
{delay_send, Boolean} 通常 erlang 会立刻发出给 socket 的消息,开启这个选项后,会等待一会儿然后集合发出。
{deliver, port | term} 发送给归属进程的消息的格式。
{dontroute, Boolean} 对于发出的消息是否采用路由。
{exit_on_close, Bloolean} socket 关闭时退出归属进程。
{header, Size} 只有当 binary 起作用时才有用,单位是 byte。
选项太多了,下列的在之后有用到的话再来解释:
{high_msgq_watermark, Size}
{ipv6_v6only, Boolean}
{linger, {true | false, Seconds}}
{low_msgq_watermark, Size}
{netns, Namespace :: file:filename_all()}
{bind_to_device, Ifname :: binary()}
{raw, Protocol, OptionNum, ValueBin}
{read_packets, Integer}
{recbuf, Size}
{recvtclass, Boolean}
{recvtos, Boolean}
{recvttl, Boolean}
{reuseaddr, Boolean}
{send_timeout, Integer}
{send_timeout_close, Boolean}
{sndbuf, Size}
{priority, Integer}
{tos, Integer}
{tclass, Integer}