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
This commit is contained in:
Ingo Weinhold 2008-04-24 15:18:05 +00:00
parent 2838616b17
commit 9afa8bc573
2 changed files with 148 additions and 0 deletions

View File

@ -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 ;

View File

@ -0,0 +1,145 @@
#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)
{
// 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;
}