#include #include #include #include #include #include #include #include std::unordered_map key_value_database; int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } int serv = socket(AF_INET, SOCK_STREAM, 0); const int one = 1; setsockopt(serv, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); sockaddr_in sa = {}; sa.sin_family = AF_INET; sa.sin_port = htons(atoi(argv[1])); if (bind(serv, (sockaddr *)&sa, sizeof(sa))) { perror("bind failed"); return 1; } listen(serv, 1); while (1) { sockaddr_in ca; socklen_t l = sizeof(ca); int cli = accept(serv, (sockaddr *)&ca, &l); char clientName[NI_MAXHOST], clientPort[NI_MAXSERV]; getnameinfo((sockaddr *)&ca, l, clientName, NI_MAXHOST, clientPort, NI_MAXSERV, 0); printf("New client [%s:%s]\n", clientName, clientPort); while (1) { char request[1025]{}; int count = read(cli, request, 1024); if (count <= 0) break; if (request[count - 1] == '\n') request[count - 1] = '\0'; if (!strlen(request)) continue; char *firstSpace = strchr(request, ' '); if (firstSpace != nullptr) { *firstSpace = '\0'; char *key = request; char *value = firstSpace + 1; key_value_database[key] = value; printf("[%s:%s] assigned to '%s' value '%s'\n", clientName, clientPort, key, value); } else { char *key = request; std::string value; if (key_value_database.count(key)) value = key_value_database[key]; else value = "(null)"; std::string response = std::string("[") + key + "] " + value + "\n"; write(cli, response.data(), response.length()); printf("[%s:%s] read from '%s' value '%s'\n", clientName, clientPort, key, value.data()); } } printf("Client [%s:%s] gone\n", clientName, clientPort); shutdown(cli, SHUT_RDWR); close(cli); } }