#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <unistd.h>
int
main(int argc, const char* const* argv)
{
int listenerSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listenerSocket < 0) {
fprintf(stderr, "failed to create listener socket: %s\n",
strerror(errno));
exit(1);
}
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = 0;
socklen_t addrLen = sizeof(addr);
if (bind(listenerSocket, (sockaddr*)&addr, addrLen) < 0) {
fprintf(stderr, "failed to bind listener socket: %s\n",
strerror(errno));
exit(1);
}
memset(&addr, 0, sizeof(addr));
addrLen = sizeof(addr);
if (getsockname(listenerSocket, (sockaddr*)&addr, &addrLen) != 0) {
fprintf(stderr, "failed to get socket name: %s\n", strerror(errno));
exit(1);
}
printf("listener port: %d (%x)\n", addr.sin_port, addr.sin_addr.s_addr);
if (listen(listenerSocket, 1) < 0) {
return -1;
}
pid_t child = fork();
if (child < 0) {
fprintf(stderr, "fork() failed: %s\n", strerror(errno));
exit(1);
}
if (child == 0) {
unsigned short previousPort = 0;
for (int i = 0; ; i++) {
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
fprintf(stderr, "child: %d: failed to create client socket: "
"%s\n", i, strerror(errno));
exit(1);
}
// test binding
if (previousPort != 0) {
sockaddr_in clientAddr;
clientAddr.sin_family = AF_INET;
clientAddr.sin_addr.s_addr = INADDR_ANY;
// clientAddr.sin_addr.s_addr = INADDR_LOOPBACK;
// clientAddr.sin_port = htons(previousPort);
// clientAddr.sin_port = htons(previousPort + 1);
clientAddr.sin_port = htons(25432);
if (bind(fd, (sockaddr*)&clientAddr, sizeof(clientAddr)) < 0) {
fprintf(stderr, "child: %d: failed to bind: %s\n",
i, strerror(errno));
}
}
*/
if (connect(fd, (sockaddr*)&addr, addrLen) == 0) {
sockaddr_in serverAddr;
socklen_t serverAddrLen = sizeof(serverAddr);
sockaddr_in clientAddr;
socklen_t clientAddrLen = sizeof(clientAddr);
if (getsockname(fd, (sockaddr*)&clientAddr, &clientAddrLen)
== 0
&& getpeername(fd, (sockaddr*)&serverAddr, &serverAddrLen)
== 0) {
previousPort = ntohs(clientAddr.sin_port);
printf("child: %d: connected to server: 0x%08x:%u, "
"local port: %u\n", i,
(unsigned)ntohl(serverAddr.sin_addr.s_addr),
ntohs(serverAddr.sin_port),
previousPort);
} else {
fprintf(stderr, "child: %d: failed to get socket name %s\n",
i, strerror(errno));
}
} else {
fprintf(stderr, "child: %d: connect() failed %s\n", i,
strerror(errno));
}
char buffer[1];
if (fd >= 0) {
read(fd, buffer, sizeof(buffer));
close(fd);
}
}
} else {
while (true) {
int fd = accept(listenerSocket, NULL, 0);
if (fd < 0) {
fprintf(stderr, "server: accept() failed: %s\n",
strerror(errno));
exit(1);
}
sleep(1);
close(fd);
}
}
printf("Everything went fine.\n");
return 0;
}