Skip to content

Instantly share code, notes, and snippets.

@droxer
Created February 28, 2015 14:10
Show Gist options
  • Save droxer/908d01ae5d7253cb2762 to your computer and use it in GitHub Desktop.
Save droxer/908d01ae5d7253cb2762 to your computer and use it in GitHub Desktop.
Linux select example.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/select.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define PORT "9421"
/* function prototypes */
void die(const char*);
int main(int argc, char **argv)
{
int sockfd, new, maxfd, on = 1, nready, i;
struct addrinfo *res0, *res, hints;
char buffer[BUFSIZ];
fd_set master, readfds;
ssize_t nbytes;
(void)memset(&hints, '\0', sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
if(-1 == (getaddrinfo(NULL, PORT, &hints, &res0)))
die("getaddrinfo()");
for(res = res0; res; res = res->ai_next)
{
if(-1 == (sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)))
{
perror("socket()");
continue;
}
if(-1 == (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(int))))
{
perror("setsockopt()");
continue;
}
if(-1 == (bind(sockfd, res->ai_addr, res->ai_addrlen)))
{
perror("bind");
continue;
}
break;
}
if(-1 == sockfd)
exit(EXIT_FAILURE);
freeaddrinfo(res0);
if(-1 == (listen(sockfd, 32)))
die("listen()");
if(-1 == (fcntl(sockfd, F_SETFD, O_NONBLOCK)))
die("fcntl()");
FD_ZERO(&master);
FD_ZERO(&readfds);
FD_SET(sockfd, &master);
maxfd = sockfd;
for(;;)
{
memcpy(&readfds, &master, sizeof(master));
(void)printf("running select()\n");
if(-1 == (nready = select(maxfd+1, &readfds, NULL, NULL, NULL)))
die("select()");
(void)printf("Number of ready descriptor: %d\n", nready);
for(i=0; i<=maxfd && nready>0; i++)
{
if(FD_ISSET(i, &readfds))
{
nready--;
if(i == sockfd)
{
(void)printf("Trying to accept() new connection(s)\n");
if(-1 == (new = accept(sockfd, NULL, NULL)))
{
if(EWOULDBLOCK != errno)
die("accept()");
break;
}
else
{
if(-1 == (fcntl(new, F_SETFD, O_NONBLOCK)))
die("fcntl()");
FD_SET(new, &master);
if(maxfd < new)
maxfd = new;
}
}
else
{
(void)printf("recv() data from one of descriptors(s)\n");
nbytes = recv(i, buffer, sizeof(buffer), 0);
buffer[nbytes] = '\0';
printf("%s", buffer);
(void)printf("%zi bytes received.\n", nbytes);
if(nbytes <= 0)
{
if(EWOULDBLOCK != errno)
die("recv()");
break;
}
close(i);
FD_CLR(i, &master);
}
}
}
}
return 0;
}
void die(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment