From 7ab92ebb3424e904ee78862683eb65fb60d878f6 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 8 Jun 2020 17:30:18 +0200 Subject: multiple clients --- 03_exercise/.srv_pid | 2 +- 03_exercise/cli/client | Bin 35192 -> 31992 bytes 03_exercise/srv/server.c | 62 +++++++++++++++++++++++++++++++++++------------ 03_exercise/srv/shell.c | 27 ++++----------------- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid index 8dcdde2..156e8ad 100644 --- a/03_exercise/.srv_pid +++ b/03_exercise/.srv_pid @@ -1 +1 @@ -2202992 +341971 diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 4450079..95db5c3 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c index 11f7482..67fe21c 100644 --- a/03_exercise/srv/server.c +++ b/03_exercise/srv/server.c @@ -9,6 +9,18 @@ #include "shell.h" +/* + * READ ME + * What works: + * - remote shell, weitesgehend die funktionalität der vorhergehenden aufgabe (damit auch pipes und background, + * auch wenn wir das nicht ausführlich getestet haben) + * - get und put für dateien + * - mehrere clients an einem server + * Known bugs: + * - das erkennen, wann eine neue prompt geprintet werden muss ist aktuell sehr hacky client-seitig implementiert, + * scheitert teilweise - die eingabe geht trzd ganz normal, es wird nur keine prompt angezeigt + */ + #define PORT 9000 #define BUF_SIZE 256 @@ -19,13 +31,13 @@ static inline void die(const char *msg) { } int main() { + setvbuf(stderr, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + struct sockaddr_in srv_addr, cli_addr; - int sockopt = 1; - socklen_t sad_sz = sizeof(struct sockaddr_in); - int sfd, cfd; - /*ssize_t bytes; - char in_buf[BUF_SIZE]; - char out_buf[BUF_SIZE];*/ + int sockopt = 1; + socklen_t sad_sz = sizeof(struct sockaddr_in); + int sfd; srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(PORT); @@ -42,16 +54,36 @@ int main() { if (listen(sfd, 1) < 0) die("Could not listen on socket"); - cfd = accept(sfd, (struct sockaddr *) &cli_addr, &sad_sz); - if (cfd < 0) - die("Could not accept incoming connection"); - - printf("srv: connected: %s\n", inet_ntoa(cli_addr.sin_addr)); - - int status = shell(cfd); + while (1) { + int cfd, pid; + cfd = accept(sfd, (struct sockaddr *) &cli_addr, &sad_sz); + if (cfd < 0) { + perror("Could not accept incoming connection"); + break; + } + + // fork new process + pid = fork(); + if (pid < 0) { + perror("ERROR in new process creation"); + } + + if (pid == 0) { + // child process + close(sfd); + + printf("srv: connected: %s\n", inet_ntoa(cli_addr.sin_addr)); + int status = shell(cfd); + fprintf(stdout, "srv: client disconnected: %s (%d)\n", inet_ntoa(cli_addr.sin_addr), status); + fflush(stdout); + close(cfd); + } else { + // parent process + close(cfd); + } + } - close(cfd); close(sfd); - return status; + return 0; } diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 686b169..c7155c6 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -13,26 +13,8 @@ #include "array.h" #include "process.h" -#include "prompt_utils.h" #include "builtins.h" -/* - * READ ME - * sorry für den unaufgeräumten Code hier :/ - * - * What works: - * - remote shell, weitesgehend die funktionalität der vorhergehenden aufgabe (damit auch pipes und background, - * auch wenn wir das nicht ausführlich getestet haben) - * - get und put für dateien - * What doesn't work: - * - mehrere clients an einem server - * Known bugs: - * - exit beendet nicht nur die client-server connection und setzt den server wieder in einen wartenden zustand, - * sondern terminiert ebenfalls den server - * - das erkennen, wann eine neue prompt geprintet werden muss ist aktuell sehr hacky client seitig implementiert, - * scheitert teilweise - die eingabe geht trzd ganz normal, es wird nur keine prompt angezeigt - */ - char *get_current_dir_name(void); #define BUF_SIZE 2048 @@ -202,8 +184,8 @@ bool check_put(char *buffer, int sock) { } int shell(int in_fd) { - setvbuf(stderr, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); + int stdoutCopy = dup(STDOUT_FILENO); + int stderrCopy = dup(STDERR_FILENO); dup2(in_fd, STDOUT_FILENO); dup2(in_fd, STDERR_FILENO); @@ -305,8 +287,9 @@ int shell(int in_fd) { free_processes(&processes); } - printf("Disconnecting..."); - printf("\n"); + // reset output + dup2(STDOUT_FILENO, stdoutCopy); + dup2(STDERR_FILENO, stderrCopy); free((void *) original_wd); -- cgit v1.2.3-54-g00ecf