资讯专栏INFORMATION COLUMN

使用 Nim 语言和使用 C 语言, 调用系统 POSIX 接口传递文件描述符的对比

ACb0y / 2050人阅读

摘要:进程组之间传递文件描述符是多进程服务器共享套接字常用的方式基于此方式可以提供使每个服务器获得平衡的负载和语言调用相同的接口的编程方式如下事实上是调用的接口

进程组之间传递文件描述符, 是多进程服务器共享套接字常用的方式. 基于此方式, 可以提供 round-robin , 使每个服务器获得平衡的负载.

Nim 和 C 语言调用相同的 POSIX 接口的编程方式如下, (事实上, Nim 是调用的 C POSIX 接口)

Nim
import posix

proc CMSG_LEN(length: cuint): cint {.importc, header: "".}

proc socketpair(fds: var array[0..1, cint]): int {.inline.} =
    result = socketpair(AF_UNIX, SOCK_STREAM, 0, fds)

var 
    pipeFds: array[0 .. 1, cint]
    sockFds: array[0 .. 1, cint]

assert socketpair(pipeFds) == 0
assert socketpair(sockFds) == 0

####################### send model ###########################

var 
    sfd = pipeFds[0].SocketHandle()
    sDataBuff = [""]
    sIov = [TIOVec(iov_base: sDataBuff[0].addr(), iov_len: 1)]
    sCmsglen = CMSG_LEN(sizeof(SocketHandle).cuint())       # 20
    sCmsg = createU(Tcmsghdr, sCmsglen)
    sMsg = Tmsghdr(msg_name: nil, 
                   msg_namelen: 0,
                   msg_iov: sIov[0].addr(),
                   msg_iovlen: 1,
                   msg_control: sCmsg,
                   msg_controllen: sCmsglen.Socklen())

sCmsg.cmsg_len  = sCmsglen.Socklen()
sCmsg.cmsg_level = SOL_SOCKET
sCmsg.cmsg_type = SCM_RIGHTS
(cast[ptr int](CMSG_DATA(sCmsg)))[] = sockFds[0]

assert sfd.sendmsg(sMsg.addr(), 0) == 1
free(sCmsg)

####################### recv model ###########################

var 
    rfd = pipeFds[1].SocketHandle()
    rDataBuff = [""]
    rIov = [TIOVec(iov_base: rDataBuff[0].addr(), iov_len: 1)]
    rCmsglen = CMSG_LEN(sizeof(SocketHandle).cuint())       # 20
    rCmsg = createU(Tcmsghdr, rCmsglen)
    rMsg = Tmsghdr(msg_name: nil, 
                   msg_namelen: 0,
                   msg_iov: rIov[0].addr(),
                   msg_iovlen: 1,
                   msg_control: rCmsg,
                   msg_controllen: rCmsglen.Socklen())

assert rfd.recvmsg(rMsg.addr(), 0) == 1
assert rCmsg.cmsg_len == rCmsglen.Socklen()
assert rCmsg.cmsg_level == SOL_SOCKET
assert rCmsg.cmsg_type == SCM_RIGHTS
echo((cast[ptr int](CMSG_DATA(rCmsg)))[]) 

free(rCmsg)
C
#include 
#include 
#include 
#include 

