Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <unistd.h>
- #include <map>
- #include <algorithm>
- #include "whatsappio.h"
- #define FAILED "failed"
- #define CLIENT_EXIT "client_exit"
- #define SUCCESS "success"
- using namespace std;
- map<int, string> clients; //sd,name
- map<string, vector<string>> groups; //group: members
- bool createGroup(string basic_string, vector<string> client_list);
- string get_clients()
- {
- string result;
- for (auto x: clients)
- {
- result += x.second + ",";
- }
- if (!result.empty())
- {
- result.pop_back(); //remove last ','
- }
- return result;
- }
- int get_client_socket(string name)
- {
- int result = -1;
- for (auto x: clients)
- {
- if (x.second == name)
- {
- result = x.first;
- }
- }
- return result;
- }
- bool send_to_group(string group_name, string sender_name, string message)
- {
- // client trying to send to group he is not in it.
- if (!(find(groups[group_name].begin(), groups[group_name].end(), sender_name) !=
- groups[group_name].end()))
- {
- return false;
- }
- for (string name : groups[group_name])
- {
- int s = get_client_socket(name);
- if (write(s, message.c_str(), strlen(message.c_str())) < 0)
- {
- return false;
- }
- }
- return true;
- }
- /** server side */
- int server(unsigned short port_num)
- {
- char myname[255] = "";
- struct hostent *hp;
- int server_socket;
- struct sockaddr_in sa;
- fd_set readfds;
- gethostname(myname, 255);
- hp = gethostbyname(myname);
- if (hp == nullptr)
- {
- exit(1);
- }
- cout << inet_ntoa(*((struct in_addr *) hp->h_addr)) << "\n";
- //sockaddrr_in initlization
- memset(&sa, 0, sizeof(struct sockaddr_in));
- sa.sin_family = hp->h_addrtype;
- cout << sa.sin_addr.s_addr << "\n";
- memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
- cout << sa.sin_addr.s_addr << "\n";
- sa.sin_port = htons(port_num);
- //create socket
- if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- perror("socket");
- exit(1);
- }
- if (bind(server_socket, (struct sockaddr *) &sa, sizeof(sa)) < 0)
- {
- close(server_socket);
- perror("bind");
- exit(1);
- }
- if (listen(server_socket, 10) < 0)
- {
- perror("listen");
- exit(1);
- }
- while (true)
- {
- FD_ZERO(&readfds);
- FD_SET(server_socket, &readfds);
- FD_SET(STDIN_FILENO, &readfds);
- int max_fd = server_socket;
- for (auto x : clients)
- {
- FD_SET(x.first, &readfds);
- if (x.first > max_fd)
- {
- max_fd = x.first;
- }
- }
- if (select(max_fd + 1, &readfds, nullptr, nullptr, nullptr) < 0)
- {
- exit(1);
- }
- if (FD_ISSET(server_socket, &readfds))
- { //new client connection
- int new_socket;
- if ((new_socket = accept(server_socket, nullptr, nullptr)) < 0)
- {
- exit(1);
- }
- char new_name[WA_MAX_NAME] = "";
- read(new_socket, new_name, WA_MAX_NAME);
- string new_name_s(new_name);
- int x = get_client_socket(new_name_s);
- if (x != -1)
- { //existing name
- write(new_socket, FAILED, strlen(FAILED));
- }
- else
- {
- write(new_socket, SUCCESS, strlen(SUCCESS));
- cout << new_name_s << " connected.\n";
- clients[new_socket] = new_name_s;
- }
- }
- if (FD_ISSET(STDIN_FILENO, &readfds))
- { // server input
- char buffer[WA_MAX_MESSAGE] = "";
- int b = (int) read(STDIN_FILENO, buffer, WA_MAX_MESSAGE);
- buffer[b - 1] = '\0';
- string string_buffer(buffer);
- if (string_buffer == "EXIT")
- {
- for (auto x: clients)
- {
- write(x.first, CLIENT_EXIT, strlen(CLIENT_EXIT));
- close(x.first);
- clients.erase(x.first);
- }
- print_exit();
- exit(0);
- }
- }
- else
- { //client request
- for (auto x : clients)
- {
- if (FD_ISSET(x.first, &readfds))
- { //check client command
- char buffer[WA_MAX_MESSAGE] = "";
- read(x.first, buffer, WA_MAX_MESSAGE);
- command_type command_t;
- string name;
- string message;
- vector<string> g_clients;
- parse_command(buffer, command_t, name, message, g_clients);
- if (command_t == CREATE_GROUP)
- {
- g_clients.push_back(x.second);
- if (createGroup(name, g_clients))
- {
- write(x.first, SUCCESS, strlen(SUCCESS));
- print_create_group(true, true, x.second, name);
- }
- else
- {
- write(x.first, FAILED, strlen(FAILED));
- print_create_group(true, false, x.second, name);
- }
- }
- else if (command_t == SEND)
- {
- if (groups.count(name))
- { //to group
- bool send_success = send_to_group(name, x.second, x.second + ": " +
- message);
- write(x.first, send_success ? SUCCESS : FAILED, send_success ? strlen
- (SUCCESS) : strlen(FAILED));
- print_send(true, send_success, x.second, name, message);
- }
- else
- { //to client
- int receiver = get_client_socket(name);
- if (receiver == -1 || name == x.second)
- { // does not exist, cant send to myself
- write(x.first, FAILED, strlen(FAILED));
- print_send(true, false, x.second, name, message);
- }
- else
- {
- write(x.first, SUCCESS, strlen(SUCCESS));
- string sent_message = x.second + ": " + message;
- write(receiver, sent_message.c_str(), strlen(sent_message.c_str()));
- print_send(true, true, x.second, name, message);
- }
- }
- }
- else if (command_t == WHO)
- {
- string clients_names = get_clients();
- write(x.first, clients_names.c_str(), strlen(clients_names.c_str()));
- print_who_server(x.second);
- }
- else if (command_t == EXIT)
- {
- print_exit(true, x.second);
- close(x.first);
- clients.erase(x.first);
- }
- }
- }
- }
- }
- }
- bool createGroup(string group_name, vector<string> client_list)
- {
- for (auto c:group_name)
- {
- if (!isalpha(c) && !isdigit(c))
- {
- return false;
- }
- }
- for (auto group :groups)
- {
- if (group.first == group_name)
- {
- return false;
- }
- }
- for (auto client: clients)
- {
- if (client.second == group_name)
- {
- return false;
- }
- }
- sort(client_list.begin(), client_list.end());
- client_list.erase(unique(client_list.begin(), client_list.end()), client_list.end());
- for (auto client : client_list)
- {
- bool found = false;
- for (auto connected_clients : clients)
- {
- if (client == connected_clients.second)
- {
- cout<<client<<" was found"<<endl;
- found = true;
- }
- }
- // user in client list that is not connected to server at all
- if (!found)
- {
- return false;
- }
- }
- if (client_list.size() < 2)
- {
- return false;
- }
- groups[group_name] = client_list;
- return true;
- }
- int main(int argc, char *argv[])
- {
- if (argc != 2)
- {
- print_server_usage();
- return -1;
- }
- server(atoi(argv[1]));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement