The Poll API is similar to the select api in its operation. To understand more about the poll API – refer the link provided below.
The current code example uses the poll API to accept incoming socket connections. The Sample code is based on unix sockets but would work as well on internet sockets. The server and client code are provided below
#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/poll.h>
/* do not create sockets in tmp directory
* To show a socket example – it is fine.
* creating sockets in tmp directory is a security
* vulnerability */
const char *path= “/tmp/unix_socket.sock”;
struct sockaddr_un *servaddr = NULL;
/* create a list of client connections */
struct sockaddr_un clientaddr[10] = {0};
int sockserver, sockclient[10] = {0};
/* Interrupt_handler so that CTRL +C can be used
* to exit the program */
void interrupt_handler (int signum) {
int index =0;
close(sockserver);
free(servaddr);
for(index = 0; index < 10; index++) {
if(sockclient[index] > 0)
close(sockclient[index]);
}
printf(“socket connection closed\n”);
exit(0);
}
int main () {
int length, max_fd, index=0, poll_ready;
char buffer[50];
char *string = “Hello from server”;
struct pollfd fd;
/* signal handler to exit out of while 1 loop */
signal (SIGINT, interrupt_handler);
signal (SIGPIPE, interrupt_handler);
/* Part 1 – create the socket */
sockserver = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockserver < 0) {
printf(“creating server socket failed\n”);
exit(0);
}
/* Part 2 – fill the structure and bind to the socket path
* Remove/unlink any previous socket file creation
*/
remove(path);
servaddr = (struct sockaddr_un *)malloc(sizeof(struct sockaddr_un));
if (servaddr == NULL) {
printf(“Unable to allocate memory\n”);
goto end;
}
servaddr->sun_family = AF_UNIX;
if ((strlen(path)) > sizeof(servaddr->sun_path)) {
printf(“Path is too long\n”);
goto end1;
}
snprintf(servaddr->sun_path, (strlen(path)+1), “%s”, path);
if (0 != (bind(sockserver,(struct sockaddr *)servaddr, sizeof(struct sockaddr_un)))) {
printf(“Unable to bind to the socket path\n”);
goto end1;
}
/* Part 3 – make the server socket a passive socket and accept connections
* from client stations */
if(-1 == listen(sockserver, 10)) {
printf(“Listen Failed\n”);
goto end1;
}
/* set the server socket as Input poll */
fd.fd = sockserver;
fd.events = POLLIN;
while (1) {
/* timeout set to negative – infinite timeout */
poll_ready = poll(&fd,1,-1);
/* poll returns a zero value if timeout occurs and a
* positive value on successful read. If it fails, a
* negative value is returned */
if (poll_ready > 0) {
sockclient[index] = accept(sockserver, (struct sockaddr *)&clientaddr[index], &length);
if (sockclient[index] < 0) {
printf(“unable to accept client connection\n”);
goto end2;
}
} else
goto end2;
/* read one packet and write one packet to client */
memset(buffer, 0, sizeof(buffer));
read(sockclient[index], buffer, sizeof(buffer));
printf(“%s\n”, buffer);
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, (strlen(string)+1), “%s”, string);
write(sockclient[index], buffer, sizeof(buffer));
index++;
}
end2:
for(index = 0; index < 10; index++) {
if(sockclient[index] > 0)
close(sockclient[index]);
}
end1:
free(servaddr);
end:
close(sockserver);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
/* do not create sockets in tmp directory
* To show a socket example – it is fine.
* creating sockets in tmp directory is a security
* vulnerability */
const char *path= “/tmp/unix_socket.sock”;
struct sockaddr_un *servaddr = NULL;
int sockserver;
int main () {
int length;
char buffer[50];
char *string = “Hello from client”;
/* Part 1 – create the socket */
sockserver = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockserver < 0) {
printf(“creating client socket failed\n”);
exit(0);
}
/* Part 2 – fill the structure and bind to the socket path
* Remove/unlink any previous socket file creation
*/
servaddr = (struct sockaddr_un *)malloc(sizeof(struct sockaddr_un));
if(servaddr == NULL) {
printf(“unable to allocate memory\n”);
goto end;
}
servaddr->sun_family = AF_UNIX;
if ((strlen(path)) > sizeof(servaddr->sun_path)) {
printf(“Path is too long\n”);
goto end1;
}
snprintf(servaddr->sun_path, (strlen(path)+1), “%s”, path);
if (0 != (connect(sockserver, (struct sockaddr *)servaddr, sizeof(struct sockaddr_un)))) {
printf(“unable to connect to the server\n”);
goto end1;
}
/* write and read one packet from server */
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, (strlen(string)+1), “%s”, string);
write(sockserver, buffer, sizeof(buffer));
memset(buffer, 0, sizeof(buffer));
read(sockserver, buffer, sizeof(buffer));
printf(“%s\n”, buffer);
end1:
free(servaddr);
end:
close(sockserver);
return 0;
}
Pingback: The Poll System call | Hitch Hiker's Guide to Learning