Advertisement
Guest User

blocking-server-client

a guest
Oct 18th, 2013
183
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.34 KB | None | 1 0
  1. #include <cstdio>
  2. #include <cstdlib>
  3.  
  4. #include <unistd.h>
  5. #include <errno.h>
  6.  
  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <netinet/in.h>
  10.  
  11. #include <netdb.h>
  12. #include <arpa/inet.h>
  13.  
  14. int create_socket(bool server = false)
  15. {
  16.     addrinfo  hints = {};
  17.     addrinfo* servinfo;
  18.  
  19.     int sockfd = -1;
  20.     int rv;
  21.  
  22.     hints.ai_family   = AF_INET;
  23.     hints.ai_socktype = SOCK_STREAM;
  24.     hints.ai_flags    = server ? AI_PASSIVE : 0;
  25.  
  26.     if ((rv = getaddrinfo(server ? 0 : "localhost", "12345", &hints, &servinfo)))
  27.     {
  28.         printf("getaddrinfo failed: %s\n", gai_strerror(rv));
  29.         exit(1);
  30.     }
  31.  
  32.     for(auto p = servinfo; p; p = p->ai_next)
  33.     {
  34.         if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
  35.         {
  36.             perror("socket");
  37.             continue;
  38.         }
  39.  
  40.         if(server)
  41.         {
  42.             int yes = 1;
  43.             setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
  44.  
  45.             if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1)
  46.             {
  47.                 close(sockfd);
  48.                 perror("bind");
  49.                 continue;
  50.             }
  51.         }
  52.         else
  53.         {
  54.             if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1)
  55.             {
  56.                 close(sockfd);
  57.                 perror("connect");
  58.                 continue;
  59.             }
  60.             else
  61.                 puts("client: connected");
  62.         }
  63.  
  64.         break;
  65.     }
  66.  
  67.     freeaddrinfo(servinfo);
  68.     return sockfd;
  69. }
  70.  
  71. void server()
  72. {
  73.     int socket = create_socket(true);
  74.     if(listen(socket, 5) == -1)
  75.     {
  76.         perror("listen");
  77.         exit(1);
  78.     }
  79.     puts("server: listening");
  80.  
  81.     int conn = -1;
  82.     sockaddr_storage addr;
  83.     unsigned int sizeof_addr = sizeof(addr);
  84.  
  85.     for(;;)
  86.     {
  87.         if((conn = accept(socket, (sockaddr *) &addr, &sizeof_addr)) == -1)
  88.         {
  89.             perror("accept");
  90.         }
  91.         else
  92.         {
  93.             puts("server: accept");
  94.  
  95.             if(!fork()) // actually not necessary, only got 1 client
  96.             {
  97.                 close(socket);
  98.                 char *buf = new char[1024*1024];
  99.                 for(;;) read(conn, buf, 1024*1024); // black hole
  100.             }
  101.         }
  102.     }
  103. }
  104.  
  105. void do_send(int socket, const char* buf, unsigned int size/*,  bool nonblock = false */)
  106. {
  107.     unsigned int sent = 0;
  108.     unsigned int count = 0;
  109.  
  110.     while(sent < size)
  111.     {
  112. //      int n = send(socket, &buf[sent], size - sent, nonblock ? MSG_DONTWAIT : 0);
  113.         int n = send(socket, &buf[sent], size - sent, 0);
  114.  
  115.         if (n == -1)
  116.         {
  117.             if(errno == EAGAIN)
  118.             {
  119.                 printf(".");
  120.             }
  121.             else
  122.             {
  123.                 perror("\nsend");
  124.                 return;
  125.             }
  126.         }
  127.         else
  128.         {
  129.             sent += n;
  130.             printf("  --> sent a chunk of %u bytes (send no. %u, total sent = %u)\n", n, ++count, sent);
  131.         }
  132.     }
  133. }
  134.  
  135. void client()
  136. {
  137.     const unsigned int max_size = 64*1024*1024; // sending up to 64MiB in one call
  138.  
  139.     sleep(1); // give server a second to start up
  140.  
  141.     int socket = create_socket();
  142.  
  143.  
  144.     unsigned int send_buffer_size = 0;
  145.     unsigned int len = sizeof(send_buffer_size);
  146.  
  147.     if(getsockopt(socket, SOL_SOCKET, SO_SNDBUF, &send_buffer_size, &len))
  148.         perror("getsockopt");
  149.  
  150.     // Linux internally doubles the buffer size, and getsockopt reports the doubled size
  151.     printf("send buffer size = %u  (doubled, actually %u)\n", send_buffer_size, send_buffer_size/2);
  152.  
  153.     if(socket == -1)
  154.     {
  155.         puts("no good");
  156.         exit(1);
  157.     }
  158.  
  159.     char *buf = new char[max_size]; // uninitialized contents, but who cares
  160.  
  161.     for(unsigned int size = 65536; size <= max_size; size += 16384)
  162.     {
  163.         printf("attempting to send %u bytes\n", size);
  164.         do_send(socket, buf, size);
  165.     }
  166.     puts("all done");
  167.     delete buf;
  168. }
  169.  
  170.  
  171. int main()
  172. {
  173.     if(fork() > 0) server(); else client();
  174.     return 0;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement