flagstone 0 Newbie Poster

I am trying to implement a chat program using epoll on the server side. However, the program gets stuck at epoll_wait(). How should I create an asynchronous chat program?

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#define MAX_BUF 30;
int
setnonblocking(int sock)
{
  int opts;
  opts = fcntl(sock,F_GETFL);
  if (opts < 0) {
    perror("fcntl(F_GETFL)");
    exit(EXIT_FAILURE);
  }
  opts = (opts | O_NONBLOCK);
  if (fcntl(sock,F_SETFL,opts) < 0) {
    perror("fcntl(F_SETFL)");
    exit(EXIT_FAILURE);
  }
  return 0;
}
int
main() {
  char buf[30];
  printf("server is starting\n");
  struct epoll_event ev, events[10];
  int write_sock, nfds, epollfd, n, err;
  const  char *str = "hello from the server";
  struct sockaddr_in my_addr;
  
  memset(&my_addr, 0, sizeof(struct sockaddr_in));
  
  //Declaring process variables.
  int server_sockfd;
  int server_len;
  struct sockaddr_in server_address;
  
  //Remove any old socket and create an unnamed socket for the server.
  struct addrinfo hints;
  memset (&hints, 0, sizeof (struct addrinfo));
  hints.ai_family = AF_UNSPEC;     /* Return IPv4 and IPv6 choices */
  hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */
  hints.ai_flags = AI_PASSIVE;     /* All interfaces */
  struct addrinfo *res;
  char *listen_port = "7734";
  err = getaddrinfo (NULL, listen_port, &hints, &res);
  server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
  server_address.sin_family = AF_INET;
  server_address.sin_port = htons(7734);
  server_address.sin_addr.s_addr= res->ai_addr;
  server_len = sizeof(server_address);
  
  bind(server_sockfd, (struct sockaddr *) res->ai_addr, res->ai_addrlen);
  setnonblocking(server_sockfd);
  //Create a connection queue and wait for clients
  if (listen(server_sockfd, 5) < 0) {
    perror("bind: ");
  }
  epollfd = epoll_create(10);
  if (epollfd == -1) {
    perror("epoll_create");
    exit(EXIT_FAILURE);
  }
  else
    printf("epoll created\n");
  ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLOUT;
  ev.data.fd = server_sockfd;
  if(epoll_ctl(epollfd, EPOLL_CTL_ADD, server_sockfd , &ev) == -1) {
    perror("epoll_ctl: server_sockfd");
    exit(EXIT_FAILURE);
  }
  else
    printf("epollctl is done, entering while\n");
  int t;
  struct sockaddr local;
  socklen_t addrlen;
  str="hello world!";
  while(1) {
    nfds = epoll_wait(epollfd, events, 10, -1);
    if (nfds == -1) {
      perror("epoll_pwait");
      exit(EXIT_FAILURE);
    }
    for(n = 0; n < nfds; ++n) {
      if(events[n].data.fd == server_sockfd) {
	write_sock = accept(server_sockfd,(struct sockaddr *) &server_address, &server_len);
	if(write_sock < 0)
	  {
	    perror("accept");
	    exit(EXIT_FAILURE);
	  }
	else
	  printf("connection accepted, executing non blocking\n");
	setnonblocking(write_sock);
	printf("returned from nonblocking\n");
	printf("sending\n");
	t=strlen(str);
	err = send(write_sock, str, t,0);
	printf("the result of send is %d \n",err);
	if (err == -1) {
	  printf("error on send (errno=%d)\n", errno);
	  if(epoll_ctl(epollfd, EPOLL_CTL_ADD, write_sock,&ev) == -1) {
	    perror("epoll_ctl: write_sock");
	    exit(EXIT_FAILURE);
	  } }
	   
	else if(err == 0)
	  printf("data has been sent\n");
      } 
    }
    n=0;
    while(1)
      { nfds = epoll_wait(epollfd, events, 10, -1);
	if (nfds == -1) {
	  perror("epoll_pwait");
	  exit(EXIT_FAILURE);
	}
	if (events[n].events & EPOLLIN) {
	  printf("waiting for data\n");
	  err = recv(write_sock, buf, 30 , 0);
	  if (err == -1)
	    {	perror("read");
	      exit(EXIT_FAILURE);}
	  else
	    printf("    read %d bytes: %.*s\n", err, err, buf);

	}
	else if(events[n].events & EPOLLOUT) {
	  printf("input data to write\n");
	  scanf("%s",&buf);      
	  if(*buf == 'q')
	    break;
	  err=send(write_sock, buf, 30, 0);
	  if(err == -1){
	    perror("write");
	    exit(EXIT_FAILURE);}
	  else printf("write %d bytes: %.*s\n", err, err, buf);
	}
      }	   
  }
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.