From 84a3cc1e945c92a1a980fdba5b0d44bcf065dc8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 2 Nov 2006 14:09:41 +0000 Subject: [PATCH] * Added small TCP tests written by Andrew. * Removed a poorly written TCP test. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19171 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/net/Jamfile | 5 ++ src/tests/kits/net/tcp_client.c | 93 ++++++++++++++++++++++ src/tests/kits/net/tcp_server.c | 133 ++++++++++++++++++++++++++++++++ src/tests/kits/net/tcp_test.c | 73 ------------------ 4 files changed, 231 insertions(+), 73 deletions(-) create mode 100644 src/tests/kits/net/tcp_client.c create mode 100644 src/tests/kits/net/tcp_server.c delete mode 100644 src/tests/kits/net/tcp_test.c diff --git a/src/tests/kits/net/Jamfile b/src/tests/kits/net/Jamfile index 4067a9f2e3..64a6df9a07 100644 --- a/src/tests/kits/net/Jamfile +++ b/src/tests/kits/net/Jamfile @@ -1,5 +1,7 @@ SubDir HAIKU_TOP src tests kits net ; +SetSubDirSupportedPlatformsBeOSCompatible ; + # bonefish: Tried to get the first test compiling. It complained about not # being able to find some headers, thus I added the respective include dirs # until it was asking for headers we currently don't have @@ -14,6 +16,9 @@ SimpleTest udp_client : udp_client.c : $(NETWORK_LIBS) ; SimpleTest udp_echo : udp_echo.c : $(NETWORK_LIBS) ; SimpleTest udp_server : udp_server.c : $(NETWORK_LIBS) ; +SimpleTest tcp_server : tcp_server.c : $(NETWORK_LIBS) ; +SimpleTest tcp_client : tcp_client.c : $(NETWORK_LIBS) ; + SubInclude HAIKU_TOP src tests kits net DialUpPreflet ; SubInclude HAIKU_TOP src tests kits net netperf ; # SubInclude HAIKU_TOP src tests kits net new_stack ; diff --git a/src/tests/kits/net/tcp_client.c b/src/tests/kits/net/tcp_client.c new file mode 100644 index 0000000000..54f9999e05 --- /dev/null +++ b/src/tests/kits/net/tcp_client.c @@ -0,0 +1,93 @@ +/* + * a stream socket client demo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PORT 40000 // the port client will be connecting to +#define MAXDATASIZE 100 // max number of bytes we can get at once + + +int +main(int argc, char **argv) +{ + int sockfd; + char buffer[MAXDATASIZE]; + short int port = PORT; + struct hostent *he; + struct sockaddr_in their_addr; + // connector's address information + + if (argc < 2) { + fprintf(stderr,"usage: tcp_client [port]\n"); + exit(1); + } + + if (argc == 3) + port = atoi(argv[2]); + + if ((he = gethostbyname(argv[1])) == NULL) { + // get the host info + perror("gethostbyname"); + exit(1); + } + + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + exit(1); + } + + memset(&their_addr, 0, sizeof(their_addr)); + their_addr.sin_family = AF_INET; + their_addr.sin_port = htons(port); + their_addr.sin_addr = *((struct in_addr *)he->h_addr); + + if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { + perror("connect"); + exit(1); + } + + if (!fork()) { + int numBytes; + + while (1) { + // child process + if ((numBytes = recv(sockfd, buffer, sizeof(buffer) - 1, 0)) == -1) { + perror("recv"); + sleep(1); + // want the read thread to stay alive + //exit(1); + } + + buffer[numBytes] = '\0'; + printf("%s", buffer); + } + } else { + while (1) { + // parent process + if (fgets(buffer, sizeof(buffer) - 1, stdin) == NULL) { + perror("fgets"); + exit(1); + } + + if ((send(sockfd, buffer, strlen(buffer), 0)) == -1) { + perror("send"); + exit(1); + } + } + } + + close(sockfd); + + return 0; +} + diff --git a/src/tests/kits/net/tcp_server.c b/src/tests/kits/net/tcp_server.c new file mode 100644 index 0000000000..48a07d94e9 --- /dev/null +++ b/src/tests/kits/net/tcp_server.c @@ -0,0 +1,133 @@ +/* + * a stream socket server demo + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define MYPORT 40000 // the port users will be connecting to +#define BACKLOG 10 // how many pending connections queue will hold +#define MAXDATASIZE 100 + + +static void +sigchld_handler(int s) +{ + while (waitpid(-1, NULL, WNOHANG) > 0) { + } +} + + +int +main(int argc, char *argv[]) +{ + int sockfd, new_fd; // listen on sock_fd, new connection on new_fd + struct sockaddr_in my_addr; // my address information + struct sockaddr_in their_addr; // connector's address information + int sin_size; + struct sigaction sa; + int yes = 1; + short int port = MYPORT; + char buf[MAXDATASIZE]; + + if (argc >= 2 && atoi(argv[1]) != 0) + port = atoi(argv[1]); + + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + exit(1); + } + + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { + perror("setsockopt"); + exit(1); + } + + memset(&my_addr, 0, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(port); + my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP + + if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { + perror("bind"); + exit(1); + } + + if (listen(sockfd, BACKLOG) == -1) { + perror("listen"); + exit(1); + } + + sa.sa_handler = sigchld_handler; // reap all dead processes + sigemptyset(&sa.sa_mask); +#ifdef HAIKU_TARGET_PLATFORM_HAIKU + sa.sa_flags = SA_RESTART; +#else + sa.sa_flags = 0; +#endif + if (sigaction(SIGCHLD, &sa, NULL) == -1) { + perror("sigaction"); + exit(1); + } + + while (1) { + // main accept() loop + sin_size = sizeof(struct sockaddr_in); + if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { + perror("accept"); + continue; + } + printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr)); + if (!fork()) { // this is the child process + close(sockfd); // child doesn't need the listener + + if (!fork()) { + while (1) { + // child's child process + if (fgets(buf, MAXDATASIZE-1, stdin) == NULL) { + perror("fgets"); + exit(1); + } + + if (send(new_fd, buf, strlen(buf), 0) == -1) { + perror("send"); + exit(1); + } + } + } else { + ssize_t numBytes; + while (1) { + // child process + if ((numBytes = recv(new_fd, buf, MAXDATASIZE-1, 0)) == -1) { + perror("recv"); + exit(1); + } + if (numBytes == 0) + exit(0); + + buf[numBytes] = '\0'; + + printf("%s:| %s", inet_ntoa(their_addr.sin_addr), buf); + } + } + + close(new_fd); + exit(0); + } + close(new_fd); // parent doesn't need this + } + + return 0; +} + diff --git a/src/tests/kits/net/tcp_test.c b/src/tests/kits/net/tcp_test.c deleted file mode 100644 index c43c09c1af..0000000000 --- a/src/tests/kits/net/tcp_test.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include - -#include "sys/socket.h" -#include "netinet/in.h" -#include "arpa/inet.h" -#include "sys/select.h" - -#include "ufunc.h" - -#define RQST "GET / HTTP/1.0\n\n" -#define BUFFER 1024 - -int main(int argc, char **argv) -{ - int sock = socket(AF_INET, SOCK_STREAM, 0); - struct sockaddr_in sin; - size_t salen = sizeof(sin); - int rv; - char buffer[BUFFER]; - - test_banner("Basic TCP Test"); - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons((real_time_clock() & 0xffff)); - sin.sin_len = salen; - sin.sin_addr.s_addr = htonl(INADDR_ANY); - rv = bind(sock, (const struct sockaddr*)&sin, salen); - if (rv < 0) - err(rv, "bind"); - printf("Bound\n"); - - sin.sin_port = htons(80); - sin.sin_addr.s_addr = htonl(0xc0a80001); - rv = connect(sock, (const struct sockaddr*)&sin, salen); - if (rv < 0) { - close(sock); - err(rv, "connect"); - } - printf("Connected!\n"); - - rv = write(sock, RQST, strlen(RQST)); - if (rv < 0) { - close(sock); - err(errno, "write"); - } - printf("Written request %d\n", rv); - - memset(&buffer,0, BUFFER); - rv = read(sock, buffer, BUFFER); - if (rv < 0) { - close(sock); - err(errno, "read"); - } - printf("%s", buffer); - memset(&buffer, 0, BUFFER); - while ((rv = read(sock, buffer, BUFFER)) >= 0) { - printf("%s", buffer); - if (rv <= 0) - break; - memset(&buffer,0, BUFFER); - } - printf("Done.\n"); - close(sock); - - return (0); -} - -