【发布时间】:2020-09-08 12:39:46
【问题描述】:
我正在使用 UNIX 域数据报套接字将记录从多个客户端发送到多线程程序中的单个服务器。一切都在一个过程中完成;我将记录从多个线程发送到充当服务器的单个线程。所有线程都使用它们的关联掩码分配给单独的核心。
它适用于单个客户端,但现在我使用多个客户端。服务器将使用 select() 从套接字读取数据以返回准备好的文件描述符(“set”),然后使用 recvfrom 获取记录。
但首先我需要将文件描述符写入 fd_set 结构,以便我可以将它与 select() 一起使用。我在 C 文件的顶部创建了 fd_set 作为全局结构,其中包含打开客户端和服务器套接字并在它们之间传递消息的程序:
fd_set fdset;
我以这种方式创建客户端套接字:
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宏。