I am using UNIX domain datagram sockets to send records from multiple clients to a single server in a multithreaded program. Everything is done within one process; I'm sending records from multiple threads to a single thread that acts as the server. All threads are assigned to separate cores using their affinity masks.
It works fine with a single client, but now I am using multiple clients. The server will read data from the socket using select() to return file descriptors that are ready ("set"), then use recvfrom to get the records.
But first I need to write the file descriptors to the fd_set struct so I can use it with select(). I created fd_set as a global struct at the top of the C file that contains the programs to open client and server sockets and pass messages between them:
fd_set fdset;
I create client sockets in this way:
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;
}
The array retvals is passed in and returned with file descriptor and client address. But to be used with select() I need to insert the file descriptor in the fd_set when the socket is created (in the program above).
Normally that wouldn't be a problem if I knew the layout of fd_set. It's defined in 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;
but from that definition I can't tell what the fields are or how to get a file descriptor or array of file descriptors into fd_set.
So my question is: how can I get the file descriptors into fd_set so it can be used with select()?
FD_SET
macro. – Thomas Jager