Guest User

Untitled

a guest
Aug 19th, 2018
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.59 KB | None | 0 0
  1. #include <iostream> // cout
  2. #include <sstream> // cout
  3. #include <stdlib.h>  // exit
  4. #include <string.h> // bzero
  5. #include <iostream> // cout
  6. #include <sstream> // cout
  7. #include <stdlib.h>  // exit
  8. #include <string.h> // bzero
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <netinet/in.h>
  12. #include <pthread.h>
  13. #include <postgresql/libpq-fe.h>
  14. #include <set>
  15. #include <time.h>
  16. #include <map>
  17.  
  18.  
  19. using namespace std;
  20.  
  21. PGconn *conn;
  22.  
  23. //set<int> clients; // o que e um set e um map. Como se introduz num set e num map?
  24. map<int, string> clientes; // porque tem os 2 maps ? qual e a logica disso?
  25. //map<string, int> mapas1;  // saber ao certo para que servem estas 3 variaveis
  26.  
  27. string getNomeUtilizador(int sockfd){
  28.   string user;
  29.   map<int,string>::iterator it = clientes.begin();
  30.     map<int,string>::iterator ite = clientes.end();
  31.     for(;it!=ite;it++){
  32.       if (it->first == sockfd)
  33.         user = it->second;
  34.     }
  35.     return user;
  36. }
  37. string get_date() {
  38.     time_t seconds = time(NULL);
  39.     struct tm * timeinfo = localtime(&seconds);
  40.     stringstream oss3;
  41.     oss3 << (timeinfo->tm_year + 1900) << "-" << timeinfo->tm_mon + 1 << "-"
  42.             << timeinfo->tm_mday;
  43.  
  44.     return oss3.str();
  45. }
  46.  
  47. string get_time() {
  48.     time_t seconds = time(NULL);
  49.     struct tm * timeinfo = localtime(&seconds);
  50.     ostringstream oss4;
  51.     oss4 << timeinfo->tm_hour << ':' << timeinfo->tm_min << ":"
  52.             << timeinfo->tm_sec;
  53.  
  54.     return oss4.str();
  55. }
  56.  
  57. /* Envia uma string para um socket */
  58. void writeline(int socketfd, string line) {
  59.     string tosend = line + "\n";
  60.     write(socketfd, tosend.c_str(), tosend.length());
  61. }
  62.  
  63. /* Lê uma linha de um socket
  64.  retorna false se o socket se tiver fechado */
  65. bool readline(int socketfd, string &line) {
  66.     int n;
  67.     /* buffer de tamanho 1025 para ter espaço
  68.      para o \0 que indica o fim de string*/
  69.     char buffer[1025];
  70.  
  71.     /* inicializar a string */
  72.     line = "";
  73.  
  74.     /* Enquanto não encontrarmos o fim de linha
  75.      vamos lendo mais dados da stream */
  76.     while (line.find('\n') == string::npos) {
  77.         // leu n carateres. se for zero chegamos ao fim
  78.         int n = read(socketfd, buffer, 1024); // ler do socket
  79.         if (n == 0)
  80.             return false; // nada para ser lido -> socket fechado
  81.         buffer[n] = 0; // colocar o \0 no fim do buffer
  82.         line += buffer; // acrescentar os dados lidos à string
  83.     }
  84.  
  85.     // Retirar o \r\n (lemos uma linha mas não precisamos do \r\n)
  86.     line.erase(line.end() - 1);
  87.     line.erase(line.end() - 1);
  88.     return true;
  89. }
  90.  
  91. bool getSalaUtilizador(int origin, int dest){
  92.     string usero, userd;
  93.     ostringstream oss1, oss2;
  94.     usero = getNomeUtilizador(origin);
  95.     userd = getNomeUtilizador(dest);
  96.     oss1 << "SELECT sala FROM users WHERE nick = '" << usero << "'";
  97.     PGresult *result1 = PQexec(conn, oss1.str().c_str());
  98.     oss2 << "SELECT sala FROM users WHERE nick = '" << userd << "'";
  99.     PGresult *result2 = PQexec(conn, oss2.str().c_str());
  100.     if ((PQresultStatus(result1) != PGRES_TUPLES_OK) || (PQresultStatus(result2) != PGRES_TUPLES_OK)) {
  101.         cout << "Failed to execute query " << endl;
  102.         return false;
  103.     }
  104.     string sala1 = PQgetvalue(result1, 0, 0);
  105.     string sala2 = PQgetvalue(result2, 0, 0);
  106.     cout << sala1 << endl;
  107.     cout << sala2 << endl;
  108.     if (sala1 == sala2)
  109.       return true;
  110.     else
  111.       return false;
  112. }
  113.  
  114. /* Envia uma mensagem para todos os clientes ligados exceto 1 */
  115. void broadcast(int origin, string text) {
  116.     /* Usamos um ostringstream para construir uma string
  117.      Funciona como um cout mas em vez de imprimir no ecrã
  118.      imprime numa string */
  119.     //string user;
  120.     ostringstream oss;
  121.     oss << "(" << get_date() + "|" + get_time() << ")["
  122.              << getNomeUtilizador(origin) << "] "<< " said: " << text;
  123.     map<int,string>::iterator it = clientes.begin();
  124.     map<int,string>::iterator ite = clientes.end();
  125.     if (clientes.size() > 0) {
  126.    
  127.     for (;it != ite; it++)
  128.     {
  129.       if (it->first != origin)
  130.       {
  131.         if (getSalaUtilizador(origin,it->first))
  132.         {
  133.           writeline(it->first, oss.str());
  134.         }
  135.       }
  136.     }
  137. }
  138.  
  139. else
  140. {
  141.   writeline(origin, "Tas sozinho oh burro");
  142. }
  143. }
  144.  
  145. PGconn * ligar_sql() {
  146.     conn = PQconnectdb("host=vdbm.fe.up.pt user=sinf12g81 password=sgvpnu");
  147.     if (PQstatus(conn) == CONNECTION_OK)
  148.         cout << "CONNECTION_OK" << endl;
  149.     //Verifica se há conexão
  150.     if (!conn) {
  151.         cout << "Failed to connect do Database" << endl;
  152.         exit(-1);
  153.     }
  154.     //Verifica se quando há conexão esta está válida, ex: username e password certos
  155.     if (PQstatus(conn) != CONNECTION_OK) {
  156.         cout << "Failed to connect do Database" << endl;
  157.         exit(-1);
  158.     }
  159. }
  160.  
  161. void identify(int sockfd, string line) {
  162.     string comando, nick;
  163.     istringstream iss(line);
  164.     iss >> comando >> nick;
  165.     ostringstream oss1;
  166.     oss1 << "SELECT nick FROM users WHERE nick = '" << nick << "'";
  167.  
  168.     PGresult *result = PQexec(conn, oss1.str().c_str());
  169.  
  170.     if (PQresultStatus(result) != PGRES_TUPLES_OK) {
  171.         cout << "Failed to execute query" << ' ' << PQresultStatus(result)
  172.                 << endl;
  173.         cout << PQerrorMessage(conn) << endl;
  174.         writeline(sockfd, "Erro ao executar o comando. Por favor, digite identify 'nick'.");
  175.         return;
  176.     }
  177.  
  178.     if (PQntuples(result) > 0) {
  179.         writeline(sockfd,
  180.                 "O Utilizador que pretende utilizar ja existe na base de dados. Para poder fazer identify, escolha outro nick.");
  181.         return;
  182.     } else {
  183.         map<int, string>::iterator it = clientes.begin();
  184.         map<int, string>::iterator ite = clientes.end();
  185.         for (;it != ite; it++) {
  186.             if (it->second == nick) {
  187.                 writeline(sockfd,
  188.                         "O nick com o qual se pretende identificar ja esta a ser utilizado. Para poder fazer identify, escolha outro nick.");
  189.                 return;
  190.             } else {
  191.                 for (it = clientes.begin(); it != ite; it++){
  192.                  if (it->first == sockfd)
  193.                   it->second = nick;
  194.                 }
  195.             }
  196.             writeline(sockfd, "Identificacao efectuada com sucesso!");
  197.             return;
  198.         }
  199.     }
  200.     }
  201.    
  202. void registo(int sockfd, string line) {
  203.     string comando, user, pass;
  204.     istringstream iss(line);
  205.     iss >> comando >> user >> pass;
  206.     string regist = "";
  207.  
  208.     ostringstream oss2;
  209.     oss2 << "SELECT nick FROM users WHERE nick = '" << user << "'";
  210.     PGresult *regi = PQexec(conn, oss2.str().c_str());
  211.     if (PQntuples(regi) > 0) {
  212.         writeline(sockfd, "O nick que pretende utilizar ja se encontra registado. Para se registar, escolha outro nick.");
  213.         return;
  214.     } else {
  215.         regist = regist + "INSERT INTO users VALUES ('" + user + "','" + pass
  216.                 + "',' 0 ','" + get_date() + "','" + "sala_default" + "','" + get_time() + "";
  217.         PGresult *reg = PQexec(conn, regist.c_str());
  218.         if (PQresultStatus(reg) != PGRES_COMMAND_OK) {
  219.             cout << "Failed to execute query" << ' ' << PQresultStatus(reg)
  220.                     << endl;
  221.         } else {
  222.             writeline(sockfd, "Registo efectuado com sucesso! Para fazer login, digite login 'nick' 'password'.");
  223.         }
  224.         return;
  225.     }
  226. }
  227.  
  228. void login(int sockfd, string line) {
  229.     string comando, user, pass;
  230.     istringstream iss(line);
  231.     iss >> comando >> user >> pass;
  232.     string regist = "";
  233.     regist = regist + "SELECT nick, password FROM users WHERE nick='" + user
  234.             + "' and password='" + pass + "'";
  235.     PGresult *log = PQexec(conn, regist.c_str());
  236.  
  237.     if (PQresultStatus(log) != PGRES_TUPLES_OK) {
  238.         cout << "Failed to execute query " << PQresultStatus(log) << endl;
  239.         return;
  240.     } else if (PQntuples(log) == 1) {
  241.         string updatedata = "";
  242.         updatedata = updatedata + "UPDATE users set data_ultimo_login = '" + get_date() + "' WHERE nick = '" + user + "'";
  243.         PGresult *log2 = PQexec(conn, updatedata.c_str());
  244.         if (PQresultStatus(log2) != PGRES_COMMAND_OK) {
  245.           cout << "Failed to execute query" << ' ' << PQresultStatus(log2) << endl;
  246.           cout << "data"<< endl;
  247.           return;
  248.         }
  249.         string updatehora = "";
  250.         updatehora = updatehora + "UPDATE users set hora_ultimo_login = '" + get_time() + "' WHERE nick = '" + user + "'";
  251.         PGresult *log3 = PQexec(conn, updatehora.c_str());
  252.         if (PQresultStatus(log3) != PGRES_COMMAND_OK) {
  253.           cout << "Failed to execute query" << ' ' << PQresultStatus(log3) << endl;
  254.           cout << "hora"<< endl;
  255.           return;
  256.         }
  257.         string updatedsala = "";
  258.         updatedsala = updatedsala + "UPDATE users set sala = '" + "sala_default" + "' WHERE nick = '" + user + "'";
  259.         PGresult *log4 = PQexec(conn, updatedsala.c_str());
  260.         if (PQresultStatus(log4) != PGRES_COMMAND_OK) {
  261.           cout << "Failed to execute query" << ' ' << PQresultStatus(log4) << endl;
  262.           cout << "sala"<< endl;
  263.           return;
  264.         }
  265.         writeline(sockfd, "Login efectuado com sucesso! =)");
  266.         clientes[sockfd] = user;
  267.         return;
  268.     } else {
  269.         writeline(sockfd,
  270.                 "Username ou password incorrectos. =( \n Tente novamente.");
  271.         return;
  272.     }
  273. }
  274.  
  275. void criar(int sockfd, string line) {
  276.     string comando, nomesala, user;
  277.     istringstream iss(line);
  278.     iss >> comando >> nomesala;
  279.    
  280.     user = getNomeUtilizador(sockfd);
  281.     string regist = "";
  282.     regist = regist + "SELECT nick FROM users WHERE nick='"
  283.             + user + "'";
  284.     PGresult *log = PQexec(conn, regist.c_str());
  285.  
  286.     if (PQresultStatus(log) != PGRES_TUPLES_OK) {
  287.         cout << "Failed to execute query" << ' ' << PQresultStatus(log) << endl;
  288.         return;
  289.     } else if (PQntuples(log) == 0){
  290.         writeline(sockfd,
  291.                 "Necessita de estar logado para criar uma sala.");
  292.         return;
  293.     }
  294.     else {
  295.         string check = "";
  296.         check = check + "SELECT nome_sala FROM rooms WHERE nome_sala='"
  297.             + nomesala + "'";
  298.         PGresult *log2 = PQexec(conn, check.c_str());
  299.         if (PQresultStatus(log2) != PGRES_TUPLES_OK) {
  300.           cout << "Failed to execute query" << ' ' << PQresultStatus(log2) << endl;
  301.           return;
  302.         } else if (PQntuples(log2) > 0)
  303.         {
  304.           writeline(sockfd,"A sala que pretende registar ja foi criada.");
  305.           return;
  306.         }
  307.         ostringstream oss;
  308.         oss << "INSERT INTO rooms VALUES ('" << nomesala << "', '" << user << "');";
  309.         string result = oss.str();
  310.         PGresult *log3 = PQexec(conn, result.c_str());
  311.         if (PQresultStatus(log3) != PGRES_COMMAND_OK) {
  312.             cout << "Failed to execute query " << ' ' << PQresultStatus(log3)
  313.                     << endl;
  314.             return;
  315.         }
  316.         writeline(sockfd, nomesala + " Sala criada com sucesso! =)");
  317.     }
  318. }
  319.  
  320. void juntar(int sockfd, string line) {
  321.     string user, comando, room;
  322.     istringstream iss(line);
  323.     iss >> comando >> room;
  324.     user = getNomeUtilizador(sockfd);
  325.     string regist = "";
  326.     regist = regist + "SELECT nome_sala FROM rooms WHERE nome_sala='"
  327.             + room + "'";
  328.     PGresult *log = PQexec(conn, regist.c_str());
  329.  
  330.     if (PQresultStatus(log) != PGRES_TUPLES_OK) {
  331.         cout << "Failed to execute query" << ' ' << PQresultStatus(log) << endl;
  332.         return;
  333.     } else if (PQntuples(log) == 0){
  334.         writeline(sockfd,"Sala nao existe.");
  335.         return;
  336.     }
  337.     else{
  338.       string junt = "";
  339.       junt = junt + "UPDATE users SET sala = '" + room + "' WHERE nick = '"
  340.               + user + "'";
  341.       PGresult *jun = PQexec(conn, junt.c_str());
  342.  
  343.       if (PQresultStatus(jun) != PGRES_COMMAND_OK) {
  344.           cout << "Failed to execute query" << ' ' << PQresultStatus(jun) << endl;
  345.           return;
  346.       }
  347.         writeline(sockfd, "Juntou-se a sala " + room + " com sucesso! =)");
  348.     }
  349.   }
  350.  
  351. void shout(int sockfd, string line) {
  352.     string comando, mensagem, user;
  353.  
  354.     istringstream iss(line);
  355.     iss >> comando >> mensagem;
  356.    
  357.     map<int, string>::iterator it = clientes.begin();
  358.     map<int, string>::iterator ite = clientes.end();
  359.     ostringstream oss;
  360.     for (;it!=ite;it++)
  361.     {
  362.       if (it->first == sockfd)
  363.         oss << "(" << get_date() + "|" + get_time() << ")["
  364.              << it->second << "] "<< " said: " << mensagem;
  365.     }
  366.     string check = "";
  367.     check = check + "SELECT nick, admin FROM users WHERE nick = '" + user + "' and admin= ' 1 '";
  368.     PGresult *log = PQexec(conn, check.c_str());
  369.    
  370.     if (PQresultStatus(log) != PGRES_TUPLES_OK) {
  371.         cout << "Failed to execute query" << ' ' << PQresultStatus(log) << endl;
  372.     } else if (PQntuples(log) == 0){
  373.         writeline(sockfd,
  374.                 " Nao tem permissoes para executar este comando! Para o fazer, necessita de estar registado e logado.");
  375.         return;
  376.     }
  377.     else {
  378.       iss >> comando;
  379.  
  380.       for (it = clientes.begin();it != ite; it++)
  381.           writeline(it->first, mensagem);
  382.     }
  383. }
  384.  
  385. void whisper(int sockfd, string line) {
  386.     string comando, user, mensagem;
  387.  
  388.     istringstream iss(line);
  389.  
  390.     iss >> comando >> user >> mensagem;
  391.    
  392.     map<int, string>::iterator it = clientes.begin();
  393.     map<int, string>::iterator ite = clientes.end();
  394.     ostringstream oss;
  395.     for (;it!=ite;it++)
  396.     {
  397.       if (it->first == sockfd)
  398.         oss << "(" << get_date() + "|" + get_time() << ")["
  399.              << it->second << "] "<< " said: " << mensagem;
  400.     }
  401.    
  402.     //comparar com o sql a variavel user e decobrir o seu socket
  403.     string util = "";
  404.     util = util + "SELECT nick FROM users WHERE nick='" + user + "'";
  405.     PGresult *log = PQexec(conn, util.c_str());
  406.  
  407.     if (PQresultStatus(log) != PGRES_TUPLES_OK) {
  408.         cout << "Failed to execute query" << ' ' << PQresultStatus(log) << endl;
  409.     } else if (PQntuples(log) == 1) {
  410.       map<int,string>::iterator it = clientes.begin();
  411.       map<int,string>::iterator ite = clientes.end();
  412.       for(;it!=ite;it++)
  413.       {
  414.         if (it->second == user)
  415.           writeline(it->first, mensagem);
  416.       }
  417.     } else {
  418.         writeline(sockfd,
  419.                 "O utilizador com o qual tentou falar nao existe ou nao esta connectado.");
  420.     }
  421.  
  422. }
  423.  
  424. void desligar(int sockfd) {
  425.     string regist = "";
  426.     regist = regist + "SELECT nick, admin FROM users WHERE nick='" + getNomeUtilizador(sockfd)
  427.             + "' and admin=' 1 '";
  428.     PGresult *log = PQexec(conn, regist.c_str());
  429.     if (PQresultStatus(log) != PGRES_TUPLES_OK) {
  430.             cout << "Failed to execute query" << ' ' << PQresultStatus(log) << endl;
  431.         } else if (PQntuples(log) == 1) {
  432.             exit(0);
  433.         } else {
  434.             writeline(sockfd, "Nao tem permissoes \n");
  435.         }
  436. }
  437.  
  438. void info(int sockfd, string line) {
  439. //  string comando, nick;
  440. //  istringstream iss(line);
  441. //  iss >> comando >> nick;
  442. //  string regist = "";
  443. //  regist = regist + "SELECT nick FROM users WHERE nick='" + nick  + "'";
  444. //  PGresult *log = PQexec(conn, regist.c_str());
  445. //
  446. //  if (PQresultStatus(log) != PGRES_TUPLES_OK) {
  447. //      cout << "Failed to execute query" << ' ' << PQresultStatus(log) << endl;
  448. //  } else if (PQntuples(log) == 0)
  449. //      writeline(sockfd,
  450. //              "Nao existe um utilizador com esse nome!");
  451. //  else {
  452. //      string regist2 = "";
  453. //      regist2 = regist2 + "SELECT nick, sala, data_ultimo_login, hora_ultimo_login FROM users WHERE nick='" + nick    + "'";
  454. //      PGresult *log2 = PQexec(conn, regist.c_str());
  455. //      writeline(sockfd,
  456. //     
  457. //      // falta o write line e saber como vamos buscar o admin sala etc.
  458. //  }
  459. }
  460.  
  461. void ajuda(int sockfd) {
  462.     writeline(
  463.             sockfd,
  464.             "\\identify - Verifica se o utilizador existe na base de dados ou se ja esta conetado. Se ainda nao existir o socket passa a estar associado a este utilizador. Serve para as pessoas se poderem identificar sem terem de criar uma conta.\n Para executar este comando, digite: identify <username> \n");
  465.     writeline(
  466.             sockfd,
  467.             "\\register - Verifica se o utilizador ja existe na base de dados. Se nao existir cria-o e associa o socket ao utilizador criado.\n Para executar este comando, digite: register <username> <password> \n");
  468.     writeline(sockfd,
  469.             "\\login - Para executar este comando, digite: login <username> <password>\n");
  470.     writeline(sockfd, "\\create - Cria uma nova sala de chat. Apenas utilizadores que estejam logados teem permissao para esta aplicacao.\n Para executar este comando, digite: create <room_name> \n");
  471.     writeline(sockfd, "\\join - Permite ao utilizador entrar numa sala.\n Para executar este comando, digite: join <room_name>\n");
  472.     writeline(
  473.             sockfd,
  474.             "\\shout - Enviar uma mensagem para todos os utilizadores (mesmo os de outras salas). So utilizadores com privilegios elevados podem usar esta funcao.\n Para executar este comando, digite: shout <mensagem> \n");
  475.     writeline(sockfd,
  476.             "\\whisper - Enviar uma mensagem a um utilizador específico.\n Para executar este comando, digite: whisper <utilizador> <mensagem> \n");
  477.     writeline(sockfd, "\\exit: Desliga a conexao deste cliente.\n Para executar este comando, digite: exit \n");
  478.     writeline(
  479.             sockfd,
  480.             "\\shutdown: Desliga o servidor. So utilizadores com privilegios elevados podem executar esta funcao.\n Para executar este comando, digite: shutdown \n");
  481.     writeline(sockfd,
  482.             "\\info - Da algumas indicacioes sobre um utilizador especíifico.\n Para executar este comando, digite: info <username> \n");
  483. }
  484.  
  485. /* Trata de receber dados de um cliente cujo socketid foi
  486.  passado como parâmetro */
  487. void* cliente(void* args) {
  488.     /* quando um utilizador entra, atribui um nome guest + numero de utilizadores online (quando um utilizador sai, a variavel
  489.      * numUtilizadoresOnline decrementa) e adiciona o utilizador ao clientes (e aos mapas???)
  490.      * */
  491.     int sockfd = *(int*) args;
  492.     string line;
  493.     int random = ((rand() % 999) + 1);
  494.     stringstream aux;
  495.     aux << random;
  496.     string nome = "guest" + aux.str();
  497.    
  498.    
  499.     pair<int,string> cliente = pair<int,string>(sockfd,nome);
  500.     clientes.insert(cliente);
  501.  
  502.     //  mapas.insert("guest" + numUtilizadoresConnectados,sockfd);
  503.     //   cout << "Client connected: " << mapas[sockfd] << endl;
  504.     while (readline(sockfd, line)) {
  505.         cout << "Socket " << sockfd << " said: " << line << endl;
  506.         if (line.find("\\identify") != string::npos)
  507.             identify(sockfd, line);
  508.         else if (line.find("\\register") != string::npos)
  509.             registo(sockfd, line);
  510.         else if (line.find("\\login") != string::npos)
  511.             login(sockfd, line);
  512.         else if (line.find("\\create") != string::npos)
  513.             criar(sockfd, line);
  514.         else if (line.find("\\join") != string::npos)
  515.             juntar(sockfd, line);
  516.         else if (line.find("\\shout") != string::npos)
  517.             shout(sockfd, line);
  518.         else if (line.find("\\whisper") != string::npos)
  519.             whisper(sockfd, line);
  520.         else if (line.find("\\exit") != string::npos)
  521.             break;
  522.         else if (line.find("\\shutdown") != string::npos)
  523.             desligar(sockfd);
  524.         else if (line.find("\\info") != string::npos)
  525.             info(sockfd, line);
  526.         else if (line.find("\\help") != string::npos)
  527.             ajuda(sockfd);
  528.         else
  529.             broadcast(sockfd, line);
  530.     }
  531.  
  532.     cout << "Client disconnected: " << sockfd << endl;
  533.     clientes.erase(sockfd);
  534.  
  535.     /* Fechar o socket */
  536.     close(sockfd);
  537. }
  538.  
  539. int main(int argc, char *argv[]) {
  540.     /* Estruturas de dados */
  541.     srand(time(NULL));
  542.  
  543.     ligar_sql();
  544.     int sockfd, newsockfd, port = 1990;
  545.     socklen_t client_addr_length;
  546.     struct sockaddr_in serv_addr, cli_addr;
  547.     int numClientes;
  548.  
  549.     /* Inicializar o socket
  550.      AF_INET - para indicar que queremos usar IP
  551.      SOCK_STREAM - para indicar que queremos usar TCP
  552.      sockfd - id do socket principal do servidor
  553.      Se retornar < 0 ocorreu um erro */
  554.     sockfd = socket(AF_INET, SOCK_STREAM, 0);
  555.     if (sockfd < 0) {
  556.         cout << "Error creating socket" << endl;
  557.         exit(-1);
  558.     }
  559.  
  560.     /* Criar a estrutura que guarda o endereço do servidor
  561.      bzero - apaga todos os dados da estrutura (coloca a 0's)
  562.      AF_INET - endereço IP
  563.      INADDR_ANY - aceitar pedidos para qualquer IP */
  564.     bzero((char *) &serv_addr, sizeof(serv_addr));
  565.     serv_addr.sin_family = AF_INET;
  566.     serv_addr.sin_addr.s_addr = INADDR_ANY;
  567.     serv_addr.sin_port = htons(port);
  568.  
  569.     /* Fazer bind do socket. Apenas nesta altura é que o socket fica ativo
  570.      mas ainda não estamos a tentar receber ligações.
  571.      Se retornar < 0 ocorreu um erro */
  572.     int res = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
  573.     if (res < 0) {
  574.         cout << "Error binding to socket" << endl;
  575.         exit(-1);
  576.     }
  577.  
  578.     /* Indicar que queremos escutar no socket com um backlog de 5 (podem
  579.      ficar até 5 ligações pendentes antes de fazermos accept */
  580.     listen(sockfd, 5);
  581.  
  582.     while (true) {
  583.         /* Aceitar uma nova ligação. O endereço do cliente fica guardado em
  584.          cli_addr - endereço do cliente
  585.          newsockfd - id do socket que comunica com este cliente */
  586.         client_addr_length = sizeof(cli_addr);
  587.         newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,
  588.                 &client_addr_length);
  589.  
  590.         /* Criar uma thread para tratar dos pedidos do novo cliente */
  591.         pthread_t thread;
  592.         pthread_create(&thread, NULL, cliente, &newsockfd);
  593.     }
  594.  
  595.     PQfinish(conn);
  596.     close(sockfd);
  597.     return 0;
  598. }
Add Comment
Please, Sign In to add comment