Home Diary Blog Photo Community Open Source
first demo for event port
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h> /* for bzero */
#include <sys/fcntl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h> /* for close */

#include <fcntl.h>

#include <port.h> /* for event ports */
#include <sys/poll.h>

#define nonblocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK)

#define SERV_PORT 8080
#define MAXLINE 80

#ifndef OPEN_MAX
#define OPEN_MAX 256
#endif

#define TRUE 1
#define FALSE 0

int portfd;
uint_t maxi;

static u_char HTML[] =
    "HTTP/1.1 200 OK\r\nServer: test/1.0\r\nDate: May,23 06:20:12 2013 GTC\r\nContent-type: text/html; charset=utf-8\r\nConnection: close\r\n\r\n"
    "<html><head><meta charset=\"utf-8\"><title>Test</title></head><body><h1>Hello,中国!</h1></body></html>";

int main() {
  int sockfd;
  int end_server = FALSE;
  struct sockaddr_in servaddr;
  int optval;

  uint_t i;
  uint_t nready;
  port_event_t client[OPEN_MAX];
  timespec_t timeout;

  bzero(&servaddr, sizeof(servaddr));
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(SERV_PORT);

  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, 4);
  bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
  listen(sockfd, 511);

  if (nonblocking(sockfd) < 0) {
    perror("nonblocking sockfd failed");
    close(sockfd);
    exit(EXIT_FAILURE);
  }

  portfd = port_create();

  port_associate(portfd, PORT_SOURCE_FD, sockfd, POLLIN, NULL);
  maxi++;

  timeout.tv_sec = 3 * 60;
  timeout.tv_nsec = 0;

  do {
    nready = maxi;

    printf("Waiting on port_getn, maxi: %d\n", maxi);

    if (port_getn(portfd, client, OPEN_MAX, &nready, &timeout) < 0) {
      if (errno == EINTR)
        continue;
      else {
        perror("port_getn");
        return -1;
      }
    }

    printf("nready: %d\n", nready);

    for (i = 0; i < nready; i++) {
      /*  if (client[i].portev_source == PORT_SOURCE_FD) { */
      if (client[i].portev_events & POLLIN) {
        int fd = client[i].portev_object;
        if (fd == sockfd) {
          int connfd;
          do {
            connfd = accept(sockfd, NULL, NULL);
            if (connfd < 0) {
              if (errno == EWOULDBLOCK) {
                /* perror("accept()"); */
                break;
              }
              perror("accept() failed");
              end_server = TRUE;
              break;
            }

            printf("New incoming connection: %d\n", connfd);

            if (nonblocking(connfd) < 0) {
              perror("nonblocking connfd failed");
              close(connfd);
              break;
            }

            port_associate(portfd, PORT_SOURCE_FD, connfd, POLLIN, NULL);

            /* port_associate(portfd, PORT_SOURCE_FD, sockfd, POLLIN, NULL); */

            /* maxi = maxi + 1; */
          } while (connfd != -1);
        } else {
          int n;
          char buffer[1024];
          int close_conn = FALSE;

          do {
            n = recv(fd, buffer, sizeof(buffer), 0);
            if (n < 0) {
              if (errno == EWOULDBLOCK) {
                /* perror("recv()"); */
                break;
              }
              perror("recv() failed");
              close_conn = TRUE;
              break;
            }

            if (n == 0) {
              printf("Connection closed\n");
              close_conn = TRUE;
              break;
            }

            printf("Received %d bytes\n", n);

            if (send(fd, HTML, sizeof(HTML), 0) < 0) {
              perror("send() failed");
            }
            close_conn = TRUE;
          } while (TRUE);

          if (close_conn) {
            close(fd);
            port_associate(portfd, PORT_SOURCE_FD, sockfd, POLLIN, NULL);
          }
        } /* end else */
      }   /* end if */
    }     /* end for */
  } while (end_server == FALSE);

  close(portfd);
  close(sockfd);
  return 0;
}