diff options
Diffstat (limited to 'testcode')
16 files changed, 3107 insertions, 0 deletions
diff --git a/testcode/app_example/CMakeLists.txt b/testcode/app_example/CMakeLists.txt new file mode 100644 index 0000000..ff25e1f --- /dev/null +++ b/testcode/app_example/CMakeLists.txt @@ -0,0 +1,31 @@ +######################################################################### +# +# 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. +######################################################################### + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) +PROJECT(nStack) +SET(CMAKE_SKIP_RPATH TRUE) +SET(CMAKE_C_COMPILER "gcc") +SET(OS_RELEASE "" CACHE STRING "User-specified OS release.") + +SET(EXECUTABLE_PATH ${CMAKE_CURRENT_LIST_DIR}/release/bin) +SET(LIB_PATH_STATIC ${PROJECT_BINARY_DIR}) +SET(LIB_PATH_SHARED ${CMAKE_CURRENT_LIST_DIR}/../../release/lib64) + +SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH_STATIC}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_PATH}) +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_PATH_SHARED}) +ADD_SUBDIRECTORY(perf-test) +ADD_SUBDIRECTORY(func-test) diff --git a/testcode/app_example/build/.gitkeep b/testcode/app_example/build/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/testcode/app_example/build/.gitkeep diff --git a/testcode/app_example/func-test/CMakeLists.txt b/testcode/app_example/func-test/CMakeLists.txt new file mode 100644 index 0000000..865eba5 --- /dev/null +++ b/testcode/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) +ADD_SUBDIRECTORY(file_transfer) diff --git a/testcode/app_example/func-test/file_transfer/CMakeLists.txt b/testcode/app_example/func-test/file_transfer/CMakeLists.txt new file mode 100644 index 0000000..e4f653a --- /dev/null +++ b/testcode/app_example/func-test/file_transfer/CMakeLists.txt @@ -0,0 +1,30 @@ +######################################################################### +# +# 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(vc_serv_file server_filetrans.c) +TARGET_LINK_LIBRARIES(vc_serv_file libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(vc_cli_file client_filetrans.c) +TARGET_LINK_LIBRARIES(vc_cli_file libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(kc_serv_file server_filetrans.c) +TARGET_LINK_LIBRARIES(kc_serv_file pthread) + +ADD_EXECUTABLE(kc_cli_file client_filetrans.c) +TARGET_LINK_LIBRARIES(kc_cli_file pthread) diff --git a/testcode/app_example/func-test/file_transfer/client_filetrans.c b/testcode/app_example/func-test/file_transfer/client_filetrans.c new file mode 100644 index 0000000..f0e2a80 --- /dev/null +++ b/testcode/app_example/func-test/file_transfer/client_filetrans.c @@ -0,0 +1,276 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <fcntl.h> +#include <netdb.h> +#include <ctype.h> +char *END_FLAG = "=================END"; +#define HEXCONVERT_COLS 8 +#define HEX_CONVERT 1 +//#define DEBUG 1 +#define out(fmt, arg...) (void)printf(fmt, ##arg) + +#ifdef DEBUG +#define DBG(fmt, arg...) do { \ + out("[Debug] " fmt, ##arg); \ + } while (0) +#else +#define DBG(fmt, arg...) ((void)0) +#endif + +void error(const char *msg) +{ + perror(msg); + out("./client_tcp [server_ip_address] [port number] [filename] [client_ip_address]\n"); + exit(1); +} + +#if defined(HEX_CONVERT) && defined(DEBUG) +void hexconvert(void *mem, unsigned int len) +{ + unsigned int i; + + for (i = 0; + i < + len + + ((len % HEXCONVERT_COLS) ? (HEXCONVERT_COLS - + len % HEXCONVERT_COLS) : 0); i++) + { + /* print offset */ + if (i % HEXCONVERT_COLS == 0) + { + DBG("\n0x%06x: ", i); + } + + /*print hex data */ + if (i < len) + { + DBG("%02x ", 0xFF & ((char *) mem)[i]); + } + else /* end of block, just aligning for ASCII dump */ + { + DBG("\n"); + } + } +} +#endif + +void tcp(char **pArgv) +{ + + int sockfd, portno; + char buff[1024]; + + struct sockaddr_in serv_addr, cli_addr; + struct hostent *server; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + { + error("error in socket creation\n"); + } + out("socket create successful\n"); + + portno = atoi(pArgv[2]); + server = gethostbyname(pArgv[1]); + + if (server == NULL) + { + fprintf(stderr, "error no such host\n"); + } + + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr, + server->h_length); + serv_addr.sin_port = htons(portno); + bzero((char *) &cli_addr, sizeof(serv_addr)); + + cli_addr.sin_family = AF_INET; + cli_addr.sin_addr.s_addr = inet_addr(pArgv[4]); + cli_addr.sin_port = htons(portno); + if (bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0) + { + error("bind fail"); + } + out("Bind successful\n"); + + if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < + 0) + { + error("connection fail"); + } + out("connection done\n"); + + FILE *file; + int filebyte = 0; + int lsize, totalsize = 0; + + file = fopen(pArgv[3], "r"); + fseek(file, 0, SEEK_END); + lsize = ftell(file); + rewind(file); + out("Name of file: %s, Size of file : %d\n", pArgv[3], lsize); + if (write(sockfd, &lsize, sizeof(int)) == -1) + { + out("error executing write\n"); + } + if (write(sockfd, pArgv[3], 255) == -1) + { + out("error executing write\n"); + } + while (lsize > totalsize) + { + bzero(buff, 1024); + fseek(file, totalsize, SEEK_SET); + filebyte = fread(buff, 1, sizeof(buff), file); + if (filebyte == 0) + { + printf("file End of file\n"); + break; + } + + if (filebyte < 0) + error("error in reading file. \n"); +#if defined(HEX_CONVERT) && defined(DEBUG) + DBG("=========================================\n"); + hexconvert(buff, filebyte); + DBG("=========================================\n"); +#endif + + void *p = buff; + totalsize += filebyte; + + while (filebyte > 0) + { +#ifdef DEBUG + DBG("=========================================\n"); + puts((const char *) p); + DBG("=========================================\n"); +#endif + int bytes_written = write(sockfd, p, filebyte); + if (bytes_written <= 0) + { + error("error in Socket write.\n"); + } + + filebyte -= bytes_written; + p += bytes_written; +//#if DEBUG + DBG("Total size of file = %d, Total Bytes sent to socket = %d, bytes_written in each step = %d\n", lsize, totalsize, bytes_written); +//#endif + } + } + out("file has been sent successfully\n"); + out("Final Total size of file = %d, Total Bytes sent to socket = %d\n", + lsize, totalsize); + + fclose(file); + sleep(60); + close(sockfd); + return; +} + +void udp(char **pArgv) +{ + int sockfd, n, fd, sz, portno, MAXLINE; + FILE *fp; + struct sockaddr_in servaddr, cliaddr; + char *buf; + char *target, *path; + portno = atoi(pArgv[2]); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(portno); + servaddr.sin_addr.s_addr = inet_addr(pArgv[1]); + bzero(&cliaddr, sizeof(servaddr)); + cliaddr.sin_family = AF_INET; + cliaddr.sin_port = htons(portno); + cliaddr.sin_addr.s_addr = inet_addr(pArgv[3]); + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) + { + out("error in socket creation\n"); + } + out("socket create successful\n"); + + if (bind(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0) + { + out("bind fail"); + } + out("Bind successful\n"); + + path = pArgv[4]; + target = pArgv[5]; + MAXLINE = atoi(pArgv[6]); + buf = malloc(MAXLINE * sizeof(int)); + fp = fopen(path, "r"); + fseek(fp, 0L, SEEK_END); + sz = ftell(fp); + out("The size of the path file is %d", sz); + sendto(sockfd, target, strlen(target), 0, + (struct sockaddr *) &servaddr, sizeof(servaddr)); + n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, NULL); + if (!strncmp(buf, "ok", 2)) + { + out("Filename sent.\n"); + } + + fd = open(path, O_RDONLY); + while ((n = read(fd, buf, MAXLINE)) > 0) + { + sendto(sockfd, buf, n, 0, (struct sockaddr *) &servaddr, + sizeof(servaddr)); + } + sendto(sockfd, END_FLAG, strlen(END_FLAG), 0, + (struct sockaddr *) &servaddr, sizeof(servaddr)); + fclose(fp); + sleep(60); + close(sockfd); + return; +} + +int main(int argc, char *argv[]) +{ + int i; + char **pArgv, str[10]; + pArgv = (char **) malloc(sizeof(char *) * 10); + for (i = 0; i < 10; i++) + { + pArgv[i] = (char *) malloc(sizeof(char) * 20); + } + printf("%s", argv[1]); + + if (strcmp("tcp", argv[1]) == 0) + { + strcpy(pArgv[0], "tcp"); + printf("pArgv[0]=%s", pArgv[0]); + /* The arguments of tcp are [server_ip_address] [port number] [filename] [client_ip_address] */ + for (i = 1; i < 5; i++) + { + strcpy(pArgv[i], argv[i + 1]); + } + tcp(pArgv); + } + + else + { + strcpy(str, argv[1]); + if (strcmp("udp", str) == 0) + { + strcpy(pArgv[0], "udp"); + printf("pArgv[0]=%s", pArgv[0]); + /* The arguments of udp are [server_ip_address] [port number] [client_ip_address] [filename] [target_filename] [MAX_BUFFER_LENGTH] */ + for (i = 1; i < 7; i++) + { + strcpy(pArgv[i], argv[i + 1]); + } + udp(pArgv); + } + } + return 0; +} diff --git a/testcode/app_example/func-test/file_transfer/server_filetrans.c b/testcode/app_example/func-test/file_transfer/server_filetrans.c new file mode 100644 index 0000000..8b7e25f --- /dev/null +++ b/testcode/app_example/func-test/file_transfer/server_filetrans.c @@ -0,0 +1,336 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <netdb.h> +#include <ctype.h> +#include <arpa/inet.h> +#include <fcntl.h> +char *END_FLAG = "=================END"; +#define HEXCONVERT_COLS 8 +#define HEX_CONVERT 1 +//#define DEBUG 1 +#define out(fmt, arg...) (void)printf(fmt, ##arg) + +#ifdef DEBUG +#define DBG(fmt, arg...) do { \ + out("[Debug] " fmt, ##arg); \ + } while (0) +#else +#define DBG(fmt, arg...) ((void)0) +#endif + +void error(const char *msg) +{ + perror(msg); + out("./server_tcp [server_ip_address] [port number]\n"); + exit(1); +} + +#if defined(HEX_CONVERT) && defined(DEBUG) +void hexconvert(void *mem, unsigned int len) +{ + unsigned int i; + + for (i = 0; + i < + len + + ((len % HEXCONVERT_COLS) ? (HEXCONVERT_COLS - + len % HEXCONVERT_COLS) : 0); i++) + { + /* print offset */ + if (i % HEXCONVERT_COLS == 0) + { + DBG("\n0x%06x: ", i); + } + + /*print hex data */ + if (i < len) + { + DBG("%02x ", 0xFF & ((char *) mem)[i]); + } + else /* end of block, just aligning for ASCII dump */ + { + DBG("\n"); + } + } +} +#endif +int compareFiles(FILE * fp1, FILE * fp2) +{ + + char ch1 = getc(fp1); + char ch2 = getc(fp2); + int error = 0, pos = 0, line = 1; + + while (ch1 != EOF && ch2 != EOF) + { + pos++; + if (ch1 == '\n' && ch2 == '\n') + { + line++; + pos = 0; + } + + if (ch1 != ch2) + { + error++; + DBG("Line Number : %d \tError" " Position :%d \n", line, pos); + } + + ch1 = getc(fp1); + ch2 = getc(fp2); + } + + //printf("Total Errors : %d\t", error); + return error; +} + +void tcp(char **pArgv) +{ + + int sockfd, newsockfd, portno; + char buff[1024], filename[255]; + + struct sockaddr_in serv_addr, cli_addr; + socklen_t clilen; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + { + error("error in socket creation"); + } + out("socket create successful\n"); + + bzero((char *) &serv_addr, sizeof(serv_addr)); + portno = atoi(pArgv[2]); + + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr(pArgv[1]); + serv_addr.sin_port = htons(portno); + + if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) + { + error("bind fail"); + } + out("Bind successful\n"); + listen(sockfd, 5); + clilen = sizeof(cli_addr); + + newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); + if (newsockfd < 0) + { + error("error in accept"); + } + out("socket accept succesful\n"); + bzero(buff, 1024); + + FILE *fp; + int lSize = 0, totallSize = 0; + + bzero(filename, 255); + + fclose(fopen("receive_file.txt", "w")); + if (system("chmod +x *") == -1) + { + out(" incorrect use of system\n"); + } + fp = fopen("receive_file.txt", "a"); + + if (read(newsockfd, &lSize, sizeof(int)) == -1) + { + out("error executing read\n"); + } + if (read(newsockfd, filename, sizeof(filename)) == -1) + { + out("error executing read\n"); + } + + while (lSize > totallSize) + { + int bytes_read = 0; + bzero(buff, 1024); + + bytes_read = read(newsockfd, buff, 1024); + + if (bytes_read == 0) + { + break; + } + + if (bytes_read < 0) + { + error("error in Socket read.\n"); + } + +#if defined(HEX_CONVERT) && defined(DEBUG) + DBG("=========================================\n"); + hexconvert(buff, bytes_read); + DBG("=========================================\n"); +#endif +#ifdef DEBUG + DBG("=========================================\n"); + puts((const char *) buff); + DBG("=========================================\n"); +#endif + totallSize += bytes_read; + + if (fwrite(buff, 1, bytes_read, fp) == -1) + { + error("error in file write\n"); + } +//#if DEBUG + DBG("Total size of file = %d, Total Bytes sent to socket = %d, bytes_read in each step = %d\n", lSize, totallSize, bytes_read); +//#endif + } + out("file name = %s\n", filename); + out("Final total size of file = %d, total read from socket = %d\n", lSize, + totallSize); + out("copy complete\n"); + fclose(fp); + + FILE *fp1 = fopen("receive_file.txt", "r"); + FILE *fp2 = fopen(filename, "r"); + + fseek(fp2, 0L, SEEK_END); + int lfile_size = ftell(fp2); + rewind(fp2); + if (lfile_size != lSize) + { + out("Size unmatch...\n"); + } + else + { + out("Size match...\n"); + } + + if (compareFiles(fp1, fp2) > 0) + { + out("file unmatch...\n"); + } + else + { + out("file match...\n"); + } + + close(newsockfd); + close(sockfd); + return; +} + +void +run(int sockfd, struct sockaddr *cliaddr, socklen_t clilen, char *res_buf, + int MAXLINE) +{ + int n, fd; + socklen_t len; + char *buf, *buf2; + FILE *fp1, *fp2; + buf = malloc(MAXLINE + 1); + len = clilen; + n = recvfrom(sockfd, buf, MAXLINE, 0, cliaddr, &len); + buf[n] = 0; + out("Received from client:[%s] \n", buf); + buf2 = malloc(MAXLINE); + strcpy(buf2, buf); + sendto(sockfd, "ok", strlen("ok"), 0, cliaddr, len); + fd = open(buf, O_RDWR | O_CREAT, 0666); + while ((n = recvfrom(sockfd, buf, MAXLINE, 0, cliaddr, &len))) + { + buf[n] = 0; + //out("%s", buf); + if (!(strcmp(buf, END_FLAG))) + { + break; + } + if (write(fd, buf, n) == -1) + { + out("error in executing write\n"); + } + } + fp1 = fopen(buf2, "r"); + fp2 = fopen(res_buf, "r"); + + if (compareFiles(fp1, fp2) == 0) + { + out("\nPass:The contents of the files are same"); + } + else + { + out("\nFail:The contents of the files are different"); + } + close(fd); +} + +void udp(char **pArgv) +{ + int sockfd, portno, MAXLINE; + struct sockaddr_in servaddr, cliaddr; + char *res_buf; + res_buf = pArgv[3]; + + portno = atoi(pArgv[2]); + MAXLINE = atoi(pArgv[4]); + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) + { + out("error in socket creation\n"); + } + out("socket create successful\n"); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr(pArgv[1]); + servaddr.sin_port = htons(portno); + + if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) + { + out("bind fail"); + } + out("Binded successfully\n"); + fd_set read_fds; + FD_ZERO(&read_fds); + FD_SET(sockfd, &read_fds); + int fdmax = sockfd; + if (FD_ISSET(sockfd, &read_fds)) + { + run(fdmax, (struct sockaddr *) &cliaddr, sizeof(cliaddr), res_buf, + MAXLINE); + } + return; +} + +int main(int argc, char *argv[]) +{ + int i, j; + char **pArgv; + pArgv = (char **) malloc(sizeof(char *) * 10); + for (i = 0; i < 10; i++) + { + pArgv[i] = (char *) malloc(sizeof(char) * 20); + } + if (strcmp("tcp", argv[1]) == 0) + { + strcpy(pArgv[0], "tcp"); + /* The arguments of tcp are [server_ip_address] [port number] */ + for (i = 1; i < 3; i++) + { + strcpy(pArgv[i], argv[i + 1]); + } + tcp(pArgv); + } + else if (strcmp("udp", argv[1]) == 0) + { + strcpy(pArgv[0], "udp"); + /* The arguments of udp are [server_ip_address] [port number] [filename] [MAX_BUFFER_LENGTH] */ + for (i = 1; i < 5; i++) + { + strcpy(pArgv[i], argv[i + 1]); + } + udp(pArgv); + } + + return 0; +} diff --git a/testcode/app_example/func-test/fork/CMakeLists.txt b/testcode/app_example/func-test/fork/CMakeLists.txt new file mode 100644 index 0000000..a78f617 --- /dev/null +++ b/testcode/app_example/func-test/fork/CMakeLists.txt @@ -0,0 +1,30 @@ +######################################################################### +# +# 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(vtcp_fork_server tcpserver.c) +TARGET_LINK_LIBRARIES(vtcp_fork_server libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(vtcp_client tcpclient.c) +TARGET_LINK_LIBRARIES(vtcp_client libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(ktcp_fork_server tcpserver.c) +TARGET_LINK_LIBRARIES(ktcp_fork_server pthread) + +ADD_EXECUTABLE(ktcp_client tcpclient.c) +TARGET_LINK_LIBRARIES(ktcp_client pthread) diff --git a/testcode/app_example/func-test/fork/tcpclient.c b/testcode/app_example/func-test/fork/tcpclient.c new file mode 100644 index 0000000..8023b34 --- /dev/null +++ b/testcode/app_example/func-test/fork/tcpclient.c @@ -0,0 +1,170 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> + +#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.errno=%d\n", errno); + 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/testcode/app_example/func-test/fork/tcpserver.c b/testcode/app_example/func-test/fork/tcpserver.c new file mode 100644 index 0000000..af11832 --- /dev/null +++ b/testcode/app_example/func-test/fork/tcpserver.c @@ -0,0 +1,156 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/wait.h> + +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.errno=%d\n", errno); + 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; +} diff --git a/testcode/app_example/module_config.json b/testcode/app_example/module_config.json new file mode 100644 index 0000000..fd4b47a --- /dev/null +++ b/testcode/app_example/module_config.json @@ -0,0 +1,15 @@ +{ + "default_stack_name": "kernel", /*when rd can't be find maybe choose the defualt one*/ + "module_list": [ + { + "stack_name": "kernel", /*stack name*/ + "function_name": "kernel_stack_register", + "libname": "./", /*library name, if loadtype is static, this maybe + null, else must give a library name*/ + "deploytype": "1", /*deploy model type:model type1, model type2, + model type3. Indicating single or multi process + deployment. Used during shared memory initialization.*/ + "stackid": "0", /*stack id, this must be ordered and not be repeated*/ + }, + ] +} diff --git a/testcode/app_example/perf-test/CMakeLists.txt b/testcode/app_example/perf-test/CMakeLists.txt new file mode 100644 index 0000000..dbef0f2 --- /dev/null +++ b/testcode/app_example/perf-test/CMakeLists.txt @@ -0,0 +1,43 @@ +######################################################################### +# +# 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(vc_common multi_tcp_common_app_Cli.c) +TARGET_LINK_LIBRARIES(vc_common libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(vs_epoll multi_tcp_epoll_app_Ser.c) +TARGET_LINK_LIBRARIES(vs_epoll libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(vs_select multi_tcp_select_app_Ser.c) +TARGET_LINK_LIBRARIES(vs_select libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(kc_common multi_tcp_common_app_Cli.c) +TARGET_LINK_LIBRARIES(kc_common pthread) + +ADD_EXECUTABLE(ks_epoll multi_tcp_epoll_app_Ser.c) +TARGET_LINK_LIBRARIES(ks_epoll pthread) + +ADD_EXECUTABLE(ks_select multi_tcp_select_app_Ser.c) +TARGET_LINK_LIBRARIES(ks_select pthread) + +ADD_EXECUTABLE(vs_common multi_tcp_common_Ser.c) +TARGET_LINK_LIBRARIES(vs_common libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(ks_common multi_tcp_common_Ser.c) +TARGET_LINK_LIBRARIES(ks_common pthread) + diff --git a/testcode/app_example/perf-test/multi_tcp_common_Ser.c b/testcode/app_example/perf-test/multi_tcp_common_Ser.c new file mode 100644 index 0000000..27d44ae --- /dev/null +++ b/testcode/app_example/perf-test/multi_tcp_common_Ser.c @@ -0,0 +1,538 @@ +/* +* +* 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. +*/ + +#include <fcntl.h> +#include <memory.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <time.h> +#include <linux/tcp.h> +#define __USE_GNU +#include <sched.h> +#include <pthread.h> +#include <arpa/inet.h> +#include <sys/epoll.h> +#include <errno.h> + +#define _BIND bind +#define _LISTEN listen +#define _SOCKET socket +#define _ACCEPT accept +#define _SEND send +#define _RECV recv +#define _CLOSE close +#define _CONNECT connect +#define _PROTOCOL IPPROTO_TCP + +#define MAX_TEST_TIME 1000 +#define MSG_LENGTH 256 +#define CORE_NUM 8 +#define START_CPU_ID 2 +#define MAX_CONN_LIMIT 256 +#define MAX_PORT_NUM 65535 +//1:A-B ;0:A-B-A +#define SEND_RECV_MODE 1 +#define MAX_EVENTS 1000 +#define Default_PortID 12345 +#define Default_SleepCnt 10000 +#define Default_SleepTime 1000000 +#define Flag_Print 1 +#define Fd_Number 1 + +static struct sockaddr_in g_dest; +static struct sockaddr_in g_src; +static struct sockaddr_in g_recv; + +int times = MAX_TEST_TIME; +int msg_length = MSG_LENGTH; +int coreNum = CORE_NUM; +int startCPUId = START_CPU_ID; +int connectNum = MAX_CONN_LIMIT; +int msgMode = SEND_RECV_MODE; +int sleepCnt = Default_SleepCnt; +int sleepTime = Default_SleepTime; //us +int fdNumber = Fd_Number; +int flagPrint = Flag_Print; +int unitPrint = 0; +int waitTime = 0; + +int srcPort = Default_PortID; +int destPort = 0; +int recvPort = 0; +char sendarr[256] = ""; +char recvarr[256] = ""; +char destarr[256] = ""; + +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); + + memset(&g_recv, 0, sizeof(g_recv)); + g_recv.sin_family = AF_INET; + g_recv.sin_addr.s_addr = inet_addr("0.0.0.0"); + g_recv.sin_port = htons(7895); + bzero(&(g_recv.sin_zero), 8); + +} + +static int process_arg(int argc, char *argv[]) +{ + int opt = 0; + int error = 0; + const char *optstring = "p:d:s:a:l:t:e:i:f:r:n:w:u:x:"; + int rw_mark = 0; + + if (argc < 4) + { + printf + ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -l msg_length; \n"); + printf + ("\t-t MAX_TEST_TIME; -i msg_interval ; -f client fd number ; -r receive port; -n connectNum(one server vs n client)\n"); + return 0; + } + while ((opt = getopt(argc, argv, optstring)) != -1) + { + switch (opt) + { + case 'p': + destPort = atoi(optarg); + g_dest.sin_port = htons(atoi(optarg)); + break; + case 'd': + stpcpy(destarr, optarg); + g_dest.sin_addr.s_addr = inet_addr(optarg); + break; + case 's': + stpcpy(sendarr, optarg); + g_src.sin_addr.s_addr = inet_addr(optarg); + g_recv.sin_addr.s_addr = inet_addr(optarg); + break; + case 'a': + //g_src.sin_port = htons(atoi(optarg)); + srcPort = atoi(optarg); + break; + case 'l': + msg_length = atoi(optarg); + break; + case 't': + times = atoi(optarg); + break; + case 'e': + sleepCnt = atoi(optarg); + break; + case 'i': + sleepTime = atoi(optarg); + break; + case 'f': + fdNumber = atoi(optarg); + break; + case 'r': + recvPort = atoi(optarg); + g_recv.sin_port = htons(atoi(optarg)); + break; + case 'n': + connectNum = atoi(optarg); + break; + case 'w': + waitTime = atoi(optarg); + break; + case 'u': + unitPrint = atoi(optarg); + break; + case 'x': + flagPrint = atoi(optarg); + break; + + } + } + return 1; +} + +void process_client(void) +{ + int sendLen = 0; + int i = 0, t = 0, p = 0, optval = 0, ret = 0; + char send_buf[1000] = ""; + int c_socketfd[100] = { 0 }; + int errbind[1000] = { 0 }; + int errconn[1000] = { 0 }; + + int send_count[1000] = { 0 }; + int pps = 0; + long pps_time = 0; + + struct timespec startTime, endTime; + struct timespec countStart; + struct timespec countEnd; + + memset(&countStart, 0, sizeof(countStart)); + memset(&countEnd, 0, sizeof(countEnd)); + + for (i = 0; i < fdNumber; i++) + { + c_socketfd[i] = _SOCKET(PF_INET, SOCK_STREAM, _PROTOCOL); + if (0 > c_socketfd[i]) + { + printf("client %d failed,err %d\n", i, errno); + } + else + { + printf("client %d created success\n", i); + } + } + + for (i = 0; i < fdNumber; i++) + { + optval = 1; + ret = + setsockopt(c_socketfd[i], SOL_SOCKET, SO_REUSEADDR, + (void *) &optval, sizeof(optval)); + if (ret == -1) + { + printf("Couldn't setsockopt(SO_REUSEADDR)\n"); + break; + } + } + + for (i = 0; i < fdNumber; i++) + { + g_src.sin_port = htons(srcPort + i); + errbind[i] = + _BIND(c_socketfd[i], (struct sockaddr *) &g_src, sizeof(g_src)); + if (errbind[i] < 0) + { + printf("client %d bind Failed %d\n", i, errno); + _CLOSE(c_socketfd[i]); + c_socketfd[i] = -1; + continue; + } + else + { + printf("client %d bind Success port:%d IP:%s\n", i, + ntohs(g_src.sin_port), + inet_ntoa(*((struct in_addr *) &(g_src.sin_addr.s_addr)))); + } + } + for (i = 0; i < fdNumber; i++) + { + if (errbind[i] >= 0) + { + errconn[i] = + _CONNECT(c_socketfd[i], (struct sockaddr *) &g_dest, + sizeof(g_dest)); + if (errconn[i] < 0) + { + printf("client %d Connect Failed %d\n", i, errno); + _CLOSE(c_socketfd[i]); + c_socketfd[i] = -1; + continue; + } + else + { + printf("client %d Connect Success port:%d, IP:%s\n", i, + ntohs(g_dest.sin_port), + inet_ntoa(* + ((struct in_addr *) + &(g_dest.sin_addr.s_addr)))); + } + } + } + + sleep(1); + + clock_gettime(CLOCK_MONOTONIC, &startTime); + clock_gettime(CLOCK_MONOTONIC, &countStart); + + for (t = 0; t < times; t++) + { + for (i = 0; i < fdNumber; i++) + { + if (c_socketfd[i] < 0) + { + continue; + } + do + { + sendLen = _SEND(c_socketfd[i], send_buf, msg_length, 0); + } + while (sendLen <= 0); + send_count[i]++; + } + + if (0 != sleepTime) + { + if ((t % sleepCnt) == 0) + { + usleep(sleepTime); + } + } + + if ((send_count[0] % unitPrint) == 0) + { + clock_gettime(CLOCK_MONOTONIC, &countEnd); + + pps_time = + (countEnd.tv_sec - countStart.tv_sec) * 1000000000 + + countEnd.tv_nsec - countStart.tv_nsec; + pps = ((float) 1000000000 / pps_time) * unitPrint * fdNumber; + if ((flagPrint != 0)) + { + printf(" sendcount %d, time: %ld ns\n", + send_count[0] * fdNumber, pps_time); + } + printf("sendcount %d , pps=%d\n", send_count[0] * fdNumber, pps); + clock_gettime(CLOCK_MONOTONIC, &countStart); + } + } + + clock_gettime(CLOCK_MONOTONIC, &endTime); + + for (i = 0; i < fdNumber; i++) + { + printf("client %d send %d , sendtime :%ld s %ld ns\n", i, + send_count[i], endTime.tv_sec - startTime.tv_sec, + endTime.tv_nsec - startTime.tv_nsec); + } + + for (i = 0; i < fdNumber; i++) + { + printf("client %d close!\n", i); + if (c_socketfd[i] > 0) + _CLOSE(c_socketfd[i]); + } + + pthread_exit(NULL); +} + +/* + using this thread to do recv msg; +*/ +void *process_server_msg_thread(void *pArgv) +{ + int recvLen = 0, recvLen2 = 0; + char send_buf[1000]; + char recv_buf[1000]; + int recv_count = 0; + long recv_ppstime = 0; + int recv_pps = 0; + int ret; + struct timespec recvStart; + struct timespec recvEnd; + memset(&recvStart, 0, sizeof(recvStart)); + memset(&recvEnd, 0, sizeof(recvEnd)); + + pthread_detach(pthread_self()); + + int msgFd = *(int *) pArgv; + clock_gettime(CLOCK_MONOTONIC, &recvStart); + while (recv_count < times) + { + recvLen = 0; + recvLen2 = 0; + while (1) + { + recvLen2 = + recv(msgFd, recv_buf + recvLen, msg_length - recvLen, 0); + if (recvLen2 <= 0) + { + break; + } + else if (recvLen2 == msg_length - recvLen) + { + recvLen = 0; + recv_count++; + if (msg_length != send(msgFd, send_buf, msg_length, 0)) + { + printf("send failed!====, need exit\n"); + } + + } + else if (recvLen2 < msg_length - recvLen) + { + recvLen += recvLen2; + } + if ((flagPrint != 0) && ((recv_count % unitPrint) == 0)) + { + clock_gettime(CLOCK_MONOTONIC, &recvEnd); + recv_ppstime = + (recvEnd.tv_sec - recvStart.tv_sec) * 1000000000 + + recvEnd.tv_nsec - recvStart.tv_nsec; + recv_pps = ((float) 1000000000 / recv_ppstime) * unitPrint; + printf("receive count:%d, receive time: %ld ns\n", recv_count, + recv_ppstime); + printf("receive pps = %d\n", recv_pps); + clock_gettime(CLOCK_MONOTONIC, &recvStart); + } + } + } + close(msgFd); +} + +/* + using this thread to do accept connect +*/ +void *process_server_accept_thread(void *pArgv) +{ + int listenFd = 0; + int x, optval, ret, m = 0; + int acpt_socketfd[1000] = { 0 }; + + listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (0 > listenFd) + { + printf("ERROR:socket failed,errno [%d]\n", errno); + return; + } + else + { + printf("INFO:Create listen socket Success, listenFd[%d]\n", listenFd); + } + + if (0 > fcntl(listenFd, F_SETFL, O_NONBLOCK)) + { + printf("ERROR:fcntl failed. fd[%d], errno[%d]/n", listenFd, errno); + close(listenFd); + } + + optval = 1; + ret = + setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, + sizeof(optval)); + if (ret == -1) + { + printf("ERROR:setsockopt failed. fd[%d], errno[%d]\n", listenFd, + errno); + close(listenFd); + return; + } + + if (0 != + bind(listenFd, (struct sockaddr *) &g_recv, sizeof(struct sockaddr))) + { + printf("ERROR:bind failed. fd[%d] errno [%d]\n", listenFd, errno); + printf("INFO:Bind Failed, port %d IP:%s\n", ntohs(g_recv.sin_port), + inet_ntoa(*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); + close(listenFd); + exit(-1); + } + else + { + printf("Info Bind Success, port %d IP:%s\n", ntohs(g_recv.sin_port), + inet_ntoa(*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); + } + + if (0 != listen(listenFd, 100)) + { + printf("server socket listen failed. err %d\n", errno); + close(listenFd); + return; + } + printf("Listen Success\n"); + + int timeout = -1; + int accpedNum = 0; + while (accpedNum < connectNum) + { + while (1) + { + acpt_socketfd[accpedNum] = + accept4(listenFd, NULL, NULL, SOCK_NONBLOCK); + if (acpt_socketfd[accpedNum] < 0) + { + break; + } + + fcntl(acpt_socketfd[accpedNum], F_SETFL, 0); + + /*add new accptFd to MsgEpFD */ + pthread_t ser_rcv_thread_id; + if (pthread_create + (&ser_rcv_thread_id, NULL, process_server_msg_thread, + (void *) &acpt_socketfd[accpedNum]) == -1) + { + printf("create process_server_msg_thread fail\n"); + break; + } + + printf("accept cnt [%d], cur accept fd [%d]\n", accpedNum, + acpt_socketfd[accpedNum]); + accpedNum++; + } + } + close(listenFd); + while (1) + { + sleep(10); + } + + pthread_exit(NULL); +} + +void main(int argc, char *argv[]) +{ + socklen_t addrlen = sizeof(struct sockaddr); + int err = 0, result = 0, ret = 0; + int i = 0, j = 0, optval = 0, z = 0, x, listenfd; + cpu_set_t mask; + + setArgsDefault(); + ret = process_arg(argc, argv); + if (ret != 1) + { + printf("The param error\n"); + return; + } + + pthread_t server_thread_id; + + if (pthread_create + (&server_thread_id, NULL, process_server_accept_thread, NULL) == -1) + { + printf("create process_server_accept_thread fail\n"); + return; + } + + printf("create process_server_accept_thread success\n"); + + if (server_thread_id != 0) + { + printf("Server Thread join\n"); + pthread_join(server_thread_id, NULL); + } + + while (1) + { + sleep(10); + } + + return; +} diff --git a/testcode/app_example/perf-test/multi_tcp_common_app_Cli.c b/testcode/app_example/perf-test/multi_tcp_common_app_Cli.c new file mode 100644 index 0000000..02991bd --- /dev/null +++ b/testcode/app_example/perf-test/multi_tcp_common_app_Cli.c @@ -0,0 +1,392 @@ +/* +* +* 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. +*/ + +#define _GNU_SOURCE +#include <sys/socket.h> +#include <fcntl.h> +#include <memory.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <time.h> +#include <linux/tcp.h> +#include <sched.h> +#include <pthread.h> +#include <arpa/inet.h> +#include <sys/epoll.h> +#include <errno.h> + +#define _BIND bind +#define _LISTEN listen +#define _SOCKET socket +#define _ACCEPT accept +#define _SEND send +#define _RECV recv +#define _CLOSE close +#define _CONNECT connect +#define _PROTOCOL IPPROTO_TCP + +#define MAX_TEST_TIME 1000 +#define MSG_LENGTH 256 +#define CORE_NUM 8 +#define START_CPU_ID 2 +#define MAX_CONN_LIMIT 256 +#define MAX_PORT_NUM 65535 +//1:A-B ;0:A-B-A +#define SEND_RECV_MODE 1 +#define MAX_EVENTS 1000 +#define Default_PortID 12345 +#define Default_SleepCnt 10000 +#define Default_SleepTime 1000000 +#define Flag_Print 1 +#define Fd_Number 1 + +static struct sockaddr_in g_dest; +static struct sockaddr_in g_src; +static struct sockaddr_in g_recv; + +int times = MAX_TEST_TIME; +int msg_length = MSG_LENGTH; +int coreNum = CORE_NUM; +int startCPUId = START_CPU_ID; +int connectNum = MAX_CONN_LIMIT; +int msgMode = SEND_RECV_MODE; +int sleepCnt = Default_SleepCnt; +int sleepTime = Default_SleepTime; //us +int fdNumber = Fd_Number; +int flagPrint = Flag_Print; +int unitPrint = 0; +int waitTime = 0; + +int srcPort = Default_PortID; +int destPort = 0; +int recvPort = 0; +char sendarr[256] = ""; +char recvarr[256] = ""; +char destarr[256] = ""; + +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); + + memset(&g_recv, 0, sizeof(g_recv)); + g_recv.sin_family = AF_INET; + g_recv.sin_addr.s_addr = inet_addr("0.0.0.0"); + g_recv.sin_port = htons(7895); + bzero(&(g_recv.sin_zero), 8); + +} + +static int process_arg(int argc, char *argv[]) +{ + int opt = 0; + int error = 0; + const char *optstring = "p:d:s:a:l:t:e:i:f:r:n:w:u:x:"; + int rw_mark = 0; + + if (argc < 4) + { + printf + ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -l msg_length; \n"); + printf + ("\t-t MAX_TEST_TIME; -i msg_interval ; -f client fd number ; -r receive port; -n connectNum(one server vs n client)\n"); + return 0; + } + while ((opt = getopt(argc, argv, optstring)) != -1) + { + switch (opt) + { + case 'p': + destPort = atoi(optarg); + g_dest.sin_port = htons(atoi(optarg)); + break; + case 'd': + stpcpy(destarr, optarg); + g_dest.sin_addr.s_addr = inet_addr(optarg); + break; + case 's': + stpcpy(sendarr, optarg); + g_src.sin_addr.s_addr = inet_addr(optarg); + g_recv.sin_addr.s_addr = inet_addr(optarg); + break; + case 'a': + //g_src.sin_port = htons(atoi(optarg)); + srcPort = atoi(optarg); + break; + case 'l': + msg_length = atoi(optarg); + break; + case 't': + times = atoi(optarg); + break; + case 'e': + sleepCnt = atoi(optarg); + break; + case 'i': + sleepTime = atoi(optarg); + break; + case 'f': + fdNumber = atoi(optarg); + break; + case 'r': + recvPort = atoi(optarg); + g_recv.sin_port = htons(atoi(optarg)); + break; + case 'n': + connectNum = atoi(optarg); + break; + case 'w': + waitTime = atoi(optarg); + break; + case 'u': + unitPrint = atoi(optarg); + break; + case 'x': + flagPrint = atoi(optarg); + break; + + } + } + return 1; +} + +void process_client(void) +{ + int sendLen = 0; + int i = 0, t = 0, p = 0, optval = 0, ret = 0; + char send_buf[1000] = ""; + char recv_buf[1000] = ""; + int c_socketfd[100] = { 0 }; + int errbind[1000] = { 0 }; + int errconn[1000] = { 0 }; + + int send_count[1000] = { 0 }; + int pps = 0; + long pps_time = 0; + + struct timespec startTime, endTime; + struct timespec countStart; + struct timespec countEnd; + memset(&countStart, 0, sizeof(countStart)); + memset(&countEnd, 0, sizeof(countEnd)); + + for (i = 0; i < fdNumber; i++) + { + c_socketfd[i] = _SOCKET(PF_INET, SOCK_STREAM, _PROTOCOL); + if (0 > c_socketfd[i]) + { + printf("client %d failed,err %d\n", i, errno); + } + else + { + printf("client %d created success\n", i); + } + } + + for (i = 0; i < fdNumber; i++) + { + optval = 1; + ret = + setsockopt(c_socketfd[i], SOL_SOCKET, SO_REUSEADDR, + (void *) &optval, sizeof(optval)); + if (ret == -1) + { + printf("Couldn't setsockopt(SO_REUSEADDR)\n"); + break; + } + } + + for (i = 0; i < fdNumber; i++) + { + g_src.sin_port = htons(srcPort + i); + errbind[i] = + _BIND(c_socketfd[i], (struct sockaddr *) &g_src, sizeof(g_src)); + if (errbind[i] < 0) + { + printf("client %d bind Failed %d\n", i, errno); + _CLOSE(c_socketfd[i]); + c_socketfd[i] = -1; + continue; + } + else + { + printf("client %d bind Success port:%d IP:%s\n", i, + ntohs(g_src.sin_port), + inet_ntoa(*((struct in_addr *) &(g_src.sin_addr.s_addr)))); + } + } + for (i = 0; i < fdNumber; i++) + { + if (errbind[i] >= 0) + { + errconn[i] = + _CONNECT(c_socketfd[i], (struct sockaddr *) &g_dest, + sizeof(g_dest)); + if (errconn[i] < 0) + { + printf("client %d Connect Failed %s\n", i, strerror(errno)); + _CLOSE(c_socketfd[i]); + c_socketfd[i] = -1; + continue; + } + else + { + printf("client %d Connect Success port:%d, IP:%s\n", i, + ntohs(g_dest.sin_port), + inet_ntoa(* + ((struct in_addr *) + &(g_dest.sin_addr.s_addr)))); + } + } + } + + sleep(1); + + clock_gettime(CLOCK_MONOTONIC, &startTime); + clock_gettime(CLOCK_MONOTONIC, &countStart); + + int recvLen2, recvLen; + for (t = 0; t < times; t++) + { + for (i = 0; i < fdNumber; i++) + { + if (c_socketfd[i] < 0) + { + continue; + } + do + { + sendLen = _SEND(c_socketfd[i], send_buf, msg_length, 0); + } + while (sendLen <= 0); + send_count[i]++; + recvLen = 0; + do + { + recvLen2 = + recv(c_socketfd[i], recv_buf + recvLen, + msg_length - recvLen, 0); + if (recvLen2 <= 0) + { + continue; + } + else if (recvLen2 == msg_length - recvLen) + { + recvLen = 0; + break; + } + else if (recvLen2 < msg_length - recvLen) + { + recvLen += recvLen2; + } + } + while (1); + } + + if (0 != sleepTime) + { + if ((t % sleepCnt) == 0) + { + usleep(sleepTime); + } + } + + if ((send_count[0] % unitPrint) == 0 && send_count[0] > 0) + { + clock_gettime(CLOCK_MONOTONIC, &countEnd); + + pps_time = + (countEnd.tv_sec - countStart.tv_sec) * 1000000000 + + countEnd.tv_nsec - countStart.tv_nsec; + pps = ((float) 1000000000 / pps_time) * unitPrint * fdNumber; + if ((flagPrint != 0)) + { + printf(" sendcount %d, time: %ld ns\n", + send_count[0] * fdNumber, pps_time); + } + printf("sendcount %d , pps=%d\n", send_count[0] * fdNumber, pps); + clock_gettime(CLOCK_MONOTONIC, &countStart); + } + } + + clock_gettime(CLOCK_MONOTONIC, &endTime); + + for (i = 0; i < fdNumber; i++) + { + printf("client %d send %d , sendtime :%ld s %ld ns\n", i, + send_count[i], endTime.tv_sec - startTime.tv_sec, + endTime.tv_nsec - startTime.tv_nsec); + } + + for (i = 0; i < fdNumber; i++) + { + printf("client %d close!\n", i); + if (c_socketfd[i] > 0) + _CLOSE(c_socketfd[i]); + } + + pthread_exit(NULL); +} + +void main(int argc, char *argv[]) +{ + socklen_t addrlen = sizeof(struct sockaddr); + int err = 0, result = 0, ret = 0; + int i = 0, j = 0, optval = 0, z = 0, x, listenfd; + cpu_set_t mask; + + setArgsDefault(); + ret = process_arg(argc, argv); + if (ret != 1) + { + printf("The param error\n"); + return; + } + + pthread_t client_thread_id; + + if (pthread_create + (&client_thread_id, NULL, (void *) (&process_client), NULL) == -1) + { + printf("create client thread fail\n"); + return; + } + + printf("create client thread success\n"); + + if (client_thread_id != 0) + { + printf("Client Thread join\n"); + pthread_join(client_thread_id, NULL); + } + + return; +} diff --git a/testcode/app_example/perf-test/multi_tcp_epoll_app_Ser.c b/testcode/app_example/perf-test/multi_tcp_epoll_app_Ser.c new file mode 100644 index 0000000..b37a9c3 --- /dev/null +++ b/testcode/app_example/perf-test/multi_tcp_epoll_app_Ser.c @@ -0,0 +1,627 @@ +/* +* +* 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. +*/ + +#define _GNU_SOURCE +#include <sys/socket.h> +#include <fcntl.h> +#include <memory.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <time.h> +#include <linux/tcp.h> +#include <sched.h> +#include <pthread.h> +#include <arpa/inet.h> +#include <sys/epoll.h> +#include <errno.h> + +#define _BIND bind +#define _LISTEN listen +#define _SOCKET socket +#define _ACCEPT accept +#define _SEND send +#define _RECV recv +#define _CLOSE close +#define _CONNECT connect +#define _PROTOCOL IPPROTO_TCP + +#define MAX_TEST_TIME 1000 +#define MSG_LENGTH 256 +#define CORE_NUM 8 +#define START_CPU_ID 2 +#define MAX_CONN_LIMIT 256 +#define MAX_PORT_NUM 65535 +//1:A-B ;0:A-B-A +#define SEND_RECV_MODE 1 +#define MAX_EVENTS 1000 +#define Default_PortID 12345 +#define Default_SleepCnt 10000 +#define Default_SleepTime 1000000 +#define Flag_Print 1 +#define Fd_Number 1 + +static struct sockaddr_in g_dest; +static struct sockaddr_in g_src; +static struct sockaddr_in g_recv; + +int times = MAX_TEST_TIME; +int msg_length = MSG_LENGTH; +int coreNum = CORE_NUM; +int startCPUId = START_CPU_ID; +int connectNum = MAX_CONN_LIMIT; +int msgMode = SEND_RECV_MODE; +int sleepCnt = Default_SleepCnt; +int sleepTime = Default_SleepTime; //us +int fdNumber = Fd_Number; +int flagPrint = Flag_Print; +int unitPrint = 0; +int waitTime = 0; + +int srcPort = Default_PortID; +int destPort = 0; +int recvPort = 0; +char sendarr[256] = ""; +char recvarr[256] = ""; +char destarr[256] = ""; + +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); + + memset(&g_recv, 0, sizeof(g_recv)); + g_recv.sin_family = AF_INET; + g_recv.sin_addr.s_addr = inet_addr("0.0.0.0"); + g_recv.sin_port = htons(7895); + bzero(&(g_recv.sin_zero), 8); + +} + +static int process_arg(int argc, char *argv[]) +{ + int opt = 0; + int error = 0; + const char *optstring = "p:d:s:a:l:t:e:i:f:r:n:w:u:x:"; + int rw_mark = 0; + + if (argc < 4) + { + printf + ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -l msg_length; \n"); + printf + ("\t-t MAX_TEST_TIME; -i msg_interval ; -f client fd number ; -r receive port; -n connectNum(one server vs n client)\n"); + return 0; + } + while ((opt = getopt(argc, argv, optstring)) != -1) + { + switch (opt) + { + case 'p': + destPort = atoi(optarg); + g_dest.sin_port = htons(atoi(optarg)); + break; + case 'd': + stpcpy(destarr, optarg); + g_dest.sin_addr.s_addr = inet_addr(optarg); + break; + case 's': + stpcpy(sendarr, optarg); + g_src.sin_addr.s_addr = inet_addr(optarg); + g_recv.sin_addr.s_addr = inet_addr(optarg); + break; + case 'a': + //g_src.sin_port = htons(atoi(optarg)); + srcPort = atoi(optarg); + break; + case 'l': + msg_length = atoi(optarg); + break; + case 't': + times = atoi(optarg); + break; + case 'e': + sleepCnt = atoi(optarg); + break; + case 'i': + sleepTime = atoi(optarg); + break; + case 'f': + fdNumber = atoi(optarg); + break; + case 'r': + recvPort = atoi(optarg); + g_recv.sin_port = htons(atoi(optarg)); + break; + case 'n': + connectNum = atoi(optarg); + break; + case 'w': + waitTime = atoi(optarg); + break; + case 'u': + unitPrint = atoi(optarg); + break; + case 'x': + flagPrint = atoi(optarg); + break; + + } + } + return 1; +} + +void process_client(void) +{ + int sendLen = 0; + int i = 0, t = 0, p = 0, optval = 0, ret = 0; + char send_buf[1000] = ""; + int c_socketfd[100] = { 0 }; + int errbind[1000] = { 0 }; + int errconn[1000] = { 0 }; + + int send_count[1000] = { 0 }; + int pps = 0; + long pps_time = 0; + + struct timespec startTime, endTime; + struct timespec countStart; + struct timespec countEnd; + memset(&countStart, 0, sizeof(countStart)); + memset(&countEnd, 0, sizeof(countEnd)); + + for (i = 0; i < fdNumber; i++) + { + c_socketfd[i] = _SOCKET(PF_INET, SOCK_STREAM, _PROTOCOL); + if (0 > c_socketfd[i]) + { + printf("client %d failed,err %d\n", i, errno); + } + else + { + printf("client %d created success\n", i); + } + } + + for (i = 0; i < fdNumber; i++) + { + optval = 1; + ret = + setsockopt(c_socketfd[i], SOL_SOCKET, SO_REUSEADDR, + (void *) &optval, sizeof(optval)); + if (ret == -1) + { + printf("Couldn't setsockopt(SO_REUSEADDR)\n"); + break; + } + } + + for (i = 0; i < fdNumber; i++) + { + g_src.sin_port = htons(srcPort + i); + errbind[i] = + _BIND(c_socketfd[i], (struct sockaddr *) &g_src, sizeof(g_src)); + if (errbind[i] < 0) + { + printf("client %d bind Failed %d\n", i, errno); + _CLOSE(c_socketfd[i]); + c_socketfd[i] = -1; + continue; + } + else + { + printf("client %d bind Success port:%d IP:%s\n", i, + ntohs(g_src.sin_port), + inet_ntoa(*((struct in_addr *) &(g_src.sin_addr.s_addr)))); + } + } + for (i = 0; i < fdNumber; i++) + { + if (errbind[i] >= 0) + { + errconn[i] = + _CONNECT(c_socketfd[i], (struct sockaddr *) &g_dest, + sizeof(g_dest)); + if (errconn[i] < 0) + { + printf("client %d Connect Failed %d\n", i, errno); + _CLOSE(c_socketfd[i]); + c_socketfd[i] = -1; + continue; + } + else + { + printf("client %d Connect Success port:%d, IP:%s\n", i, + ntohs(g_dest.sin_port), + inet_ntoa(* + ((struct in_addr *) + &(g_dest.sin_addr.s_addr)))); + } + } + } + + sleep(1); + + clock_gettime(CLOCK_MONOTONIC, &startTime); + clock_gettime(CLOCK_MONOTONIC, &countStart); + + for (t = 0; t < times; t++) + { + for (i = 0; i < fdNumber; i++) + { + if (c_socketfd[i] < 0) + { + continue; + } + do + { + sendLen = _SEND(c_socketfd[i], send_buf, msg_length, 0); + } + while (sendLen <= 0); + send_count[i]++; + } + + if (0 != sleepTime) + { + if ((t % sleepCnt) == 0) + { + usleep(sleepTime); + } + } + + if ((send_count[0] % unitPrint) == 0) + { + clock_gettime(CLOCK_MONOTONIC, &countEnd); + + pps_time = + (countEnd.tv_sec - countStart.tv_sec) * 1000000000 + + countEnd.tv_nsec - countStart.tv_nsec; + pps = ((float) 1000000000 / pps_time) * unitPrint * fdNumber; + if ((flagPrint != 0)) + { + printf(" sendcount %d, time: %ld ns\n", + send_count[0] * fdNumber, pps_time); + } + printf("sendcount %d , pps=%d\n", send_count[0] * fdNumber, pps); + clock_gettime(CLOCK_MONOTONIC, &countStart); + } + + } + + clock_gettime(CLOCK_MONOTONIC, &endTime); + + for (i = 0; i < fdNumber; i++) + { + printf("client %d send %d , sendtime :%ld s %ld ns\n", i, + send_count[i], endTime.tv_sec - startTime.tv_sec, + endTime.tv_nsec - startTime.tv_nsec); + } + + for (i = 0; i < fdNumber; i++) + { + printf("client %d close!\n", i); + if (c_socketfd[i] > 0) + _CLOSE(c_socketfd[i]); + } + + pthread_exit(NULL); +} + +/* + using this thread to do recv msg; +*/ +void *process_server_msg_thread(void *pArgv) +{ + int recvLen = 0, recvLen2 = 0; + char send_buf[1000]; + char recv_buf[1000]; + int recv_count = 0; + long recv_ppstime = 0; + int recv_pps = 0; + int ret; + struct epoll_event event; + + struct epoll_event eventList[MAX_EVENTS]; + + struct timespec recvStart; + struct timespec recvEnd; + memset(&recvStart, 0, sizeof(recvStart)); + memset(&recvEnd, 0, sizeof(recvEnd)); + + pthread_detach(pthread_self()); + + int msgEpFd = epoll_create(100); + int msgFd = *(int *) pArgv; + + event.events = EPOLLIN | EPOLLET; + event.data.fd = msgFd; + if (epoll_ctl(msgEpFd, EPOLL_CTL_ADD, msgFd, &event) < 0) + { + printf("epoll add fd[%d] to msgEpfd:[%d] failed\n", msgFd, msgEpFd); + close(msgEpFd); + close(msgFd); + return NULL; + } + + clock_gettime(CLOCK_MONOTONIC, &recvStart); + while (1) + { + int timeout = -1; + int m; + int sock; + ret = epoll_wait(msgEpFd, eventList, MAX_EVENTS, timeout); + if (ret == 0) + continue; + + for (m = 0; m < ret; m++) + { + if ((eventList[m].events & EPOLLERR) + || (eventList[m].events & EPOLLHUP) + || !(eventList[m].events & EPOLLIN)) + { + printf("fd %d epoll error event:%d\n", eventList[m].data.fd, + eventList[m].events); + close(eventList[m].data.fd); + continue; + } + else + { + recvLen = 0; + recvLen2 = 0; + sock = eventList[m].data.fd; + + do + { + recvLen2 = + recv(sock, recv_buf + recvLen, msg_length - recvLen, + 0); + if (recvLen2 <= 0) + { + break; + } + else if (recvLen2 == msg_length - recvLen) + { + recvLen = 0; + recv_count++; + if (msg_length != send(sock, send_buf, msg_length, 0)) + { + printf("send failed!====, need exit\n"); + } + } + else if (recvLen2 < msg_length - recvLen) + { + recvLen += recvLen2; + } + if ((flagPrint != 0) && ((recv_count % unitPrint) == 0)) + { + clock_gettime(CLOCK_MONOTONIC, &recvEnd); + recv_ppstime = + (recvEnd.tv_sec - recvStart.tv_sec) * 1000000000 + + recvEnd.tv_nsec - recvStart.tv_nsec; + recv_pps = + ((float) 1000000000 / recv_ppstime) * unitPrint; + printf("receive count:%d, receive time: %ld ns\n", + recv_count, recv_ppstime); + printf("receive pps = %d\n", recv_pps); + clock_gettime(CLOCK_MONOTONIC, &recvStart); + } + } + while (1); + } + + } + + if (recv_count == times) + { + break; + } + } + close(msgFd); + close(msgEpFd); +} + +/* + using this thread to do accept connect +*/ +void *process_server_accept_thread(void *pArgv) +{ + int listenFd = 0; + int x, optval, ret = 0; + int acpt_socketfd[1000] = { 0 }; + + listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (0 > listenFd) + { + printf("ERROR:socket failed,errno [%d]\n", errno); + return NULL; + } + else + { + printf("INFO:Create listen socket Success, listenFd[%d]\n", listenFd); + } + + if (0 > fcntl(listenFd, F_SETFL, O_NONBLOCK)) + { + printf("ERROR:fcntl failed. fd[%d], errno[%d]/n", listenFd, errno); + close(listenFd); + } + + optval = 1; + ret = + setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, + sizeof(optval)); + if (ret == -1) + { + printf("ERROR:setsockopt failed. fd[%d], errno[%d]\n", listenFd, + errno); + close(listenFd); + return NULL; + } + + if (0 != + bind(listenFd, (struct sockaddr *) &g_recv, sizeof(struct sockaddr))) + { + printf("ERROR:bind failed. fd[%d] errno [%d]\n", listenFd, errno); + printf("INFO:Bind Failed, port %d IP:%s\n", ntohs(g_recv.sin_port), + inet_ntoa(*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); + close(listenFd); + //return NULL; + exit(-1); + } + else + { + printf("INFO:Bind Success, port %d IP:%s\n", ntohs(g_recv.sin_port), + inet_ntoa(*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); + } + + if (0 != listen(listenFd, 100)) + { + printf("server socket listen failed. err %d\n", errno); + close(listenFd); + return NULL; + } + printf("Listen Success\n"); + + int accEpFd; + struct epoll_event eventList[100]; + accEpFd = epoll_create(100); + struct epoll_event event; + event.events = EPOLLIN | EPOLLET; + event.data.fd = listenFd; + + if (epoll_ctl(accEpFd, EPOLL_CTL_ADD, listenFd, &event) < 0) + { + printf("epoll_ctl add [%d] to epfd:%d failed\n", listenFd, accEpFd); + exit(-1); + } + + int timeout = -1; + int accpedNum = 0; + while (accpedNum < connectNum) + { + ret = epoll_wait(accEpFd, eventList, connectNum, timeout); + + if (ret < 0) + { + printf("accept_thread epoll_wait error, epfd[%d], errno[%d]\n", + accEpFd, errno); + continue; + } + else if (ret == 0) + continue; + + /*loop done ever Event */ + for (x = 0; x < ret; x++) + { + printf("event:%d; ret:%d\n", eventList[x].events, ret); + if ((eventList[x].events & EPOLLERR) + || !(eventList[x].events & EPOLLIN)) + { + printf("epoll fd %d error\n", eventList[x].data.fd); + close(eventList[x].data.fd); + continue; + } + + while (1) + { + acpt_socketfd[accpedNum] = + accept4(listenFd, NULL, NULL, SOCK_NONBLOCK); + if (acpt_socketfd[accpedNum] < 0) + { + printf("no more connect\n"); + break; + } + /*add new accptFd to MsgEpFD */ + pthread_t ser_rcv_thread_id; + if (pthread_create + (&ser_rcv_thread_id, NULL, process_server_msg_thread, + (void *) &acpt_socketfd[accpedNum]) == -1) + { + printf("create process_server_msg_thread fail\n"); + break; + } + + printf("accept cnt [%d], cur accept fd [%d]\n", accpedNum, + acpt_socketfd[accpedNum]); + accpedNum++; + } + } + } + + close(listenFd); + close(accEpFd); + + while (1) + { + sleep(10); + } + + pthread_exit(NULL); +} + +void main(int argc, char *argv[]) +{ + socklen_t addrlen = sizeof(struct sockaddr); + int err = 0, result = 0, ret = 0; + int i = 0, j = 0, optval = 0, z = 0, x, listenfd; + cpu_set_t mask; + + setArgsDefault(); + ret = process_arg(argc, argv); + if (ret != 1) + { + printf("The param error\n"); + return; + } + + pthread_t server_thread_id; + + if (pthread_create + (&server_thread_id, NULL, process_server_accept_thread, NULL) == -1) + { + printf("create process_server_accept_thread fail\n"); + return; + } + + printf("create process_server_accept_thread success\n"); + + if (server_thread_id != 0) + { + printf("Server Thread join\n"); + pthread_join(server_thread_id, NULL); + } + + while (1) + { + sleep(10); + } + + return; +} diff --git a/testcode/app_example/perf-test/multi_tcp_select_app_Ser.c b/testcode/app_example/perf-test/multi_tcp_select_app_Ser.c new file mode 100644 index 0000000..56b9c5d --- /dev/null +++ b/testcode/app_example/perf-test/multi_tcp_select_app_Ser.c @@ -0,0 +1,431 @@ +/* +* +* 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. +*/ + +#define _GNU_SOURCE +#include <sys/socket.h> +#include <fcntl.h> +#include <memory.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <time.h> +#include <linux/tcp.h> +#include <sched.h> +#include <pthread.h> +#include <arpa/inet.h> +#include <sys/epoll.h> +#include <errno.h> + +#define _BIND bind +#define _LISTEN listen +#define _SOCKET socket +#define _ACCEPT accept +#define _SEND send +#define _RECV recv +#define _CLOSE close +#define _CONNECT connect +#define _PROTOCOL IPPROTO_TCP + +#define MAX_TEST_TIME 1000 +#define MSG_LENGTH 256 +#define CORE_NUM 8 +#define START_CPU_ID 2 +#define MAX_CONN_LIMIT 256 +#define MAX_PORT_NUM 65535 +//1:A-B ;0:A-B-A +#define SEND_RECV_MODE 1 +#define MAX_EVENTS 1000 +#define Default_PortID 12345 +#define Default_SleepCnt 10000 +#define Default_SleepTime 1000000 +#define Flag_Print 1 +#define Fd_Number 1 + +static struct sockaddr_in g_dest; +static struct sockaddr_in g_src; +static struct sockaddr_in g_recv; + +int times = MAX_TEST_TIME; +int msg_length = MSG_LENGTH; +int coreNum = CORE_NUM; +int startCPUId = START_CPU_ID; +int connectNum = MAX_CONN_LIMIT; +int msgMode = SEND_RECV_MODE; +int sleepCnt = Default_SleepCnt; +int sleepTime = Default_SleepTime; //us +int fdNumber = Fd_Number; +int flagPrint = Flag_Print; +int unitPrint = 0; +int waitTime = 0; + +int srcPort = Default_PortID; +int destPort = 0; +int recvPort = 0; +char sendarr[256] = ""; +char recvarr[256] = ""; +char destarr[256] = ""; + +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); + + memset(&g_recv, 0, sizeof(g_recv)); + g_recv.sin_family = AF_INET; + g_recv.sin_addr.s_addr = inet_addr("0.0.0.0"); + g_recv.sin_port = htons(7895); + bzero(&(g_recv.sin_zero), 8); + +} + +static int process_arg(int argc, char *argv[]) +{ + int opt = 0; + int error = 0; + const char *optstring = "p:d:s:a:l:t:e:i:f:r:n:w:u:x:"; + int rw_mark = 0; + + if (argc < 4) + { + printf + ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -l msg_length; \n"); + printf + ("\t-t MAX_TEST_TIME; -i msg_interval ; -f client fd number ; -r receive port; -n connectNum(one server vs n client)\n"); + return 0; + } + while ((opt = getopt(argc, argv, optstring)) != -1) + { + switch (opt) + { + case 'p': + destPort = atoi(optarg); + g_dest.sin_port = htons(atoi(optarg)); + break; + case 'd': + stpcpy(destarr, optarg); + g_dest.sin_addr.s_addr = inet_addr(optarg); + break; + case 's': + stpcpy(sendarr, optarg); + g_src.sin_addr.s_addr = inet_addr(optarg); + g_recv.sin_addr.s_addr = inet_addr(optarg); + break; + case 'a': + //g_src.sin_port = htons(atoi(optarg)); + srcPort = atoi(optarg); + break; + case 'l': + msg_length = atoi(optarg); + break; + case 't': + times = atoi(optarg); + break; + case 'e': + sleepCnt = atoi(optarg); + break; + case 'i': + sleepTime = atoi(optarg); + break; + case 'f': + fdNumber = atoi(optarg); + break; + case 'r': + recvPort = atoi(optarg); + g_recv.sin_port = htons(atoi(optarg)); + break; + case 'n': + connectNum = atoi(optarg); + break; + case 'w': + waitTime = atoi(optarg); + break; + case 'u': + unitPrint = atoi(optarg); + break; + case 'x': + flagPrint = atoi(optarg); + break; + + } + } + return 1; +} + +/* + using this thread to do recv msg; +*/ +void *process_server_msg_thread(void *pArgv) +{ + int recvLen = 0, recvLen2 = 0; + char send_buf[1000]; + char recv_buf[1000]; + int recv_count = 0; + long recv_ppstime = 0; + int recv_pps = 0; + int ret; + struct timeval timeout; + fd_set rfds; + int maxfd; + + struct timespec recvStart; + struct timespec recvEnd; + memset(&recvStart, 0, sizeof(recvStart)); + memset(&recvEnd, 0, sizeof(recvEnd)); + + pthread_detach(pthread_self()); + + int msgFd = *(int *) pArgv; + + clock_gettime(CLOCK_MONOTONIC, &recvStart); + while (1) + { + FD_ZERO(&rfds); + FD_SET(msgFd, &rfds); + maxfd = msgFd + 1; + timeout.tv_sec = 10; + timeout.tv_usec = 0; + ret = select(maxfd, &rfds, NULL, NULL, &timeout); + + if (ret <= 0) + { + continue; + } + + if (FD_ISSET(msgFd, &rfds) == 0) + { + continue; + } + + recvLen = 0; + recvLen2 = 0; + + do + { + recvLen2 = + recv(msgFd, recv_buf + recvLen, msg_length - recvLen, 0); + if (recvLen2 <= 0) + { + break; + } + else if (recvLen2 == msg_length - recvLen) + { + recvLen = 0; + recv_count++; + if (msg_length != send(msgFd, send_buf, msg_length, 0)) + { + printf("send failed!====, need exit\n"); + } + } + else if (recvLen2 < msg_length - recvLen) + { + recvLen += recvLen2; + } + if ((flagPrint != 0) && ((recv_count % unitPrint) == 0)) + { + clock_gettime(CLOCK_MONOTONIC, &recvEnd); + recv_ppstime = + (recvEnd.tv_sec - recvStart.tv_sec) * 1000000000 + + recvEnd.tv_nsec - recvStart.tv_nsec; + recv_pps = ((float) 1000000000 / recv_ppstime) * unitPrint; + printf("receive count:%d, receive time: %ld ns\n", + recv_count, recv_ppstime); + printf("receive pps = %d\n", recv_pps); + clock_gettime(CLOCK_MONOTONIC, &recvStart); + } + } + while (1); + + if (recv_count == times) + { + break; + } + } + close(msgFd); +} + +/* + using this thread to do accept connect +*/ +void *process_server_accept_thread(void *pArgv) +{ + int listenFd = 0; + int x, optval, ret, m = 0; + int acpt_socketfd[1000] = { 0 }; + struct timeval timeout; + fd_set rfds; + int maxfd; + + listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (0 > listenFd) + { + printf("ERROR:socket failed,errno [%d]\n", errno); + return NULL; + } + else + { + printf("INFO:Create listen socket Success, listenFd[%d]\n", listenFd); + } + + if (0 > fcntl(listenFd, F_SETFL, O_NONBLOCK)) + { + printf("ERROR:fcntl failed. fd[%d], errno[%d]/n", listenFd, errno); + close(listenFd); + } + + optval = 1; + ret = + setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, + sizeof(optval)); + if (ret == -1) + { + printf("ERROR:setsockopt failed. fd[%d], errno[%d]\n", listenFd, + errno); + close(listenFd); + return NULL; + } + + if (0 != + bind(listenFd, (struct sockaddr *) &g_recv, sizeof(struct sockaddr))) + { + printf("ERROR:bind failed. fd[%d] errno [%d]\n", listenFd, errno); + printf("INFO:Bind Failed, port %d IP:%s\n", ntohs(g_recv.sin_port), + inet_ntoa(*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); + close(listenFd); + //return NULL; + exit(-1); + } + else + { + printf("INFO:Bind Success, port %d IP:%s\n", ntohs(g_recv.sin_port), + inet_ntoa(*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); + } + + if (0 != listen(listenFd, 100)) + { + printf("server socket listen failed. err %d\n", errno); + close(listenFd); + return NULL; + } + printf("Listen Success\n"); + + int accpedNum = 0; + while (accpedNum < connectNum) + { + FD_ZERO(&rfds); + FD_SET(listenFd, &rfds); + maxfd = listenFd + 1; + timeout.tv_sec = 10; + timeout.tv_usec = 0; + ret = select(maxfd, &rfds, NULL, NULL, &timeout); + + if (ret <= 0) + { + continue; + } + + if (FD_ISSET(listenFd, &rfds) == 0) + { + continue; + } + + while (1) + { + acpt_socketfd[accpedNum] = + accept4(listenFd, NULL, NULL, SOCK_NONBLOCK); + if (acpt_socketfd[accpedNum] < 0) + { + printf("no more connect\n"); + break; + } + /*add new accptFd to MsgEpFD */ + pthread_t ser_rcv_thread_id; + if (pthread_create + (&ser_rcv_thread_id, NULL, process_server_msg_thread, + (void *) &acpt_socketfd[accpedNum]) == -1) + { + printf("create process_server_msg_thread fail\n"); + break; + } + + printf("accept cnt [%d], cur accept fd [%d]\n", accpedNum, + acpt_socketfd[accpedNum]); + accpedNum++; + } + } + + close(listenFd); + + while (1) + { + sleep(10); + } + + pthread_exit(NULL); +} + +void main(int argc, char *argv[]) +{ + socklen_t addrlen = sizeof(struct sockaddr); + int err = 0, result = 0, ret = 0; + int i = 0, j = 0, optval = 0, z = 0, x, listenfd; + cpu_set_t mask; + + setArgsDefault(); + ret = process_arg(argc, argv); + if (ret != 1) + { + printf("The param error\n"); + return; + } + + pthread_t server_thread_id; + + if (pthread_create + (&server_thread_id, NULL, process_server_accept_thread, NULL) == -1) + { + printf("create process_server_accept_thread fail\n"); + return; + } + + printf("create process_server_accept_thread success\n"); + + if (server_thread_id != 0) + { + printf("Server Thread join\n"); + pthread_join(server_thread_id, NULL); + } + + while (1) + { + sleep(10); + } + + return; +} diff --git a/testcode/app_example/rd_config.json b/testcode/app_example/rd_config.json new file mode 100644 index 0000000..26abef6 --- /dev/null +++ b/testcode/app_example/rd_config.json @@ -0,0 +1,14 @@ +{ + "modules": [ + { + "name": "kernel", + "ip_route": [ + "127.0.0.1/24" + ], + "type_route": [ + ], + "protocol_route": [ + ] + } + ] +} |