Reputation: 572
Is there anyway of printing the state of a socket in a fd_set?
Say i have this code:
int main(int argc, char * argv[]) {
int sockfd, newfd, i;
struct sockaddr_un sv_addr, cli_addr;
int sv_len, cli_len;
fd_set testmask, mask;
if ((sockfd = socket(AF_UNIX,SOCK_STREAM,0))<0) {
perror("Error creating socket");
exit(-1);
}
bzero((char*)&sv_addr,sizeof(sv_addr));
sv_addr.sun_family = AF_UNIX;
strcpy(sv_addr.sun_path,UNIXSTR_PATH);
sv_len=sizeof(sv_addr.sun_family)+strlen(sv_addr.sun_path);
unlink(UNIXSTR_PATH);
if(bind(sockfd,(struct sockaddr*)&sv_addr,sv_len)<0) {
perror("Error binding socket");
exit(-1);
}
listen(sockfd, 15);
FD_ZERO(&testmask);
FD_SET(sockfd,&testmask);
for(;;) {
mask = testmask;
select(MAXSOCKS,&mask,0,0,0);
if(FD_ISSET(sockfd,&mask)) {
cli_len = sizeof(cli_addr);
newfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
echo(newfd);
close(newfd);
}
for(i=0;i<MAXSOCKS;i++) {
if (FD_ISSET(i, &mask)) {
close(i);
FD_CLR(i, &mask);
}
}
}
close(sockfd);
return 0;
}
Everything is working in my program (its an echo server, the client sends a line and the server just echos it back). I would like to, after the select call, print in the server terminal something like; 00011011011 This means, print the socks that are ready to be handled. Is there anyway i could do this?
Also, what should i do in the end of the for loop? I know i have to somehow clear the fd_set. The way i did it (the small for loop closing and FD_CLR the fd_set) its correct? Or i should i do it another way?
PS: Sorry for my english or any mistakes. :)
Upvotes: 3
Views: 5727
Reputation: 70931
[This does not answer your question, but refers to a comment to the OP and is too long for another comment]
From man select
:
nfds is the highest-numbered file descriptor in any of the three sets, plus 1.
nfds
is not a constant! The man-pages does not read:
[...] the highest-possible-numbered file descriptor [...]
nfds
dynamically has to describe the fd_set
s passed to select()
.
int nfds = sockfd + 1;
for(;;) {
mask = testmask;
select(nfds, &mask, 0, 0, 0);
if(FD_ISSET(sockfd,&mask)) {
cli_len = sizeof(cli_addr);
newfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
echo(newfd);
close(newfd);
}
for(i = 0; i < nfds; ++i) {
if (FD_ISSET(i, &mask)) {
close(i);
FD_CLR(i, &mask);
}
}
}
Adjust nfds
for every socket descriptor being add to fd_set
passed to select()
.
Upvotes: 2
Reputation: 1
After select call you checked the sockfd. If that's true, means that a client try to connect your server. Then you accept the connection.
newfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
newfd is the fd number you know, between client and server. Here, you don't still read the clientfd(newfd) data. After the connection accepted, you read data on the clentfd like that
read(newfd,buffer,sizeof(buffer))
Your data sent from client, now in buffer. Then maybe you can echo or write() in clientfd.
Your code sent to client , fd number between server and client.
Also if listen always the client(s), after the accept connection, you have to set your client fd in readfds(mask in your code) like FDSET(newfd,&mask)
Then you can listen the client(s) always
Upvotes: 0