繁体   English   中英

C UNIX 数据报 sockets — 如何将文件描述符放入 fd_set

[英]C UNIX datagram sockets — how to get file descriptor into fd_set

我正在使用 UNIX 域数据报 sockets 将记录从多个客户端发送到多线程程序中的单个服务器。 一切都在一个过程中完成; 我将记录从多个线程发送到充当服务器的单个线程。 所有线程都使用它们的关联掩码分配给单独的核心。

它适用于单个客户端,但现在我使用多个客户端。 服务器将使用 select() 从套接字读取数据以返回准备好的文件描述符(“set”),然后使用 recvfrom 获取记录。

但首先我需要将文件描述符写入 fd_set 结构,以便我可以将它与 select() 一起使用。 我在 C 文件的顶部创建了 fd_set 作为全局结构,该文件包含打开客户端和服务器 sockets 并在它们之间传递消息的程序:

fd_set fdset;

我以这种方式创建客户端 sockets:

int64_t * create_socket_client(struct sockaddr_un claddr, int64_t retvals[])
{
    int sfd, j;
    size_t msgLen;
    ssize_t numBytes;
    char resp[BUF_SIZE];

    retvals[0] = 0;
    retvals[1] = 0;

    sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (sfd == -1)
        return retvals;

    memset(&claddr, 0, sizeof(struct sockaddr_un));
    claddr.sun_family = AF_UNIX;
    snprintf(claddr.sun_path, sizeof(claddr.sun_path),  "/tmp/ud_ucase_cl.%ld", (long) getpid());

    retvals[0] = sfd;
    retvals[1] = (int64_t)&claddr;

     return retvals;
}

数组 retvals 被传入并与文件描述符和客户端地址一起返回。 但是要与 select() 一起使用,我需要在创建套接字时(在上面的程序中)将文件描述符插入到 fd_set 中。

如果我知道 fd_set 的布局,通常这不会是一个问题。 它在 sys/select.h 中定义:

/* fd_set for select and pselect.  */
typedef struct
  {
    /* XPG4.2 requires this member name.  Otherwise avoid the name
       from the global namespace.  */
#ifdef __USE_XOPEN
    __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
#else
    __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif
  } fd_set;

但从该定义中,我无法判断字段是什么或如何将文件描述符或文件描述符数组放入 fd_set。

所以我的问题是:如何将文件描述符放入 fd_set 以便它可以与 select() 一起使用?

操作fd_set的方法是使用以下宏(来自select()man页):

void FD_CLR(int fd, fd_set *set);
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);

一个新的fd_set在使用前必须被清除:

FD_ZERO(&my_fd_set);

要在fd_set中设置文件描述符,请执行以下操作:

FD_SET(my_fd, &my_fd_set);

同样,要从fd_set中删除 fd,请执行以下操作:

FD_CLR(my_fd, &my_fd_set);

测试是否在fd_set中设置了文件描述符(即测试哪些描述符返回就绪):

if (FD_ISSET(my_fd, &my_fd_set)) {
    // Take action on my_fd
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM