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
main(int argc,const char * const * argv)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