走读 amqp_socket.c 源码,发现若干值得注意的细节: 缓存
【amqp_open_socket 】 socket
在 amqp_open_socket 函数中经过 getaddrinfo 函数进行域名解析可能会产生阻塞。其中参数指定了 函数
struct addrinfo hint; ... hint.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */ hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = IPPROTO_TCP; ...
故其会对IPv4和IPv6地址均进行查询。 学习
建立 socket 时的代码代表,其根据实际状况(IPv4或IPv6)建立对应的socket。 spa
sockfd = (int)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
socket 建立后仅设置了 SO_NOSIGPIPE(该标识仅在 IOS 系统下有效) 和 TCP_NODELAY 选项,以后就进行了 connect 动做,说明该 socket 为阻塞式用法,而且未绑定本地任何地址。这样的结果是 connect 会根据链接到的对端地址自动绑定本地对应地址。 code
另外,因为处理的是阻塞式 socket ,故 connect 仅对出错返回进行了简单处理。惟一可能须要注意的,实现中没有 connect 重连机制,直接结果是对每个地址仅尝试 connect 一次。 rabbitmq
【amqp_send_header】 进程
该函数仅需看一下 send 函数的 flags 便可。 文档
send(state->sockfd, (void *)header, 8, MSG_NOSIGNAL);
设置 send 函数第三个参数为 MSG_NOSIGNAL ,即要求进程不把信号 SIGPIPE 发送给系统,而输出到终端。 rpc
【sasl_method_name】
该函数说明 rabbitmq-c 仅支持 PLAIN SASL ,其他扩展须要本身实现。
【sasl_response】
没啥好说的,只有 response_buf 的内容拼接格式看下就能够。
【wait_frame_inner】
该函数是当前 C 文件最核心的一个。其中包含了用于帧数据解析和生成的 amqp_handle_input 函数,以及用于接收数据 recv 函数。其中 recv 是阻塞点。在 sockfd 上收到的数据先缓存在 sock_inbound_buffer 中,随后会在 while 循环中按协议,逐个按帧解析出来,返回给上层。此代码写的挺精巧,能够学习借鉴。
【amqp_simple_wait_frame】
此函数是对 wait_frame_inner 的封装,并增长了对帧链表的检测和处理。意思是只要帧链表中还有数据待处理就先把其中的数据取出来处理,不然经过 wait_frame_inner 接收帧后再处理。
【amqp_simple_wait_method】
此函数是对 amqp_simple_wait_frame 的封装,并增长了对帧的内容的检测和处理。
【amqp_send_method】
构造待发送帧的内容,内部使用 amqp_send_frame 来发送实际的帧数据。
【amqp_simple_rpc】
该函数是另外一个须要留意的点。其内部经过调用 amqp_send_method 和 wait_frame_inner 实现了简单的 RPC 功能。
经过 wait_frame_inner 获得的帧不必定是 amqp_send_method 方法但愿获得的应答帧,故须要对前者的返回内容进行相应的处理,包括对 channel 关闭、connection 关闭,以及非 method 帧的处理(放进帧链表)。只有在得到正确的应答帧后才返回。
【amqp_simple_rpc_decoded】
此函数是对 amqp_simple_rpc 的封装,仅增长了对数据的组织处理。
【amqp_login_inner】
该函数就是使用上述的函数实现了登录流程中的各个动做:发送协议版本信息、进行 connection 处理、进行 SASL 处理、进行 TUNE 处理。详细请参考协议文档。
【amqp_login】
除了包含 amqp_login_inner 外,额外还增长了对 channel 信令的处理。
以上就是对 amqp_socket.c 内容的所有要点总结,相信有助于你对 rabbitmq-c 的进一步研究。