From 0a5a2aadb7789251a2cba285e0a680951c5db573 Mon Sep 17 00:00:00 2001 From: Swarup Nayak Date: Tue, 4 Sep 2018 17:26:26 +0530 Subject: Feat: Fork support Change-Id: Iae75c1c0bd4961ee052428bdd661d6f1da1bdbcb Signed-off-by: Swarup Nayak --- app_example/CMakeLists.txt | 2 +- app_example/func-test/CMakeLists.txt | 18 ++++ app_example/func-test/fork/CMakeLists.txt | 27 +++++ app_example/func-test/fork/tcpclient.c | 173 ++++++++++++++++++++++++++++++ app_example/func-test/fork/tcpserver.c | 161 +++++++++++++++++++++++++++ 5 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 app_example/func-test/CMakeLists.txt create mode 100644 app_example/func-test/fork/CMakeLists.txt create mode 100644 app_example/func-test/fork/tcpclient.c create mode 100644 app_example/func-test/fork/tcpserver.c (limited to 'app_example') diff --git a/app_example/CMakeLists.txt b/app_example/CMakeLists.txt index 0c88a4f..a82c752 100644 --- a/app_example/CMakeLists.txt +++ b/app_example/CMakeLists.txt @@ -15,4 +15,4 @@ ######################################################################### ADD_SUBDIRECTORY(perf-test) - +ADD_SUBDIRECTORY(func-test) diff --git a/app_example/func-test/CMakeLists.txt b/app_example/func-test/CMakeLists.txt new file mode 100644 index 0000000..e6357b8 --- /dev/null +++ b/app_example/func-test/CMakeLists.txt @@ -0,0 +1,18 @@ +######################################################################### +# +# Copyright (c) 2018 Huawei Technologies Co.,Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +######################################################################### + +ADD_SUBDIRECTORY(fork) + diff --git a/app_example/func-test/fork/CMakeLists.txt b/app_example/func-test/fork/CMakeLists.txt new file mode 100644 index 0000000..266dd9f --- /dev/null +++ b/app_example/func-test/fork/CMakeLists.txt @@ -0,0 +1,27 @@ +######################################################################### +# +# Copyright (c) 2018 Huawei Technologies Co.,Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +######################################################################### +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -fPIC -m64 -mssse3 -std=gnu89") + +LINK_DIRECTORIES(${LIB_PATH_SHARED} ${LIB_PATH_STATIC}) + +ADD_EXECUTABLE(tcp_fork_server tcpserver.c) +ADD_DEPENDENCIES(tcp_fork_server nStackAPI) +TARGET_LINK_LIBRARIES(tcp_fork_server libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(tcp_client tcpclient.c) +ADD_DEPENDENCIES(tcp_client nStackAPI) +TARGET_LINK_LIBRARIES(tcp_client libnStackAPI.so -lpthread -lrt) + diff --git a/app_example/func-test/fork/tcpclient.c b/app_example/func-test/fork/tcpclient.c new file mode 100644 index 0000000..274dcbb --- /dev/null +++ b/app_example/func-test/fork/tcpclient.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG + +#ifdef DEBUG +#define DBG(fmt, arg...) do { \ + printf(fmt, ##arg); \ +} while(0) +#else +#define DBG(fmt, arg...) ((void)0) +#endif + +static struct sockaddr_in g_dest; +static struct sockaddr_in g_src; +int srcPort = 0; +int destPort = 0; +int times = 0; + +void +random_str (char *str, const int len) +{ + static const char alphaNum[] = + "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; + int i = 0; + + for (i = 0; i < len; i++) + { + str[i] = alphaNum[rand () % (sizeof (alphaNum) - 1)]; + } + + str[len] = 0; +} + +static void +setArgsDefault () +{ + + memset (&g_dest, 0, sizeof (g_dest)); + g_dest.sin_family = AF_INET; + g_dest.sin_addr.s_addr = inet_addr ("127.0.0.1"); + g_dest.sin_port = htons (12345); + bzero (&(g_dest.sin_zero), 8); + + memset (&g_src, 0, sizeof (g_src)); + g_src.sin_family = AF_INET; + g_src.sin_addr.s_addr = inet_addr ("0.0.0.0"); + g_src.sin_port = htons (7895); + bzero (&(g_src.sin_zero), 8); + + times = 1; +} + +static int +process_arg (int argc, char *argv[]) +{ + int opt = 0; + int error = 0; + const char *optstring = "p:d:s:a:t:"; + + if (argc < 5) + { + DBG + ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -t times; \n"); + return -1; + } + setArgsDefault (); + while ((opt = getopt (argc, argv, optstring)) != -1) + { + switch (opt) + { + case 'p': + g_dest.sin_port = htons (atoi (optarg)); + break; + case 'd': + g_dest.sin_addr.s_addr = inet_addr (optarg); + break; + case 's': + g_src.sin_addr.s_addr = inet_addr (optarg); + break; + case 'a': + g_src.sin_port = htons (atoi (optarg)); + break; + case 't': + times = atoi (optarg); + break; + } + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + + int clientSocket, ret, i; + char sndbuffer[1024]; + char rcvbuffer[1024]; + int result = 0; + + /* + * check command line arguments + */ + if (0 != process_arg (argc, argv)) + { + DBG ("Error in argument.%d\n", argc); + exit (1); + } + + clientSocket = socket (AF_INET, SOCK_STREAM, 0); + if (clientSocket < 0) + { + DBG ("Error in connection.\n"); + exit (1); + } + DBG ("[INFO]Client Socket is created.\n"); + + ret = bind (clientSocket, (struct sockaddr *) &g_src, sizeof (g_src)); + if (ret < 0) + { + DBG ("Error in binding.\n"); + exit (1); + } + + DBG ("[INFO]Bind to client aaddress port 0\n"); + + ret = connect (clientSocket, (struct sockaddr *) &g_dest, sizeof (g_dest)); + if (ret < 0) + { + DBG ("Error in connection.\n"); + exit (1); + } + DBG ("[INFO]Connected to Server.\n"); + + memset (sndbuffer, '\0', 1024 * sizeof (char)); + memset (rcvbuffer, '\0', 1024 * sizeof (char)); + + for (i = 1; i <= times; i++) + { + DBG ("Client: \t"); + random_str (sndbuffer, 50); + send (clientSocket, sndbuffer, strlen (sndbuffer), 0); + + if (recv (clientSocket, rcvbuffer, 1024, 0) < 0) + { + DBG ("Error in receiving data.\n"); + } + else + { + DBG ("Server: \t%s\n", rcvbuffer); + } + if (0 != strcmp (sndbuffer, rcvbuffer)) + { + result = -1; + break; + } + } + + /* Send exit message to server */ + strcpy (sndbuffer, "#exit"); + send (clientSocket, sndbuffer, strlen (sndbuffer), 0); + + DBG ("Result = %s\n", (result == 0) ? "Success" : "Fail"); + close (clientSocket); + DBG ("Disconnecting from server.\n"); + return 0; +} diff --git a/app_example/func-test/fork/tcpserver.c b/app_example/func-test/fork/tcpserver.c new file mode 100644 index 0000000..5474c35 --- /dev/null +++ b/app_example/func-test/fork/tcpserver.c @@ -0,0 +1,161 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct sockaddr_in g_src; +int srcPort = 0; +int destPort = 0; +int times = 0; + +#ifdef DEBUG +#define DBG(fmt, arg...) do { \ + DBG(fmt, ##arg); \ +} while(0) +#else +#define DBG(fmt, arg...) ((void)0) +#endif + +static void +setArgsDefault () +{ + memset (&g_src, 0, sizeof (g_src)); + g_src.sin_family = AF_INET; + g_src.sin_addr.s_addr = inet_addr ("0.0.0.0"); + g_src.sin_port = htons (7895); + bzero (&(g_src.sin_zero), 8); + + times = 1; +} + +static int +process_arg (int argc, char *argv[]) +{ + int opt = 0; + int error = 0; + const char *optstring = "s:a:t:"; + + if (argc < 5) + { + DBG + ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -t times; \n"); + return -1; + } + setArgsDefault (); + while ((opt = getopt (argc, argv, optstring)) != -1) + { + switch (opt) + { + case 's': + g_src.sin_addr.s_addr = inet_addr (optarg); + break; + case 'a': + g_src.sin_port = htons (atoi (optarg)); + break; + case 't': + times = atoi (optarg); + break; + } + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + + int sockfd, ret; + int newSocket; + socklen_t addr_size; + static struct sockaddr_in accept_addr; + char buffer[1024]; + pid_t childpid; + + /* + * check command line arguments + */ + if (0 != process_arg (argc, argv)) + { + DBG ("Error in argument.%d\n", argc); + exit (1); + } + + sockfd = socket (AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + { + DBG ("Error in connection.\n"); + exit (1); + } + DBG ("Server Socket is created. %d\n", sockfd); + + ret = bind (sockfd, (struct sockaddr *) &g_src, sizeof (g_src)); + if (ret < 0) + { + DBG ("Error in binding.\n"); + exit (1); + } + + DBG ("Bind sucess port %d\n", g_src.sin_port); + + if (listen (sockfd, 10) == 0) + { + DBG ("Listening on %s....\n", inet_ntoa (g_src.sin_addr)); + } + else + { + DBG ("Error in binding.\n"); + } + + while (1) + { + newSocket = + accept (sockfd, (struct sockaddr *) &accept_addr, &addr_size); + if (newSocket < 0) + { + DBG ("Error: Exiting here pid %d", getpid ()); + exit (1); + } + + DBG ("Connection accepted from %s:%d fd %d\n", + inet_ntoa (accept_addr.sin_addr), + ntohs (accept_addr.sin_port), newSocket); + if ((childpid = fork ()) == 0) + { + DBG ("[ PID %d] Child process Created. Pid %d \r\n", getpid (), + getpid ()); + DBG ("[ PID %d] Closing fd %d\n", getpid (), sockfd); + close (sockfd); + + while (1) + { + memset (buffer, '\0', 1024 * sizeof (char)); + recv (newSocket, buffer, 1024, 0); + if (strcmp (buffer, "#exit") == 0) + { + DBG ("Disconnected from %s:%d\n", + inet_ntoa (newAddr.sin_addr), + ntohs (newAddr.sin_port)); + break; + } + else + { + DBG ("[PID %d]Client: %s\n", getpid (), buffer); + send (newSocket, buffer, strlen (buffer), 0); + bzero (buffer, sizeof (buffer)); + } + } + + DBG ("[PID %d]Closing socket %d\r\n", getpid (), newSocket); + close (newSocket); + } + + } + + DBG ("[PID %d]Process exiting... %d\r\n", getpid (), getpid ()); + return 0; +} -- cgit