C   66

p1.c

Guest on 5th May 2022 11:03:38 PM

  1. #include <netdb.h>
  2. #include <netinet/ip.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sys/epoll.h>
  6. #include <sys/socket.h>
  7. #include <unistd.h>
  8. #include "common.h"
  9.  
  10. void usage(char *name) {
  11.         fprintf(stderr, "uso: %s <ip> <puerto>\n", name);
  12.         exit(1);
  13. }
  14.  
  15. static void print_event(int fd, struct epoll_event ev) {
  16.         char flags_str[200];
  17.  
  18.         flags_str[0] = 0;
  19.         flags_str[1] = 0; /* dirty */
  20.  
  21.         if (ev.events & EPOLLIN )       strcat(flags_str, "|EPOLLIN");
  22.         if (ev.events & EPOLLOUT)       strcat(flags_str, "|EPOLLOUT");
  23.         if (ev.events & EPOLLERR)       strcat(flags_str, "|EPOLLERR");
  24.         if (ev.events & EPOLLHUP)       strcat(flags_str, "|EPOLLHUP");
  25.         if (ev.events & EPOLLRDHUP)     strcat(flags_str, "|EPOLLRDHUP");
  26.         if (ev.events & EPOLLPRI)       strcat(flags_str, "|EPOLLPRI");
  27.         if (ev.events & EPOLLET)        strcat(flags_str, "|EPOLLET");
  28.         if (ev.events & EPOLLONESHOT)   strcat(flags_str, "|EPOLLONESHOT");
  29.  
  30.         fprintf(stderr, "Event for fd %i. Flags=(%s).\n",
  31.                         fd, flags_str+1);
  32. }
  33.  
  34.  
  35. int create_sock(char *host, char *port);
  36. int setup_epoll(int sockfd);
  37.  
  38. int main(int argc, char **argv) {
  39.         int sock, epfd;
  40.         struct epoll_event ev;
  41.         char buf[100];
  42.         int n, count;
  43.  
  44.         if (argc != 3)
  45.                 usage(argv[0]);
  46.  
  47.         sock = create_sock(argv[1], argv[2]);
  48.         epfd = setup_epoll(sock);
  49.  
  50.         count = 2;
  51.         while (count > 0) {
  52.                 fprintf(stderr, "count=%i\n", count);
  53.  
  54.                 n = epoll_wait(epfd, &ev, 1, -1);
  55.                 if (n < 0)
  56.                         die("epoll_wait");
  57.  
  58.                 /*
  59.                  * n debe ser igual a 1, si o si, ya que
  60.                  * no hubo error ni timeout
  61.                  */
  62.                 assert(n == 1);
  63.  
  64.                 int fd = ev.data.fd;
  65.                 print_event(fd, ev);
  66.  
  67.                 if (ev.events & EPOLLERR)
  68.                         die("epollerr");
  69.  
  70.                 if (fd == 0) {
  71.                         int t;
  72.                         t = read(0, buf, 100);
  73.  
  74.                         if (t == 0) {
  75.                                 /*
  76.                                  * Cuando cerramos todas las refencias
  77.                                  * a un archivo, se remueve automaticamente
  78.                                  * del epoll.
  79.                                  */
  80.                                 close(0);
  81.  
  82.                                 count--;
  83.                         } else {
  84.                                 write(sock, buf, t);
  85.                         }
  86.                 } else if (fd == sock) {
  87.                         int t;
  88.                         t = read(sock, buf, 100);
  89.  
  90.                         if (t == 0) {
  91.                                 close(sock);
  92.                                 count--;
  93.                         } else {
  94.                                 write(1, buf, t);
  95.                         }
  96.                 } else {
  97.                         die("????");
  98.                 }
  99.         }
  100.  
  101.         close(epfd);
  102.  
  103.         return 0;
  104. }
  105.  
  106. int create_sock(char *host, char *port) {
  107.         int sock, ret;
  108.         struct sockaddr_in addr;
  109.         struct addrinfo *gai, hints;
  110.  
  111.         sock = socket(AF_INET, SOCK_STREAM, 0);
  112.         if (sock < 0)
  113.                 die("socket");
  114.  
  115.         memset(&hints, 0, sizeof hints);
  116.         hints.ai_family = AF_INET;
  117.         hints.ai_socktype = SOCK_STREAM;
  118.  
  119.         /*
  120.          * Consultamos la información sobre la dirección que nos
  121.          * dieron. Podemos pasar una IP, o un nombre que será
  122.          * consultado a /etc/hosts o al nameserver configurado
  123.          */o
  124.          */
  125.         ret = getaddrinfo(host, port, &hints, &gai);
  126.         if (ret)
  127.                 die("getaddrinfo (%s)", gai_strerror(ret/*
  128.          * getaddrinfo devuelve una lista enlazada con
  129.          * información, tomamos el primer nodo
  130.          */odo
  131.          */
  132.  
  133.         addr = *(sin*)gai->ai_addr;
  134.  
  135.         freeaddrinfo(/* Conectamos a esa dirección */ción */
  136.         ret = connect(sock, (sad*)&addr, sizeof addr);
  137.         if (ret < 0)
  138.                 die("connect");
  139.  
  140.         return sock;
  141. }
  142.  
  143. int setup_epoll(int sockfd) {
  144.         int epfd;
  145.         int ret;
  146.         struct epoll_event ev;
  147.  
  148.         epfd = epoll_create(1);
  149.         if (epfd < 0)
  150.                 die("epoll_create");
  151.  
  152.         ev.events = EPOLLIN;
  153.         ev.data.fd = sockfd;
  154.  
  155.         ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
  156.         if (ret)
  157.                 die("epoll_ctl.1");
  158.  
  159.         ev.events = EPOLLIN;
  160.         ev.data.fd = 0;
  161.         ret = epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &ev);
  162.         if (ret)
  163.                 die("epoll_ctl.2");
  164.  
  165.         retu

Raw Paste


Login or Register to edit or fork this paste. It's free.