backlog.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "unp.h"
  2. #define PORT 9999
  3. #define ADDR "127.0.0.1"
  4. #define MAXBACKLOG 100
  5. /* globals */
  6. struct sockaddr_in serv;
  7. pid_t pid; /* of child */
  8. int pipefd[2];
  9. #define pfd pipefd[1] /* parent's end */
  10. #define cfd pipefd[0] /* child's end */
  11. /* function prototypes */
  12. void do_parent(void);
  13. void do_child(void);
  14. int
  15. main(int argc, char **argv)
  16. {
  17. if (argc != 1)
  18. err_quit("usage: backlog");
  19. Socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd);
  20. bzero(&serv, sizeof(serv));
  21. serv.sin_family = AF_INET;
  22. serv.sin_port = htons(PORT);
  23. Inet_pton(AF_INET, ADDR, &serv.sin_addr);
  24. if ( (pid = Fork()) == 0)
  25. do_child();
  26. else
  27. do_parent();
  28. exit(0);
  29. }
  30. void
  31. parent_alrm(int signo)
  32. {
  33. return; /* just interrupt blocked connect() */
  34. }
  35. void
  36. do_parent(void)
  37. {
  38. int backlog, j, k, junk, fd[MAXBACKLOG + 1];
  39. Close(cfd);
  40. Signal(SIGALRM, parent_alrm);
  41. for (backlog = 0; backlog <= 14; backlog++) {
  42. printf("backlog = %d: ", backlog);
  43. Write(pfd, &backlog, sizeof(int)); /* tell child value */
  44. Read(pfd, &junk, sizeof(int)); /* wait for child */
  45. for (j = 1; j <= MAXBACKLOG; j++) {
  46. fd[j] = Socket(AF_INET, SOCK_STREAM, 0);
  47. alarm(2);
  48. if (connect(fd[j], (SA * ) &serv, sizeof(serv)) < 0) {
  49. if (errno != EINTR)
  50. err_sys("connect error, j = %d", j);
  51. printf("timeout, %d connections completed\n", j-1);
  52. for (k = 1; k <= j; k++)
  53. Close(fd[k]);
  54. break; /* next value of backlog */
  55. }
  56. alarm(0);
  57. }
  58. if (j > MAXBACKLOG)
  59. printf("%d connections?\n", MAXBACKLOG);
  60. }
  61. backlog = -1; /* tell child we're all done */
  62. Write(pfd, &backlog, sizeof(int));
  63. }
  64. void
  65. do_child(void)
  66. {
  67. int listenfd, backlog, junk;
  68. const int on = 1;
  69. Close(pfd);
  70. Read(cfd, &backlog, sizeof(int)); /* wait for parent */
  71. while (backlog >= 0) {
  72. listenfd = Socket(AF_INET, SOCK_STREAM, 0);
  73. Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  74. Bind(listenfd, (SA *) &serv, sizeof(serv));
  75. Listen(listenfd, backlog); /* start the listen */
  76. Write(cfd, &junk, sizeof(int)); /* tell parent */
  77. Read(cfd, &backlog, sizeof(int));/* just wait for parent */
  78. Close(listenfd); /* closes all queued connections, too */
  79. }
  80. }