#include #include #include #include #include #include #include #include #include #include #include #define BUFFERLEN 255 #define SERV_TCP_PORT 9000 #define UNKNOWN_COMMAND "UNKNOWN COMMAND\n" int panic(char *where) { fprintf(stderr, "error at %s '%s'\n", where, strerror(errno)); exit(127); } /* liest zeilenweise aus dem Socketdeskriptor sd und schreibt die Zeile in das char-Array buf. buflen gibt die Laenge von buf an. Rueckgabewert ist die Anzahl der gelesen Zeichen */ int readline(int sd, char *buf, int buflen) { int n, rc; char c; for (n = 1; n < buflen; n++) { if ((rc = read(sd, &c, 1)) == 1) { *buf++ = c; if (c == '\n') break; } else if (rc == 0) { if (n == 1) return 0; else break; } else return -1; } *buf = 0; return n; } void write_safe(int fd, const void *buf, size_t nbytes) { if (write(fd, buf, nbytes) < 0) panic("write()"); } void process_requests(int fd, struct sockaddr_in *client_addr) { char buf[BUFFERLEN]; char answer[BUFFERLEN]; int arg_1, arg_2; for(;;) { bzero((void *) buf, BUFFERLEN); bzero((void *) answer, BUFFERLEN); if (readline(fd, buf, BUFFERLEN) < 0) panic("readline()"); if (sscanf(buf, "ADD %i %i", &arg_1, &arg_2) == 2) { sprintf(answer, "RESULT %i\n", arg_1 + arg_2); write_safe(fd, answer, strlen(answer)); } else if (sscanf(buf, "MUL %i %i", &arg_1, &arg_2) == 2) { sprintf(answer, "RESULT %i\n", arg_1 * arg_2); write_safe(fd, answer, strlen(answer)); } else if (strncmp("INFO", buf, 4) == 0) { sprintf(answer, "YOURIP %s\n", inet_ntoa(client_addr->sin_addr)); write_safe(fd, answer, strlen(answer)); } else if (strncmp("QUIT", buf, 4) == 0) { close(fd); break; } else write_safe(fd, UNKNOWN_COMMAND, strlen(UNKNOWN_COMMAND)); } } int main(int argc, char argv[]) { int sock_fd, client_fd, addr_len; struct sockaddr_in client_addr, server_addr; if ((sock_fd = socket(AF_INET,SOCK_STREAM,0)) < 0) panic("socket()"); bzero((void *) &server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERV_TCP_PORT); server_addr.sin_addr.s_addr =INADDR_ANY; if (bind(sock_fd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)) < 0) panic("bind()"); if (listen(sock_fd, SOMAXCONN) < 0) panic("listen()"); for(;;) { addr_len = sizeof(struct sockaddr_in); client_fd = accept(sock_fd, (struct sockaddr *) &client_addr, &addr_len); if (client_fd < 0) panic("accept()"); process_requests(client_fd, &client_addr); } close(sock_fd); /* close listening socket */ return 0; }