From 9afa8bc573adbb84182a4fc634fc8d2fcdda9709 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 24 Apr 2008 15:18:05 +0000 Subject: [PATCH] Small test that repeatedly connects to a server. Under Haiku after several iterations the connect()s start to fail -- first occasionally, later quite often. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25127 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/net/Jamfile | 3 + src/tests/kits/net/tcp_connection_test.cpp | 145 +++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 src/tests/kits/net/tcp_connection_test.cpp diff --git a/src/tests/kits/net/Jamfile b/src/tests/kits/net/Jamfile index 2536cff692..7a7f70477a 100644 --- a/src/tests/kits/net/Jamfile +++ b/src/tests/kits/net/Jamfile @@ -11,6 +11,9 @@ SimpleTest tcp_client : tcp_client.c : $(TARGET_NETWORK_LIBS) ; SimpleTest getpeername : getpeername.cpp : $(TARGET_NETWORK_LIBS) ; +SimpleTest tcp_connection_test : tcp_connection_test.cpp + : $(TARGET_NETWORK_LIBS) ; + SubInclude HAIKU_TOP src tests kits net DialUpPreflet ; SubInclude HAIKU_TOP src tests kits net multicast ; SubInclude HAIKU_TOP src tests kits net netperf ; diff --git a/src/tests/kits/net/tcp_connection_test.cpp b/src/tests/kits/net/tcp_connection_test.cpp new file mode 100644 index 0000000000..30274d9a1f --- /dev/null +++ b/src/tests/kits/net/tcp_connection_test.cpp @@ -0,0 +1,145 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int +main(int argc, const char* const* argv) +{ + // create the listener socket + int listenerSocket = socket(AF_INET, SOCK_STREAM, 0); + if (listenerSocket < 0) { + fprintf(stderr, "failed to create listener socket: %s\n", + strerror(errno)); + exit(1); + } + + // bind it to the port + 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); + + // start listening + if (listen(listenerSocket, 1) < 0) { + return -1; + } + + // fork client + pid_t child = fork(); + if (child < 0) { + fprintf(stderr, "fork() failed: %s\n", strerror(errno)); + exit(1); + } + + if (child == 0) { + // child + unsigned short previousPort = 0; + + for (int i = 0; ; i++) { + // create the client socket + 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)); + } + } +*/ + + // connect to server + 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)); + } + + // wait for the other end to be closed + char buffer[1]; + if (fd >= 0) { + read(fd, buffer, sizeof(buffer)); + close(fd); + } + +// close(fd); +// sleep(1); + } + } else { + // parent + while (true) { + // accept a socket + int fd = accept(listenerSocket, NULL, 0); + if (fd < 0) { + fprintf(stderr, "server: accept() failed: %s\n", + strerror(errno)); + exit(1); + } + + // wait for it to be closed +// char buffer[1]; +// read(fd, buffer, sizeof(buffer)); +// close(fd); + + sleep(1); + close(fd); + } + } + + printf("Everything went fine.\n"); + + return 0; +}