From de5c17ba61176572e189ad41e58ff046f49e0360 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogawa Date: Sat, 12 Apr 2014 07:31:58 +0900 Subject: [PATCH 1/3] Save temporary status that client can read some lines and make child process to read data from input --- client.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++---- clt_writer.c | 124 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 255 insertions(+), 11 deletions(-) create mode 100644 clt_writer.c diff --git a/client.c b/client.c index 01eb0177cdd02f..f1dac5b0695d18 100644 --- a/client.c +++ b/client.c @@ -19,10 +19,83 @@ static void bcopy(void *dest, void *source, int length) static void sleep(int seconds) { -return; Sleep(seconds * 1000); } +#if WIN32 +int win_start_process(const char* exename, int exestdin, int exestdout, int exestderr) +{ + int result; + STARTUPINFO si; + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + { + struct { + int fd; + HANDLE fall_back_hdl; + HANDLE *si_hdl; + } ioe[] = { + { + exestdin, + GetStdHandle(STD_INPUT_HANDLE), + &si.hStdInput + }, + { + exestdout, + GetStdHandle(STD_OUTPUT_HANDLE), + &si.hStdOutput + }, + { + exestderr, + GetStdHandle(STD_ERROR_HANDLE), + &si.hStdError + }, + + }; + int i; + for (i = 0; i < sizeof(ioe) / sizeof(ioe[0]); i++) { + if (ioe[i].fd < 0) { + *ioe[i].si_hdl = ioe[i].fall_back_hdl; + } + else { + HANDLE hdl; + hdl = (HANDLE)_get_osfhandle(ioe[i].fd); + if (hdl != INVALID_HANDLE_VALUE) { + *ioe[i].si_hdl = hdl; + } + else { + *ioe[i].si_hdl = ioe[i].fall_back_hdl; + } + } + } + } + + { + PROCESS_INFORMATION pi; + BOOL state; + state = CreateProcess(exename, NULL, NULL, NULL, TRUE, 0, + NULL, + NULL, + &si, + &pi); + + result = state ? 0 : -1; + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + + return result; +} +int read_all_from_socket_with_process(int sockfd) +{ + int result; + result = win_start_process("svr_reader.exe", sockfd, -1, -1); + return result; +} + + +#endif #include static int mingw_socket(int domain, int type, int protocol) { @@ -190,17 +263,68 @@ void error(const char *msg) } +int read_all_from_socket_in_process(int sockfd) +{ +#define BUFFER_SIZE 256 + char buffer[BUFFER_SIZE]; + int n; + int result; + result = 0; + do { + bzero(buffer, sizeof(buffer)); + n = read(sockfd,buffer,sizeof(buffer) - 1); + if (n == 0) { + break; + } + else if (n < 0) + { + error("Error reading from socket"); + result = -1; + } + else { + fputs(buffer, stdout); + fflush(stdout); + } + } while (1); + return result; +} +int read_all_from_socket(int sockfd, int in_proc) +{ + int result; + if (in_proc) + { + result = read_all_from_socket_in_process(sockfd); + } + else + { + result = read_all_from_socket_with_process(sockfd); + } + return result; +} + int main(int argc, char *argv[]) { - int sockfd, portno, n; + int sockfd, portno; struct sockaddr_in serv_addr; struct hostent *server; - - char buffer[256]; + int in_proc; + in_proc = 1; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } + { + int i; + for (i = 0; i < argc; i++) + { + if (strcmp(argv[i], "-p") == 0) + { + in_proc = 0; + } + } + } + + #ifdef WIN32 WSADATA wsa; if (WSAStartup(MAKEWORD(2,2), &wsa)) error("WSAStartup"); @@ -221,16 +345,12 @@ int main(int argc, char *argv[]) serv_addr.sin_port = htons(portno); if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); - printf("Sleeping 1 second\n"); - sleep(1); - bzero(buffer,256); - n = read(sockfd,buffer,255); - if (n < 0) - error("ERROR reading from socket"); - printf("%s\n",buffer); + read_all_from_socket(sockfd, in_proc); close(sockfd); #ifdef WIN32 WSACleanup(); #endif return 0; } + + diff --git a/clt_writer.c b/clt_writer.c new file mode 100644 index 00000000000000..f8d9a10dcf9c8e --- /dev/null +++ b/clt_writer.c @@ -0,0 +1,124 @@ +#include +#include +#include + +#include +#if WIN32 +#include +#endif +int write_all(int max_line) +{ + int i; + int result; + char buffer[256]; + result = 0; + for (i = 0; i < max_line; i++) + { + int write_size; + size_t n; + memset(buffer, 0, 256); + write_size = sprintf(buffer, "% 4d I got the connection\n",i); + n = fwrite(buffer, 1, write_size, stdout); + if (n < write_size) + { + fputs("ERROR writing to socket\n", stderr); + result = -1; + break; + } + } + + return result; +} + + +#if WIN32 +int write_handle_info(int fd) +{ + HANDLE osh; + int result; + osh = (HANDLE)_get_osfhandle(fd); + if (osh != INVALID_HANDLE_VALUE) + { + BOOL bState; + DWORD dwFlags; + + bState = GetHandleInformation(osh, &dwFlags); + if (bState) + { + const char* flag_inherit; + const char* protect_from_close; + if (dwFlags & HANDLE_FLAG_INHERIT) + { + flag_inherit = "Yes"; + } + else + { + flag_inherit = "No"; + } + if (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) + { + protect_from_close = "Yes"; + } + else + { + protect_from_close = "No"; + } + printf("file descripter(%d): \n" + "Handle Inherit: %s\n" + "Protect from close: %s\n", + fd, flag_inherit, protect_from_close); + result = 0; + } + else + { + result = -1; + } + } + else + { + result = -1; + } + return result; +} +#else +int write_handle_info(int fd) +{ + return 0; +} + +#endif + +int write_file_status(FILE *f) +{ + int fd; + int result; +#if WIN32 + fd = _fileno(f); +#else + fd = fileno(f); +#endif + if (fd != -1) + { + result = write_handle_info(fd); + } + else + { + result = -1; + } + return result; +} + +int main(int argc, char *argv[]) +{ + int result; + int count_of_line; + if (argc < 2) { + count_of_line = 10; + } else { + count_of_line = atoi(argv[1]); + } + result = write_file_status(stdout); + result = write_all(count_of_line); + return result; +} + From f42dcc284eb5c38864d4976a927f2d39e32c9b6f Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogawa Date: Sat, 12 Apr 2014 17:54:41 +0900 Subject: [PATCH 2/3] printing handle information for stdout --- server.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 177 insertions(+), 5 deletions(-) diff --git a/server.c b/server.c index 8b6d52d3fac6f0..1ca412284f7ccd 100644 --- a/server.c +++ b/server.c @@ -93,22 +93,196 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz) error("unable to make a socket file descriptor: %s", strerror(err)); } + if (s2) + { + BOOL bState; + DWORD dwFlags; + + bState = GetHandleInformation((HANDLE)s2, &dwFlags); + if (bState) + { + const char* flag_inherit; + const char* protect_from_close; + if (dwFlags & HANDLE_FLAG_INHERIT) + { + flag_inherit = "Yes"; + } + else + { + flag_inherit = "No"; + } + if (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) + { + protect_from_close = "Yes"; + } + else + { + protect_from_close = "No"; + } + printf("accept socket handle info: \n" + "Handle Inherit: %s\n" + "Protect from close: %s\n", flag_inherit, protect_from_close); + } + } return sockfd2; } #define accept mingw_accept +int win_start_process(const char* exename, char * args, int exestdin, int exestdout, int exestderr) +{ + int result; + STARTUPINFO si; + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + { + struct { + int fd; + HANDLE fall_back_hdl; + HANDLE *si_hdl; + } ioe[] = { + { + exestdin, + GetStdHandle(STD_INPUT_HANDLE), + &si.hStdInput + }, + { + exestdout, + GetStdHandle(STD_OUTPUT_HANDLE), + &si.hStdOutput + }, + { + exestderr, + GetStdHandle(STD_ERROR_HANDLE), + &si.hStdError + }, + + }; + int i; + for (i = 0; i < sizeof(ioe) / sizeof(ioe[0]); i++) { + if (ioe[i].fd < 0) { + *ioe[i].si_hdl = ioe[i].fall_back_hdl; + } + else { + HANDLE hdl; + hdl = (HANDLE)_get_osfhandle(ioe[i].fd); + if (hdl != INVALID_HANDLE_VALUE) { + *ioe[i].si_hdl = hdl; + } + else { + *ioe[i].si_hdl = ioe[i].fall_back_hdl; + } + } + } + } + + { + PROCESS_INFORMATION pi; + BOOL state; + state = CreateProcess(exename, args, NULL, NULL, TRUE, 0, + NULL, + NULL, + &si, + &pi); + + result = state ? 0 : -1; + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + + return result; +} #endif +int write_all_to_socket_with_process(int sockfd, int max_line) +{ + char buffer[128]; + int result; + memset(buffer, 0, sizeof(buffer)); + sprintf(buffer, " %d", max_line); + result = win_start_process("clt_writer.exe", buffer, -1, sockfd, -1); + return result; +} + +int write_all_to_socket_in_process(int sockfd, int max_line) +{ + int i; + int result; + char buffer[256]; + result = 0; + for (i = 0; i < max_line; i++) + { + int write_size; + int n; + bzero(buffer,256); + write_size = sprintf(buffer, "% 4d I got the connection\n",i); + n = write(sockfd, buffer, write_size); + if (n < 0) + { + error("ERROR writing to socket"); + result = -1; + break; + } + } + + return result; +} + +int write_all_to_socket(int sockfd, int line_count, int in_process) +{ + int result; + if (in_process) + { + result = write_all_to_socket_in_process(sockfd, line_count); + } + else + { + result = write_all_to_socket_with_process(sockfd, line_count); + } + return result; +} + int main(int argc, char *argv[]) { int sockfd, newsockfd, portno; socklen_t clilen; - char buffer[256]; - struct sockaddr_in serv_addr, cli_addr; + struct sockaddr_in serv_addr, cli_addr; int n; + int line_count; + int in_proc; + line_count = 10; + in_proc = 1; if (argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); exit(1); } + { + int i; + int parse_mode; + const static int PM_NORMAL = 0; + const static int PM_LINE = 1; + const static int PM_PROC = 2; + parse_mode = PM_NORMAL; + for (i = 0; i < argc; i++) + { + if (parse_mode == PM_NORMAL) + { + if (strcmp(argv[i], "-l") == 0) + { + parse_mode = PM_LINE; + } + else if (strcmp(argv[i], "-p") == 0) + { + in_proc = 0; + } + } + else if (parse_mode == PM_LINE) + { + line_count = atoi(argv[i]); + parse_mode = PM_NORMAL; + } + } + } + #ifdef WIN32 WSADATA wsa; if (WSAStartup(MAKEWORD(2,2), &wsa)) error("WSAStartup"); @@ -131,9 +305,7 @@ int main(int argc, char *argv[]) &clilen); if (newsockfd < 0) error("ERROR on accept"); - bzero(buffer,256); - n = write(newsockfd,"I got the connection",20); - if (n < 0) error("ERROR writing to socket"); + write_all_to_socket(newsockfd, line_count, in_proc); close(newsockfd); close(sockfd); #ifdef WIN32 From 0a56ecd385c3a721b43ae6018e9a5494a5ec9a44 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogawa Date: Sat, 12 Apr 2014 18:33:37 +0900 Subject: [PATCH 3/3] You can test client and server under windows os. You can test following case. Case 1. Test connected server-side socket which is passed to a child process. You can do this by running server with '-p' option. ('./server 1337 -p') Case 2. Test connected server-side socket which is used in server process. Case 3. Test socket in which variable length data go through. You can do this by running server with '-l' option. ('./server 1337 -l 256') To create test programs. gcc -o server server.c -lws2_32 gcc -o client client.c -lws2_32 gcc -o clt_writer clt_writer.c To test case 1. ./server 1337 -p & ./client 127.0.0.1 1337 To test case 2. ./server 1337 & ./client 127.0.0.1 1337 To test case 3. ./server 1337 -l 500 & ./client 127.0.0.1 1337 To test case 1 and 3. ./server 1337 -p -l 256 & ./client 127.0.0.1 1337 To test case 2 and 3. ./server 1337 -l 256 & ./client 127.0.0.1 1337 --- client.c | 25 ++--------------- clt_writer.c | 78 ---------------------------------------------------- server.c | 31 --------------------- 3 files changed, 3 insertions(+), 131 deletions(-) diff --git a/client.c b/client.c index f1dac5b0695d18..a9fe4cf6c982b0 100644 --- a/client.c +++ b/client.c @@ -288,17 +288,10 @@ int read_all_from_socket_in_process(int sockfd) } while (1); return result; } -int read_all_from_socket(int sockfd, int in_proc) +int read_all_from_socket(int sockfd) { int result; - if (in_proc) - { - result = read_all_from_socket_in_process(sockfd); - } - else - { - result = read_all_from_socket_with_process(sockfd); - } + result = read_all_from_socket_in_process(sockfd); return result; } @@ -307,22 +300,10 @@ int main(int argc, char *argv[]) int sockfd, portno; struct sockaddr_in serv_addr; struct hostent *server; - int in_proc; - in_proc = 1; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } - { - int i; - for (i = 0; i < argc; i++) - { - if (strcmp(argv[i], "-p") == 0) - { - in_proc = 0; - } - } - } #ifdef WIN32 @@ -345,7 +326,7 @@ int main(int argc, char *argv[]) serv_addr.sin_port = htons(portno); if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); - read_all_from_socket(sockfd, in_proc); + read_all_from_socket(sockfd); close(sockfd); #ifdef WIN32 WSACleanup(); diff --git a/clt_writer.c b/clt_writer.c index f8d9a10dcf9c8e..29998b9cad883b 100644 --- a/clt_writer.c +++ b/clt_writer.c @@ -31,83 +31,6 @@ int write_all(int max_line) } -#if WIN32 -int write_handle_info(int fd) -{ - HANDLE osh; - int result; - osh = (HANDLE)_get_osfhandle(fd); - if (osh != INVALID_HANDLE_VALUE) - { - BOOL bState; - DWORD dwFlags; - - bState = GetHandleInformation(osh, &dwFlags); - if (bState) - { - const char* flag_inherit; - const char* protect_from_close; - if (dwFlags & HANDLE_FLAG_INHERIT) - { - flag_inherit = "Yes"; - } - else - { - flag_inherit = "No"; - } - if (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) - { - protect_from_close = "Yes"; - } - else - { - protect_from_close = "No"; - } - printf("file descripter(%d): \n" - "Handle Inherit: %s\n" - "Protect from close: %s\n", - fd, flag_inherit, protect_from_close); - result = 0; - } - else - { - result = -1; - } - } - else - { - result = -1; - } - return result; -} -#else -int write_handle_info(int fd) -{ - return 0; -} - -#endif - -int write_file_status(FILE *f) -{ - int fd; - int result; -#if WIN32 - fd = _fileno(f); -#else - fd = fileno(f); -#endif - if (fd != -1) - { - result = write_handle_info(fd); - } - else - { - result = -1; - } - return result; -} - int main(int argc, char *argv[]) { int result; @@ -117,7 +40,6 @@ int main(int argc, char *argv[]) } else { count_of_line = atoi(argv[1]); } - result = write_file_status(stdout); result = write_all(count_of_line); return result; } diff --git a/server.c b/server.c index 1ca412284f7ccd..1529af81651e1e 100644 --- a/server.c +++ b/server.c @@ -93,37 +93,6 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz) error("unable to make a socket file descriptor: %s", strerror(err)); } - if (s2) - { - BOOL bState; - DWORD dwFlags; - - bState = GetHandleInformation((HANDLE)s2, &dwFlags); - if (bState) - { - const char* flag_inherit; - const char* protect_from_close; - if (dwFlags & HANDLE_FLAG_INHERIT) - { - flag_inherit = "Yes"; - } - else - { - flag_inherit = "No"; - } - if (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) - { - protect_from_close = "Yes"; - } - else - { - protect_from_close = "No"; - } - printf("accept socket handle info: \n" - "Handle Inherit: %s\n" - "Protect from close: %s\n", flag_inherit, protect_from_close); - } - } return sockfd2; } #define accept mingw_accept