Advertisement
pveselov

rtest.c

Aug 21st, 2015
767
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.59 KB | None | 0 0
  1.  
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <netinet/tcp.h>
  5. #include <netinet/ip.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <errno.h>
  11. #include <pthread.h>
  12.  
  13. static void * server(void*);
  14. static void * connecter(void*);
  15.  
  16. static int s_clt;
  17. static struct sockaddr_in a_srv;
  18. static struct sockaddr_in a_clt;
  19. static int is_client;
  20.  
  21. static void wait_for_close(int);
  22. static void close_on_read(int);
  23.  
  24. int main(int argc, char ** argv) {
  25.  
  26.     int port;
  27.     int aux;
  28.     socklen_t slen;
  29.     pthread_t bux;
  30.  
  31.     int s_srv = socket(PF_INET,SOCK_STREAM,0);
  32.     if (s_srv<1) { perror("server socket"); return 1; }
  33.  
  34.     if (argc < 3) {
  35.         fprintf(stderr, "Use: %s <port> {c|s}\n", argv[0]);
  36.         return 1;
  37.     }
  38.  
  39.     port = atoi(argv[1]);
  40.     if (port <= 0) {
  41.         fprintf(stderr, "port?\n"); return 1;
  42.     }
  43.  
  44.     if (argv[2][0] == 'c') {
  45.         is_client = 1;
  46.         fprintf(stdout, "Will initiate client close\n");
  47.     } else {
  48.         is_client = 0;
  49.         fprintf(stdout, "Will initiate server close\n");
  50.     }
  51.  
  52.     a_srv.sin_family = a_clt.sin_family = AF_INET;
  53.     a_srv.sin_port = htons(port);
  54.     a_clt.sin_port = htons(port+1);
  55.     a_srv.sin_addr.s_addr = a_clt.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  56.  
  57.     if (bind(s_srv, (struct sockaddr*)&a_srv, sizeof(struct sockaddr_in))) {
  58.         perror("binding server"); return 1;
  59.     }
  60.  
  61.     if (listen(s_srv, 5)) { perror("listen"); return 1; }
  62.  
  63.     pthread_create(&bux, 0, connecter, 0);
  64.  
  65.     while (1) {
  66.  
  67.         struct sockaddr_in a_inp;
  68.  
  69.         aux = accept(s_srv, (struct sockaddr*)&a_inp, &slen);
  70.         int * fd = malloc(sizeof(int));
  71.         *fd = aux;
  72.         pthread_create(&bux, 0, server, fd);
  73.     }
  74.  
  75. }
  76.  
  77. void * connecter(void * arg) {
  78.  
  79.     int i = 20;
  80.     int yes = 1;
  81.  
  82.     while (i--) {
  83.  
  84.         s_clt = socket(PF_INET,SOCK_STREAM,0);
  85.         if (s_clt<1) { perror("server socket"); _exit(1); }
  86.  
  87.         if (setsockopt(s_clt, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) {
  88.             perror("setsockopt"); _exit(1);
  89.         }
  90.  
  91.         if (bind(s_clt, (struct sockaddr*)&a_clt, sizeof(struct sockaddr_in))) {
  92.             perror("binding client"); _exit(1);
  93.         }
  94.    
  95.         fprintf(stdout, "connecting...\n");
  96.         if (connect(s_clt, (struct sockaddr*)&a_srv, sizeof(struct sockaddr_in))) {
  97.             perror("connect");
  98.             _exit(1);
  99.         }
  100.  
  101.         if (is_client) {
  102.             close_on_read(s_clt);
  103.         } else {
  104.             wait_for_close(s_clt);
  105.         }
  106.    
  107.     }
  108.  
  109.     return 0;
  110.  
  111. }
  112.  
  113. void * server(void * arg) {
  114.  
  115.     int fd = *(int*)arg;
  116.     free(arg);
  117.  
  118.     if (is_client) {
  119.         wait_for_close(fd);
  120.     } else {
  121.         close_on_read(fd);
  122.     }
  123.  
  124.     return 0;
  125.  
  126. }
  127.  
  128. void close_on_read(int fd) {
  129.  
  130.     unsigned char c;
  131.     fprintf(stdout, "Reading child connection\n");
  132.     int rc = read(fd, &c, 1);
  133.     if (rc < 0) {
  134.         perror("read"); _exit(1);
  135.     }
  136.     if (!rc) {
  137.         fprintf(stderr, "unexpected EOF?\n"); _exit(1);
  138.     }
  139.  
  140.     fprintf(stdout, "byte sent, closing\n");
  141.  
  142.     shutdown(fd, SHUT_RDWR);
  143.     close(fd);
  144.  
  145. }
  146.  
  147. void  wait_for_close(int fd) {
  148.     unsigned char c;
  149.     int rc = write(fd, &c, 1);
  150.     if (rc < 0) {
  151.         perror("write"); _exit(1);
  152.     }
  153.  
  154.     // read should exit with EOF
  155.     rc = read(fd, &c, 1);
  156.     if (rc < 0) {
  157.         perror("read"); _exit(1);
  158.     }
  159.     if (rc > 0) {
  160.         fprintf(stderr, "what read?\n"); _exit(1);
  161.     }
  162.     fprintf(stdout, "Received EOF\n");
  163.     shutdown(fd, SHUT_RDWR);
  164.     close(fd);
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement