diff options
author | Stefan Zabka <zabkaste@hu-berlin.de> | 2020-06-10 17:11:44 +0200 |
---|---|---|
committer | Stefan Zabka <zabkaste@hu-berlin.de> | 2020-06-10 17:11:44 +0200 |
commit | 5598f8300b9d3e7b49a4d3e65d1d837616b8beb5 (patch) | |
tree | 84fe96600f41f7d9a7b806edf8f27a3fbb82da4e /03_exercise/srv/server.c | |
parent | 47aaae2c42d554963fb811b68fdf28c9743598e8 (diff) | |
parent | d80bb89ceaee252cff304c3f7dcb160d3bee8fde (diff) | |
download | betriebssysteme-5598f8300b9d3e7b49a4d3e65d1d837616b8beb5.tar.gz betriebssysteme-5598f8300b9d3e7b49a4d3e65d1d837616b8beb5.zip |
Merge branch 'master' into threadpool
Diffstat (limited to '03_exercise/srv/server.c')
-rw-r--r-- | 03_exercise/srv/server.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c new file mode 100644 index 0000000..67fe21c --- /dev/null +++ b/03_exercise/srv/server.c @@ -0,0 +1,89 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include <unistd.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#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 + +static inline void die(const char *msg) { + perror(msg); + exit(-1); +} + +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; + + srv_addr.sin_family = AF_INET; + srv_addr.sin_port = htons(PORT); + srv_addr.sin_addr.s_addr = INADDR_ANY; + + if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + die("Could not open socket"); + + setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &sockopt, sizeof(sockopt)); + + if (bind(sfd, (struct sockaddr *) &srv_addr, sad_sz) < 0) + die("Could not bind socket"); + + if (listen(sfd, 1) < 0) + die("Could not listen on socket"); + + 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(sfd); + + return 0; +} |