名称
zmq_socket - 创建 0MQ 套接字
概要
void *zmq_socket (void '*context', int 'type');
描述
zmq_socket() 函数应在指定的 'context' 中创建一个 0MQ 套接字,并返回新创建套接字的非透明句柄。 'type' 参数指定套接字类型,它决定了套接字上通信的语义。
新创建的套接字最初处于未绑定状态,并且不与任何端点相关联。为了建立消息流,套接字必须首先通过 zmq_connect 连接到至少一个端点,或者必须创建一个端点用于通过 zmq_bind 接受传入连接。
一般来说,传统套接字提供了一个同步接口,用于面向连接的可靠字节流 (SOCK_STREAM) 或无连接的不可靠数据报 (SOCK_DGRAM)。相比之下,0MQ 套接字提供了异步消息队列的抽象,具体的排队语义取决于所使用的套接字类型。传统套接字传输字节流或离散数据报,而 0MQ 套接字传输离散的消息。
0MQ 套接字是异步的,这意味着物理连接的建立和断开、重新连接和有效交付的时间对用户来说是透明的,并且由 0MQ 本身组织。此外,如果对端不可用接收消息,消息可能会被排队。
传统套接字只允许严格的一对一(两个对端)、多对一(多个客户端,一个服务器)或在某些情况下的一对多(组播)关系。除了 'ZMQ_PAIR' 和 'ZMQ_CHANNEL' 外,0MQ 套接字可以使用 zmq_connect() 连接到多个端点,同时使用 zmq_bind() 绑定到套接字并接受来自多个端点的传入连接,从而允许多对多关系。
0MQ 既有线程安全的套接字类型,也有非线程安全的套接字类型。在任何情况下,应用程序都不能从多个线程中使用非线程安全的套接字。这样做会导致未定义的行为。
以下是线程安全的套接字: * ZMQ_CLIENT * ZMQ_SERVER * ZMQ_DISH * ZMQ_RADIO * ZMQ_SCATTER * ZMQ_GATHER * ZMQ_PEER * ZMQ_CHANNEL
以下章节介绍了 0MQ 定义的套接字类型,按由相关套接字类型构建的通用消息模式分组。
客户端-服务器模式
客户端-服务器模式用于允许单个 'ZMQ_SERVER' 服务器与一个或多个 'ZMQ_CLIENT' 客户端通信。客户端总是发起对话,之后任一对端都可以异步地向对方发送消息。
客户端-服务器模式由 https://rfc.zeromq.cn/spec:41 正式定义。
注意
|
服务器-客户端仍在草案阶段。 |
ZMQ_CLIENT
一个 'ZMQ_CLIENT' 套接字与一个 'ZMQ_SERVER' 套接字通信。任一对端都可以连接,但通常推荐的模型是绑定 'ZMQ_SERVER' 并连接 'ZMQ_CLIENT'。
如果 'ZMQ_CLIENT' 套接字已建立连接,zmq_send 将接受消息、将它们排队,并以网络允许的最快速度发送。发送缓冲区限制由套接字的高水位线定义。如果发送缓冲区已满,或者对于面向连接的传输,如果设置了 ZMQ_IMMEDIATE 选项且没有连接的对端,zmq_send 将阻塞。'ZMQ_CLIENT' 套接字不会丢弃消息。
当 'ZMQ_CLIENT' 套接字连接到多个 'ZMQ_SERVER' 套接字时,发送消息在连接的对端之间以轮询方式分发。同样,'ZMQ_CLIENT' 套接字公平地从每个连接的对端接收消息。这种用法仅适用于无状态协议。
'ZMQ_CLIENT' 套接字是线程安全的,可以同时从多个线程使用。请注意,来自 'ZMQ_SERVER' 套接字的回复将发送给第一个调用 zmq_msg_recv 的客户端线程。如果您需要将回复返回到发起线程,请为每个线程使用一个 'ZMQ_CLIENT' 套接字。
注意
|
'ZMQ_CLIENT' 套接字是线程安全的。它们在发送时不支持 ZMQ_SNDMORE 选项,在接收时不支持 ZMQ_RCVMORE。这限制了它们只能处理单部分数据。意图是扩展 API 以支持多部分数据的分散/聚集。 |
兼容的对端套接字 |
'ZMQ_SERVER' |
方向 |
双向 |
发送/接收模式 |
不受限制 |
发送路由策略 |
轮询 |
接收路由策略 |
公平排队 |
静默状态下的行为 |
阻塞 |
ZMQ_SERVER
一个 'ZMQ_SERVER' 套接字与一组 'ZMQ_CLIENT' 套接字通信。 'ZMQ_SERVER' 套接字只能回复传入消息:'ZMQ_CLIENT' 对端必须始终发起对话。
每条接收到的消息都有一个 'routing_id',它是一个 32 位无符号整数。应用程序可以使用 zmq_msg_routing_id 获取它。要将消息发送到指定的 'ZMQ_CLIENT' 对端,应用程序必须使用 zmq_msg_set_routing_id 在消息上设置对端的 'routing_id'。
如果未指定 'routing_id',或者它未指向连接的客户端对端,发送调用将失败并返回 EHOSTUNREACH。如果客户端对端的发送缓冲区已满,发送调用将阻塞,除非在发送时使用了 ZMQ_DONTWAIT,在这种情况下将失败并返回 EAGAIN。在任何情况下,'ZMQ_SERVER' 套接字都不应丢弃消息。
注意
|
'ZMQ_SERVER' 套接字是线程安全的。它们在发送时不支持 ZMQ_SNDMORE 选项,在接收时不支持 ZMQ_RCVMORE。这限制了它们只能处理单部分数据。意图是扩展 API 以支持多部分数据的分散/聚集。 |
兼容的对端套接字 |
'ZMQ_CLIENT' |
方向 |
双向 |
发送/接收模式 |
不受限制 |
发送路由策略 |
参见正文 |
接收路由策略 |
公平排队 |
静默状态下的行为 |
返回 EAGAIN |
广播-接收模式
广播-接收模式用于将数据从单个发布者以扇出方式一对多地分发到多个订阅者。
广播-接收使用分组(与发布-订阅的主题相对),接收套接字可以加入一个组,广播套接字发送的每条消息都属于一个组。
组是空终止字符串,长度限制为 16 个字符(包括空字符)。意图是将长度增加到 40 个字符(包括空字符)。组的编码应为 UTF8。
组使用精确匹配(与发布-订阅的前缀匹配相对)进行匹配。
注意
|
广播-接收模式仍在草案阶段。 |
ZMQ_RADIO
类型为 'ZMQ_RADIO' 的套接字由发布者用于分发数据。每条消息都属于一个组,使用 zmq_msg_set_group 指定一个组。消息被分发到组的所有成员。对于此套接字类型,未实现 zmq_recv 函数。
当 'ZMQ_RADIO' 套接字因达到某个订阅者的高水位线而进入“静默”状态时,任何原本要发送给该订阅者的消息将被丢弃,直到静默状态结束。对于此套接字类型,zmq_send() 函数绝不会阻塞。
注意
|
'ZMQ_RADIO' 套接字是线程安全的。它们在发送时不支持 ZMQ_SNDMORE 选项。这限制了它们只能处理单部分数据。 |
兼容的对端套接字 |
'ZMQ_DISH' |
方向 |
单向 |
发送/接收模式 |
仅发送 |
接收路由策略 |
不适用 |
发送路由策略 |
扇出 |
静默状态下的行为 |
丢弃 |
ZMQ_DISH
类型为 'ZMQ_DISH' 的套接字由订阅者用于订阅由广播分发的组。最初,'ZMQ_DISH' 套接字未订阅任何组,使用 zmq_join 加入一个组。要获取消息所属的组,请调用 zmq_msg_group。对于此套接字类型,未实现 zmq_send() 函数。
注意
|
'ZMQ_DISH' 套接字是线程安全的。它们在接收时不支持 ZMQ_RCVMORE。这限制了它们只能处理单部分数据。 |
兼容的对端套接字 |
'ZMQ_RADIO' |
方向 |
单向 |
发送/接收模式 |
仅接收 |
接收路由策略 |
公平排队 |
发送路由策略 |
不适用 |
发布-订阅模式
发布-订阅模式用于将数据从单个发布者以扇出方式一对多地分发到多个订阅者。
发布-订阅模式由 https://rfc.zeromq.cn/spec:29 正式定义。
ZMQ_PUB
类型为 'ZMQ_PUB' 的套接字由发布者用于分发数据。发送的消息以扇出方式分发到所有连接的对端。对于此套接字类型,未实现 zmq_recv 函数。
当 'ZMQ_PUB' 套接字因达到某个订阅者的高水位线而进入“静默”状态时,任何原本要发送给该订阅者的消息将被丢弃,直到静默状态结束。对于此套接字类型,zmq_send() 函数绝不会阻塞。
兼容的对端套接字 |
'ZMQ_SUB', 'ZMQ_XSUB' |
方向 |
单向 |
发送/接收模式 |
仅发送 |
接收路由策略 |
不适用 |
发送路由策略 |
扇出 |
静默状态下的行为 |
丢弃 |
ZMQ_SUB
类型为 'ZMQ_SUB' 的套接字由订阅者用于订阅由发布者分发的数据。最初,'ZMQ_SUB' 套接字未订阅任何消息,使用 zmq_setsockopt 的 'ZMQ_SUBSCRIBE' 选项指定要订阅的消息。对于此套接字类型,未实现 zmq_send() 函数。
兼容的对端套接字 |
'ZMQ_PUB', 'ZMQ_XPUB' |
方向 |
单向 |
发送/接收模式 |
仅接收 |
接收路由策略 |
公平排队 |
发送路由策略 |
不适用 |
ZMQ_XPUB
与 ZMQ_PUB 相同,但你可以接收来自对端以传入消息形式发送的订阅信息。订阅消息是一个字节 1(表示订阅)或字节 0(表示取消订阅),后跟订阅主体。没有订阅/取消订阅前缀的消息也会被接收,但对订阅状态没有影响。
兼容的对端套接字 |
'ZMQ_SUB', 'ZMQ_XSUB' |
方向 |
单向 |
发送/接收模式 |
发送消息,接收订阅 |
接收路由策略 |
不适用 |
发送路由策略 |
扇出 |
静默状态下的行为 |
丢弃 |
ZMQ_XSUB
与 ZMQ_SUB 相同,但你通过向套接字发送订阅消息来订阅。订阅消息是一个字节 1(表示订阅)或字节 0(表示取消订阅),后跟订阅主体。没有订阅/取消订阅前缀的消息也可以发送,但对订阅状态没有影响。
兼容的对端套接字 |
'ZMQ_PUB', 'ZMQ_XPUB' |
方向 |
单向 |
发送/接收模式 |
接收消息,发送订阅 |
接收路由策略 |
公平排队 |
发送路由策略 |
不适用 |
静默状态下的行为 |
丢弃 |
管道模式
管道模式用于将数据分发到按管道排列的节点。数据总是沿管道向下流动,管道的每个阶段都连接到至少一个节点。当管道阶段连接到多个节点时,数据在所有连接的节点之间以轮询方式分发。
管道模式由 https://rfc.zeromq.cn/spec:30 正式定义。
ZMQ_PUSH
类型为 'ZMQ_PUSH' 的套接字由管道节点用于将消息发送到下游管道节点。消息以轮询方式发送到所有连接的下游节点。对于此套接字类型,未实现 zmq_recv() 函数。
当 'ZMQ_PUSH' 套接字因达到所有下游节点的高水位线而进入“静默”状态时,或者对于面向连接的传输,如果设置了 ZMQ_IMMEDIATE 选项且没有任何下游节点,则套接字上的任何 zmq_send 操作将阻塞,直到静默状态结束或至少有一个下游节点可用于发送;消息不会被丢弃。
兼容的对端套接字 |
'ZMQ_PULL' |
方向 |
单向 |
发送/接收模式 |
仅发送 |
接收路由策略 |
不适用 |
发送路由策略 |
轮询 |
静默状态下的行为 |
阻塞 |
ZMQ_PULL
类型为 'ZMQ_PULL' 的套接字由管道节点用于接收来自上游管道节点的消息。消息从所有连接的上游节点中公平排队。对于此套接字类型,未实现 zmq_send() 函数。
兼容的对端套接字 |
'ZMQ_PUSH' |
方向 |
单向 |
发送/接收模式 |
仅接收 |
接收路由策略 |
公平排队 |
发送路由策略 |
不适用 |
静默状态下的行为 |
阻塞 |
分散-聚集模式
分散-聚集模式是管道模式的线程安全版本。分散-聚集模式用于将数据分发到按管道排列的节点。数据总是沿管道向下流动,管道的每个阶段都连接到至少一个节点。当管道阶段连接到多个节点时,数据在所有连接的节点之间以轮询方式分发。
ZMQ_SCATTER
类型为 'ZMQ_SCATTER' 的套接字由分散-聚集节点用于将消息发送到下游分散-聚集节点。消息以轮询方式发送到所有连接的下游节点。对于此套接字类型,未实现 zmq_recv() 函数。
当 'ZMQ_SCATTER' 套接字因达到所有下游节点的高水位线而进入“静默”状态时,或者对于面向连接的传输,如果设置了 ZMQ_IMMEDIATE 选项且没有任何下游节点,则套接字上的任何 zmq_send 操作将阻塞,直到静默状态结束或至少有一个下游节点可用于发送;消息不会被丢弃。
注意
|
'ZMQ_SCATTER' 套接字是线程安全的。它们在接收时不支持 ZMQ_RCVMORE。这限制了它们只能处理单部分数据。 |
兼容的对端套接字 |
'ZMQ_SCATTER' |
方向 |
单向 |
发送/接收模式 |
仅发送 |
接收路由策略 |
不适用 |
发送路由策略 |
轮询 |
静默状态下的行为 |
阻塞 |
ZMQ_GATHER
类型为 'ZMQ_GATHER' 的套接字由分散-聚集节点用于接收来自上游分散-聚集节点的消息。消息从所有连接的上游节点中公平排队。对于此套接字类型,未实现 zmq_send() 函数。
注意
|
'ZMQ_GATHER' 套接字是线程安全的。它们在接收时不支持 ZMQ_RCVMORE。这限制了它们只能处理单部分数据。 |
兼容的对端套接字 |
'ZMQ_GATHER' |
方向 |
单向 |
发送/接收模式 |
仅接收 |
接收路由策略 |
公平排队 |
发送路由策略 |
不适用 |
静默状态下的行为 |
阻塞 |
独占对模式
独占对模式用于将一个对端精确地连接到另一个对端。此模式用于跨进程内传输进行线程间通信。
独占对模式由 https://rfc.zeromq.cn/spec:31 正式定义。
ZMQ_PAIR
类型为 'ZMQ_PAIR' 的套接字一次只能连接到一个对端。通过 'ZMQ_PAIR' 套接字发送的消息不执行消息路由或过滤。
当 'ZMQ_PAIR' 套接字因达到连接对端的高水位线而进入“静默”状态时,或者对于面向连接的传输,如果设置了 ZMQ_IMMEDIATE 选项且没有连接的对端,则套接字上的任何 zmq_send 操作将阻塞,直到对端可用于发送;消息不会被丢弃。
虽然 'ZMQ_PAIR' 套接字可以在 zmq_inproc 之外的传输上使用,但它们无法自动重连,加上当任何先前的连接(包括正在关闭状态的连接)存在时,新的传入连接将被终止,这使得它们在大多数情况下不适合 TCP。
注意
|
'ZMQ_PAIR' 套接字专为跨 zmq_inproc 传输的线程间通信而设计,不实现自动重连等功能。 |
兼容的对端套接字 |
'ZMQ_PAIR' |
方向 |
双向 |
发送/接收模式 |
不受限制 |
接收路由策略 |
不适用 |
发送路由策略 |
不适用 |
静默状态下的行为 |
阻塞 |
对等模式
对等模式用于将一个对端连接到多个对端。对端可以同时连接和绑定,并在同一个套接字上混合使用这两种操作。对等模式对于构建对等网络(例如 zyre、比特币、torrent)非常有用,其中一个对端既可以接受来自其他对端的连接,也可以连接到它们。
注意
|
对等模式仍在草案阶段。 |
ZMQ_PEER
一个 'ZMQ_PEER' 套接字与一组 'ZMQ_PEER' 套接字通信。
要连接并获取对端的 'routing_id',请使用 zmq_connect_peer
每条接收到的消息都有一个 'routing_id',它是一个 32 位无符号整数。应用程序可以使用 zmq_msg_routing_id 获取它。
要将消息发送到指定的 'ZMQ_PEER' 对端,应用程序必须使用 zmq_msg_set_routing_id 在消息上设置对端的 'routing_id'。
如果未指定 'routing_id',或者它未指向连接的对端,发送调用将失败并返回 EHOSTUNREACH。如果对端的发送缓冲区已满,发送调用将阻塞,除非在发送时使用了 ZMQ_DONTWAIT,在这种情况下将失败并返回 EAGAIN。在任何情况下,'ZMQ_PEER' 套接字都不应丢弃消息。
注意
|
'ZMQ_PEER' 套接字是线程安全的。它们在发送时不支持 ZMQ_SNDMORE 选项,在接收时不支持 ZMQ_RCVMORE。这限制了它们只能处理单部分数据。 |
兼容的对端套接字 |
'ZMQ_PEER' |
方向 |
双向 |
发送/接收模式 |
不受限制 |
发送路由策略 |
参见正文 |
接收路由策略 |
公平排队 |
静默状态下的行为 |
返回 EAGAIN |
通道模式
通道模式是独占对模式的线程安全版本。通道模式用于将一个对端精确地连接到另一个对端。此模式用于跨进程内传输进行线程间通信。
注意
|
通道模式仍在草案阶段。 |
ZMQ_CHANNEL
类型为 'ZMQ_CHANNEL' 的套接字一次只能连接到一个对端。通过 'ZMQ_CHANNEL' 套接字发送的消息不执行消息路由或过滤。
当 'ZMQ_CHANNEL' 套接字因达到连接对端的高水位线而进入“静默”状态时,或者对于面向连接的传输,如果设置了 ZMQ_IMMEDIATE 选项且没有连接的对端,则套接字上的任何 zmq_send 操作将阻塞,直到对端可用于发送;消息不会被丢弃。
虽然 'ZMQ_CHANNEL' 套接字可以在 zmq_inproc 之外的传输上使用,但它们无法自动重连,加上当任何先前的连接(包括正在关闭状态的连接)存在时,新的传入连接将被终止,这使得它们在大多数情况下不适合 TCP。
注意
|
'ZMQ_CHANNEL' 套接字专为跨 zmq_inproc 传输的线程间通信而设计,不实现自动重连等功能。 |
注意
|
'ZMQ_CHANNEL' 套接字是线程安全的。它们在接收时不支持 ZMQ_RCVMORE。这限制了它们只能处理单部分数据。 |
兼容的对端套接字 |
'ZMQ_CHANNEL' |
方向 |
双向 |
发送/接收模式 |
不受限制 |
接收路由策略 |
不适用 |
发送路由策略 |
不适用 |
静默状态下的行为 |
阻塞 |
原生模式
原生模式用于与 TCP 对端通信,并允许在任一方向上进行异步请求和回复。
ZMQ_STREAM
类型为 'ZMQ_STREAM' 的套接字用于在使用 tcp:// 传输时,向非 0MQ 对端发送和接收 TCP 数据。'ZMQ_STREAM' 套接字可以充当客户端和/或服务器,异步地发送和/或接收 TCP 数据。
接收 TCP 数据时,'ZMQ_STREAM' 套接字应在将消息传递给应用程序之前,向消息添加一个消息部分,其中包含发起对端的路由 ID。接收到的消息从所有连接的对端中公平排队。
发送 TCP 数据时,'ZMQ_STREAM' 套接字应移除消息的第一个部分,并使用它来确定消息将路由到的对端的路由 ID,无法路由的消息将导致 EHOSTUNREACH 或 EAGAIN 错误。
要打开与服务器的连接,请使用 zmq_connect 调用,然后使用带 ZMQ_ROUTING_ID 选项的 zmq_getsockopt 调用获取套接字路由 ID。
要关闭特定连接,请发送路由 ID 帧,后跟一个零长度消息(参见示例部分)。
建立连接时,应用程序将收到一个零长度消息。类似地,当对端断开连接(或连接丢失)时,应用程序将收到一个零长度消息。
您必须发送一个路由 ID 帧,后跟一个数据帧。路由 ID 帧需要 ZMQ_SNDMORE 标志,但在数据帧上被忽略。
兼容的对端套接字 |
无。 |
方向 |
双向 |
发送/接收模式 |
不受限制 |
发送路由策略 |
参见正文 |
接收路由策略 |
公平排队 |
静默状态下的行为 |
EAGAIN |
请求-回复模式
请求-回复模式用于从 ZMQ_REQ 客户端向一个或多个 ZMQ_REP 服务发送请求,并接收对发送的每个请求的后续回复。
请求-回复模式由 https://rfc.zeromq.cn/spec:28 正式定义。
ZMQ_REQ
类型为 'ZMQ_REQ' 的套接字由客户端用于向服务发送请求并接收回复。此套接字类型只允许交替进行的 zmq_send(request) 和随后的 zmq_recv(reply) 调用序列。发送的每个请求都在所有服务之间以轮询方式分发,接收到的每个回复都与最后发出的请求匹配。
对于面向连接的传输,如果设置了 ZMQ_IMMEDIATE 选项且没有可用服务,则套接字上的任何发送操作将阻塞,直到至少有一个服务可用。REQ 套接字不应丢弃消息。
兼容的对端套接字 |
'ZMQ_REP', 'ZMQ_ROUTER' |
方向 |
双向 |
发送/接收模式 |
发送,接收,发送,接收,…… |
发送路由策略 |
轮询 |
接收路由策略 |
最后对端 |
静默状态下的行为 |
阻塞 |
ZMQ_REP
类型为 'ZMQ_REP' 的套接字由服务用于接收来自客户端的请求并发送回复。此套接字类型只允许交替进行的 zmq_recv(request) 和随后的 zmq_send(reply) 调用序列。接收到的每个请求都从所有客户端中公平排队,发送的每个回复都路由到发起最后请求的客户端。如果原始请求者不再存在,则回复会被静默丢弃。
兼容的对端套接字 |
'ZMQ_REQ', 'ZMQ_DEALER' |
方向 |
双向 |
发送/接收模式 |
接收,发送,接收,发送,…… |
接收路由策略 |
公平排队 |
发送路由策略 |
最后对端 |
ZMQ_DEALER
类型为 'ZMQ_DEALER' 的套接字是一种用于扩展请求/回复套接字的高级模式。发送的每条消息都在所有连接的对端之间以轮询方式分发,接收到的每条消息都从所有连接的对端中公平排队。
当 'ZMQ_DEALER' 套接字因达到所有对端的高水位线而进入“静默”状态时,或者对于面向连接的传输,如果设置了 ZMQ_IMMEDIATE 选项且没有任何对端,则套接字上的任何 zmq_send 操作将阻塞,直到静默状态结束或至少有一个对端可用于发送;消息不会被丢弃。
当 'ZMQ_DEALER' 套接字连接到 'ZMQ_REP' 套接字时,发送的每条消息必须由一个空消息部分(即分隔符)组成,后跟一个或多个消息体部分。
兼容的对端套接字 |
'ZMQ_ROUTER', 'ZMQ_REP', 'ZMQ_DEALER' |
方向 |
双向 |
发送/接收模式 |
不受限制 |
发送路由策略 |
轮询 |
接收路由策略 |
公平排队 |
静默状态下的行为 |
阻塞 |
ZMQ_ROUTER
类型为 'ZMQ_ROUTER' 的套接字是一种用于扩展请求/回复套接字的高级套接字类型。接收消息时,'ZMQ_ROUTER' 套接字应在将消息传递给应用程序之前,向消息添加一个消息部分,其中包含发起对端的路由 ID。接收到的消息从所有连接的对端中公平排队。发送消息时,'ZMQ_ROUTER' 套接字应移除消息的第一个部分,并使用它来确定消息将路由到的对端的路由 ID。如果对端不再存在或从未存在,消息将被静默丢弃。但是,如果将 'ZMQ_ROUTER_MANDATORY' 套接字选项设置为 '1',套接字在这两种情况下都将失败并返回 EHOSTUNREACH。
当 'ZMQ_ROUTER' 套接字因达到所有对端的高水位线而进入“静默”状态时,发送到该套接字的任何消息都将被丢弃,直到静默状态结束。同样,路由到已达到各自高水位线的对端的任何消息也将被丢弃。如果 'ZMQ_ROUTER_MANDATORY' 设置为 '1',套接字在这两种情况下都将阻塞或返回 EAGAIN。
当 'ZMQ_ROUTER' 套接字设置了 'ZMQ_ROUTER_MANDATORY' 标志为 '1' 时,在接收到一个或多个对端的消息时,套接字应生成 'ZMQ_POLLIN' 事件。同样,当至少有一条消息可以发送到一个或多个对端时,套接字应生成 'ZMQ_POLLOUT' 事件。
当 'ZMQ_REQ' 套接字连接到 'ZMQ_ROUTER' 套接字时,除了发起对端的路由 ID 外,接收到的每条消息都应包含一个空的分隔符消息部分。因此,应用程序看到的每条接收消息的完整结构变为:一个或多个路由 ID 部分、分隔符部分、一个或多个消息体部分。向 'ZMQ_REQ' 套接字发送回复时,应用程序必须包含分隔符部分。
兼容的对端套接字 |
'ZMQ_DEALER', 'ZMQ_REQ', 'ZMQ_ROUTER' |
方向 |
双向 |
发送/接收模式 |
不受限制 |
发送路由策略 |
参见正文 |
接收路由策略 |
公平排队 |
静默状态下的行为 |
丢弃(参见正文) |
返回值
如果成功,zmq_socket() 函数应返回新创建套接字的非透明句柄。否则,它应返回 NULL 并将 'errno' 设置为下面定义的值之一。
错误
- EINVAL
-
请求的套接字 'type' 无效。
- EFAULT
-
提供的 'context' 无效。
- EMFILE
-
已达到打开 0MQ 套接字总数的限制。
- ETERM
-
指定的 context 已关闭或终止。
示例
void *ctx = zmq_ctx_new (); assert (ctx); /* Create ZMQ_STREAM socket */ void *socket = zmq_socket (ctx, ZMQ_STREAM); assert (socket); int rc = zmq_bind (socket, "tcp://*:8080"); assert (rc == 0); /* Data structure to hold the ZMQ_STREAM routing id */ uint8_t routing_id [256]; size_t routing_id_size = 256; /* Data structure to hold the ZMQ_STREAM received data */ uint8_t raw [256]; size_t raw_size = 256; while (1) { /* Get HTTP request; routing id frame and then request */ routing_id_size = zmq_recv (socket, routing_id, 256, 0); assert (routing_id_size > 0); do { raw_size = zmq_recv (socket, raw, 256, 0); assert (raw_size >= 0); } while (raw_size == 256); /* Prepares the response */ char http_response [] = "HTTP/1.0 200 OK\r\n" "Content-Type: text/plain\r\n" "\r\n" "Hello, World!"; /* Sends the routing id frame followed by the response */ zmq_send (socket, routing_id, routing_id_size, ZMQ_SNDMORE); zmq_send (socket, http_response, strlen (http_response), 0); /* Closes the connection by sending the routing id frame followed by a zero response */ zmq_send (socket, routing_id, routing_id_size, ZMQ_SNDMORE); zmq_send (socket, 0, 0, 0); } zmq_close (socket); zmq_ctx_destroy (ctx);
作者
此页面由 0MQ 社区编写。要进行修改,请阅读 0MQ 贡献政策:https://zeromq.cn/how-to-contribute/。