int main(int argc, char **argv) {
    int pipeFds[1];
    int sockFds[1];

    assert(socketpair(AF_UNIX, SOCK_STREAM, 0, pipeFds) == 0);
    assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sockFds) == 0);

    /********************* send model *********************/

    struct msghdr sMsg;
    struct iovec sIov[1];
    char sDataBuff[1] = "";
    int sCmsglen = CMSG_LEN(sizeof(int));              // 20
    struct cmsghdr *sCmsg = malloc(sCmsglen);

    sIov[0].iov_base = sDataBuff;
    sIov[0].iov_len  = 1;

    sMsg.msg_name = NULL; 
    sMsg.msg_namelen = 0;
    sMsg.msg_iov = sIov;
    sMsg.msg_iovlen = 1;
    sMsg.msg_control = sCmsg;
    sMsg.msg_controllen = sCmsglen;                     // 20

    sCmsg->cmsg_len = sCmsglen;                         // 20
    sCmsg->cmsg_level = SOL_SOCKET;
    sCmsg->cmsg_type  = SCM_RIGHTS;
    *((int *)(CMSG_DATA(sCmsg))) = sockFds[0];

    assert(sendmsg(pipeFds[0], &sMsg, 0) == 1);
    free(sCmsg);

    /********************* recv model *********************/
    
    struct msghdr rMsg;
    struct iovec rIov[1];
    char rDataBuff[1] = "";
    int rCmsglen = CMSG_LEN(sizeof(int));               // 20
    struct cmsghdr *rCmsg = malloc(rCmsglen);

    rIov[0].iov_base = rDataBuff;
    rIov[0].iov_len  = 1;

    rMsg.msg_name = NULL; 
    rMsg.msg_namelen = 0;
    rMsg.msg_iov = rIov;
    rMsg.msg_iovlen = 1;
    rMsg.msg_control = rCmsg;
    rMsg.msg_controllen = rCmsglen;                     // 20

    assert(recvmsg(pipeFds[1], &rMsg, 0) == 1);
    
    assert(rCmsg->cmsg_len == rCmsglen);
    assert(rCmsg->cmsg_level == SOL_SOCKET);
    assert(rCmsg->cmsg_type == SCM_RIGHTS);
    printf("%d
", *((int *)(CMSG_DATA(rCmsg))));       // 7

    free(rCmsg);
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/15168.html

相关文章

  • 使用 Nim 语言使用 C 语言, 调用系统 POSIX 接口传递文件描述符的对比

    摘要:进程组之间传递文件描述符是多进程服务器共享套接字常用的方式基于此方式可以提供使每个服务器获得平衡的负载和语言调用相同的接口的编程方式如下事实上是调用的接口 进程组之间传递文件描述符, 是多进程服务器共享套接字常用的方式. 基于此方式, 可以提供 round-robin , 使每个服务器获得平衡的负载. Nim 和 C 语言调用相同的 POSIX 接口的编程方式如下, (事实上, Ni...

    Chao 评论0 收藏0
  • [原创]nim与rust的特点比较

    摘要:与的特点比较这两个目前都是小众语言做了些时间的研究写了点东西有了点心得相似点有卫生宏区别与的不卫生宏在类或定义体之外定义函数代码没有分成头与实现体例如的头与实现的与定义的接口定义与实现定义是分开的而与是不分开的运用函数式编程高阶函数目前是新 nim与rust的特点比较 这两个目前都是小众语言,做了些时间的研究,写了点东西有了点心得 相似点: 有卫生宏.区别与C++的(不卫生)宏 在类...

    DevTalking 评论0 收藏0
  • 并发编程导论

    摘要:并发编程导论是对于分布式计算并发编程系列的总结与归纳。并发编程导论随着硬件性能的迅猛发展与大数据时代的来临,并发编程日益成为编程中不可忽略的重要组成部分。并发编程复兴的主要驱动力来自于所谓的多核危机。 并发编程导论是对于分布式计算-并发编程 https://url.wx-coder.cn/Yagu8 系列的总结与归纳。欢迎关注公众号:某熊的技术之路。 showImg(https://...

    Jiavan 评论0 收藏0
  • 并发编程导论

    摘要:并发编程导论是对于分布式计算并发编程系列的总结与归纳。并发编程导论随着硬件性能的迅猛发展与大数据时代的来临,并发编程日益成为编程中不可忽略的重要组成部分。并发编程复兴的主要驱动力来自于所谓的多核危机。 并发编程导论是对于分布式计算-并发编程 https://url.wx-coder.cn/Yagu8 系列的总结与归纳。欢迎关注公众号:某熊的技术之路。 showImg(https://...

    GeekQiaQia 评论0 收藏0
  • [原创][连载]nim与python的异同1

    摘要:与的异同名词方法与函数同义仅仅是语言规定差异在本文中不做区别都是指定义的处理过程的有返回值没有返回值版之后出现的方法专指类中的函数的方法指无返回值的处理函数指有返回值的处理中的方法指无返回值的处理函数指有返回值的处理主模块的判断空代码为保 nim与python的异同 名词:方法与函数同义.仅仅是语言规定差异.在本文中不做区别. 1. python都是指def定义的处理过程 2. nim...

    wuaiqiu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<