butil::EndPoint已经支持UDS(Unix Domain Socket)及IPV6。
代码用法:
EndPoint ep; str2endpoint("unix:path.sock", &ep); // 初始化一个UDS的EndPoint str2endpoint("[::1]:8086", &ep); // 初始化一个IPV6的EndPoint str2endpoint("[::1]", 8086, &ep); // 初始化一个IPV6的EndPoint // 获取EndPoint的类型 sa_family_t type = get_endpoint_type(ep); // 可能为AF_INET、AF_INET6或AF_UNIX // 使用EndPoint,和原来的方式一样 LOG(DEBUG) << ep; // 打印EndPoint std::string ep_str = endpoint2str(ep).c_str(); // EndPoint转str tcp_listen(ep); // 用监听EndPoint表示的tcp端口 tcp_connect(ep, NULL); // 用连接EndPoint表示的tcp端口 sockaddr_storage ss; socklen_t socklen = 0; endpoint2sockaddr(ep, &ss, &socklen); // 将EndPoint转为sockaddr结构,以便调用系统函数
只需要在原来输入IPV4字符串的时候,填写UDS路径或IPV6地址即可,如:
server.Start("unix:path.sock", options); // 启动server监听UDS地址 server.Start("[::0]:8086", options); // 启动server监听IPV6地址 channel.Init("unix:path.sock", options); // 初始化single server的Channel,访问UDS地址 channel.Init("list://[::1]:8086,[::1]:8087", "rr", options); // 初始化带LB的Channel,访问IPV6地址
通过 example/echo_c++ ,展示了如何使用UDS或IPV6:
./echo_server -listen_addr='unix:path.sock' & # 启动Server监听UDS地址 ./echo_server -listen_addr='[::0]:8080' & # 启动Server监听IPV6端口 ./echo_client -server='unix:path.sock' # 启动Client访问UDS地址 ./echo_client -server='[::1]:8080' # 启动Client访问IPV6端口
由于EndPoint结构被广泛地使用,为了保证对存量代码的兼容性(包括ABI兼容性),目前采用的实现方式是不修改EndPoint的ABI定义,使用原来的ip字段作为id,port字段来做为扩展标记,把真正的信息存在一个外部的数据结构中。
这种实现方式对于现存的仅使用IPV4的代码是完全兼容的,但对于使用UDS或IPV6的用户,有些代码是不兼容的,比如直接访问EndPoint的ip和port成员的代码。
关于UDS和IPV6,目前已知的一些限制: