1 #include <errno.h> 2 #include <fcntl.h> 3 #include <netinet/in.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <sys/socket.h> 8 #include <sys/uio.h> 9 #include <unistd.h> 10 11 12 int 13 main(int argc, const char* const* argv) 14 { 15 // create the listener socket 16 int listenerSocket = socket(AF_INET, SOCK_STREAM, 0); 17 if (listenerSocket < 0) { 18 fprintf(stderr, "failed to create listener socket: %s\n", 19 strerror(errno)); 20 exit(1); 21 } 22 23 // bind it to the port 24 sockaddr_in addr; 25 addr.sin_family = AF_INET; 26 addr.sin_addr.s_addr = INADDR_ANY; 27 addr.sin_port = 0; 28 socklen_t addrLen = sizeof(addr); 29 if (bind(listenerSocket, (sockaddr*)&addr, addrLen) < 0) { 30 fprintf(stderr, "failed to bind listener socket: %s\n", 31 strerror(errno)); 32 exit(1); 33 } 34 35 memset(&addr, 0, sizeof(addr)); 36 addrLen = sizeof(addr); 37 if (getsockname(listenerSocket, (sockaddr*)&addr, &addrLen) != 0) { 38 fprintf(stderr, "failed to get socket name: %s\n", strerror(errno)); 39 exit(1); 40 } 41 42 printf("listener port: %d (%x)\n", addr.sin_port, addr.sin_addr.s_addr); 43 44 // start listening 45 if (listen(listenerSocket, 1) < 0) { 46 return -1; 47 } 48 49 // fork client 50 pid_t child = fork(); 51 if (child < 0) { 52 fprintf(stderr, "fork() failed: %s\n", strerror(errno)); 53 exit(1); 54 } 55 56 if (child == 0) { 57 // child 58 unsigned short previousPort = 0; 59 60 for (int i = 0; ; i++) { 61 // create the client socket 62 int fd = socket(AF_INET, SOCK_STREAM, 0); 63 if (fd < 0) { 64 fprintf(stderr, "child: %d: failed to create client socket: " 65 "%s\n", i, strerror(errno)); 66 exit(1); 67 } 68 69 /* 70 // test binding 71 if (previousPort != 0) { 72 sockaddr_in clientAddr; 73 clientAddr.sin_family = AF_INET; 74 clientAddr.sin_addr.s_addr = INADDR_ANY; 75 // clientAddr.sin_addr.s_addr = INADDR_LOOPBACK; 76 // clientAddr.sin_port = htons(previousPort); 77 // clientAddr.sin_port = htons(previousPort + 1); 78 clientAddr.sin_port = htons(25432); 79 if (bind(fd, (sockaddr*)&clientAddr, sizeof(clientAddr)) < 0) { 80 fprintf(stderr, "child: %d: failed to bind: %s\n", 81 i, strerror(errno)); 82 } 83 } 84 */ 85 86 // connect to server 87 if (connect(fd, (sockaddr*)&addr, addrLen) == 0) { 88 sockaddr_in serverAddr; 89 socklen_t serverAddrLen = sizeof(serverAddr); 90 sockaddr_in clientAddr; 91 socklen_t clientAddrLen = sizeof(clientAddr); 92 if (getsockname(fd, (sockaddr*)&clientAddr, &clientAddrLen) 93 == 0 94 && getpeername(fd, (sockaddr*)&serverAddr, &serverAddrLen) 95 == 0) { 96 previousPort = ntohs(clientAddr.sin_port); 97 printf("child: %d: connected to server: 0x%08x:%u, " 98 "local port: %u\n", i, 99 (unsigned)ntohl(serverAddr.sin_addr.s_addr), 100 ntohs(serverAddr.sin_port), 101 previousPort); 102 } else { 103 fprintf(stderr, "child: %d: failed to get socket name %s\n", 104 i, strerror(errno)); 105 } 106 } else { 107 fprintf(stderr, "child: %d: connect() failed %s\n", i, 108 strerror(errno)); 109 } 110 111 // wait for the other end to be closed 112 char buffer[1]; 113 if (fd >= 0) { 114 read(fd, buffer, sizeof(buffer)); 115 close(fd); 116 } 117 118 // close(fd); 119 // sleep(1); 120 } 121 } else { 122 // parent 123 while (true) { 124 // accept a socket 125 int fd = accept(listenerSocket, NULL, 0); 126 if (fd < 0) { 127 fprintf(stderr, "server: accept() failed: %s\n", 128 strerror(errno)); 129 exit(1); 130 } 131 132 // wait for it to be closed 133 // char buffer[1]; 134 // read(fd, buffer, sizeof(buffer)); 135 // close(fd); 136 137 sleep(1); 138 close(fd); 139 } 140 } 141 142 printf("Everything went fine.\n"); 143 144 return 0; 145 } 146