Advertisement
Bressam

AlgoritmoBully

Jun 28th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 22.74 KB | None | 0 0
  1. /*
  2.  * To change this license header, choose License Headers in Project Properties.
  3.  * To change this template file, choose Tools | Templates
  4.  * and open the template in the editor.
  5.  */
  6.  
  7. /**
  8.  *
  9.  * @author giovanne.gaspareto
  10.  */
  11. /*
  12.  * To change this license header, choose License Headers in Project Properties.
  13.  * To change this template file, choose Tools | Templates
  14.  * and open the template in the editor.
  15.  */
  16.  
  17. import java.io.BufferedOutputStream;
  18. import java.io.ByteArrayInputStream;
  19. import java.io.ByteArrayOutputStream;
  20. //import java.io.EOFException;
  21. //import java.io.IOException;
  22. //import java.io.ObjectInputStream;
  23. //import java.net.UnknownHostException;
  24. import java.io.ByteArrayOutputStream;
  25. import java.io.IOException;
  26. import java.io.ObjectOutputStream;
  27. import java.net.DatagramPacket;
  28. import java.net.DatagramSocket;
  29. import java.net.InetAddress;
  30. import java.net.MulticastSocket;
  31. import java.net.SocketException;
  32. import java.net.SocketTimeoutException;
  33. import java.util.Scanner;
  34. import java.util.logging.Level;
  35. import java.util.logging.Logger;
  36.  
  37. public class ProcessoSender {
  38.     static DatagramPacket msg;
  39.     static DatagramPacket recv;
  40.     static DatagramPacket datagramLider;
  41.     static InetAddress grupo;
  42.     static MulticastSocket s;
  43.     private static Scanner keyboard;
  44.    
  45.     static int contadorMensagens = 0;
  46.     static final String GROUP_IP = "224.0.0.1";
  47.     static final int MULTICAST_PORT = 2000;
  48.     static int IDProcesso = 0;
  49.     static int IDLider = 0;
  50.     static InetAddress IPLider;
  51.     static int PortLider;
  52.     static int IDRecebido = 0;
  53.     static boolean aguardarResposta = false;
  54.     static boolean pararExecucao = false;
  55.     static int tempoDeVerificacao = 15;
  56.     /*
  57.     // Leitura de teclado
  58.     static String lerGrupo = "1";
  59.     static String enviarMensagem = "2";
  60.     static String verificarCoordenador = "3";
  61.     */
  62.     static boolean eleicaoEmAndamento = false;
  63.     static boolean isLeader = false;
  64.     static String mensagem = "";
  65.     static final String OK_STRING = "ok";
  66.     static final String DESCONECTAR_STRING = "q";
  67.     static final String ELEICAO_STRING = "e";
  68.     static final String VERIFICA_COORDENADOR_STRING = "v";
  69.     static final String DIVISOR_STRING = ";";
  70.     static final String OK_LIDER = "okL";
  71.     static final String TIMEOUT_STRING = "";
  72.     static final String LIDER_ELEITO_STRING = "L";
  73.     static final int DESCONECTAR = 1;
  74.     static final int REALIZAR_ELEICAO = 2;
  75.     static final int VERIFICA_COORDENADOR = 3;
  76.     static final int RESPONDER_ELEICAO = 4;
  77.     static final int LIDER_ELEITO = 5;
  78.     static final int OK = 6;
  79.     static final int RESPONDER_VERIFICACAO_LIDER = 7;
  80.     static final int IGNORAR = 0;
  81.     static final int ERRO_SOCKET = -1;
  82.     static final String MENU = "1-Ler grupo\n"
  83.                                 + "2-Enviar mensagem\n"
  84.                                 + "3-Verificar Coordenador\n"
  85.                                 + "q-Encerrar processo";
  86.    
  87.    
  88.     //Unicast
  89.     static DatagramSocket serverSocket;
  90.     static final String LIDER_EXISTE_STRING = "lider";
  91.     static final String PERGUNTA_LIDER_VIVO = "lider?";
  92.     static final int TIMEOUT = 10;
  93.     //
  94.    
  95.     /**
  96.      *
  97.      * @param msgStr
  98.      */
  99.     public static void sendMessageGroup(String msgStr) {
  100.         msg=new DatagramPacket(msgStr.getBytes(), msgStr.length(),grupo, 2000);
  101.        // System.out.println("Enviando mensagem para o grupo ...");
  102.         try {
  103.             s.send(msg);
  104.         } catch (IOException e) {
  105.             // TODO Auto-generated catch block
  106.             e.printStackTrace();
  107.         }
  108.     }
  109.  
  110.     /*
  111.     public static void receiveMessage(int i) {
  112.         byte[] buf=new byte[1000];
  113.         DatagramPacket recv=new DatagramPacket(buf, buf.length);
  114.         System.err.print("Aguardando mensagem "+i+" ...");
  115.         try {
  116.             s.receive(recv);
  117.             byte[] dest=new byte[recv.getLength()];
  118.             System.arraycopy(recv.getData(), 0, dest, 0, dest.length);
  119.             System.err.println("Mensagen recebida: "+
  120.                     new String(recv.getData(),recv.getOffset(),recv.getLength()));
  121.         } catch (IOException e) {
  122.             // TODO Auto-generated catch block
  123.             e.printStackTrace();
  124.         }
  125.     }
  126.    */
  127.     /*
  128.     public static void sendObj() {
  129.        
  130.         try {
  131.              //Prepare Data
  132.             String message = "Hello there!";
  133.             ByteArrayOutputStream baos = new ByteArrayOutputStream();
  134.             ObjectOutputStream oos;
  135.             oos = new ObjectOutputStream(baos);
  136.             oos.writeObject(message);
  137.             byte[] data = baos.toByteArray();
  138.      
  139.             //Send data
  140.             s.send(new DatagramPacket(data, data.length, grupo, multicastPort));
  141.         } catch (IOException e) {
  142.             // TODO Auto-generated catch block
  143.             e.printStackTrace();
  144.         }
  145.     }
  146.     */
  147.    
  148.     //Funcao de configuracao
  149.     public static void setUp() {
  150.         try {
  151.             System.setProperty("java.net.preferIPv4Stack", "true"); // somente pra mac no wifi
  152.             grupo=InetAddress.getByName(GROUP_IP);
  153.             s=new MulticastSocket(MULTICAST_PORT);
  154.             System.err.println("Entrando no grupo ...");
  155.             s.joinGroup(grupo);
  156.             System.err.println("Ok.");
  157.            // s.setLoopbackMode(true);  //evita de ler a propria mensagem
  158.         } catch (IOException e) {
  159.             // TODO Auto-generated catch block
  160.             e.printStackTrace();
  161.         }
  162.        
  163.     }
  164.    
  165.     public static void defineIDProcesso(){
  166.         keyboard = new Scanner(System.in);
  167.         System.out.println("Informe o ID deste processo: ");
  168.         IDProcesso = keyboard.nextInt();
  169.     }
  170.    
  171.  
  172.     /*
  173.     public static int opcoesTeclado(){
  174.         keyboard = new Scanner(System.in);
  175.         System.out.println(menu);
  176.         mensagem = keyboard.nextLine();
  177.         if(mensagem.equals(lerGrupo)){
  178.             contadorMensagens++;
  179.             receiveMessage(contadorMensagens);
  180.         }else if(mensagem.equals(enviarMensagem)){
  181.             //sendObj();
  182.             keyboard = new Scanner(System.in);
  183.             System.out.println("Mensagem a ser enviada: ");
  184.             mensagem = keyboard.nextLine();
  185.             sendMessage(mensagem);
  186.         }else if(mensagem.equals(verificarCoordenador)){
  187.             //System.out.println("Opcao 3 selecionada");
  188.             if(verificaCoordenador()){
  189.                 //Achou coordenador
  190.              }else{
  191.                 //Nao achou coordenador, faz eleicao
  192.              }
  193.         }else if(mensagem.equalsIgnoreCase(sair)){
  194.             break;
  195.         }
  196.     }
  197.     */
  198.     public static String receiveMessageGroup(){
  199.         byte[] buf=new byte[1000];
  200.         recv=new DatagramPacket(buf, buf.length);
  201.         try {
  202.             s.setSoTimeout(10);
  203.             s.setLoopbackMode(false);
  204.            // System.out.println("timeout no recevei sem nada: " + s.getSoTimeout());
  205.             s.receive(recv);
  206.             byte[] dest=new byte[recv.getLength()];
  207.             System.arraycopy(recv.getData(), 0, dest, 0, dest.length);
  208.             String mensagemRecebida = new String(recv.getData(),recv.getOffset(),recv.getLength());
  209.             //System.err.println("Mensagen recebida: "+ mensagemRecebida);
  210.             return mensagemRecebida;
  211.         } catch (SocketTimeoutException ex) {
  212.           //  Logger.getLogger(ProcessoSender.class.getName()).log(Level.SEVERE, null, ex);
  213.             return "x;0;0";
  214.     } catch (IOException e) {
  215.             // TODO Auto-generated catch block
  216.             e.printStackTrace();
  217.             return "x;0;0";
  218.         }
  219.     }
  220.    
  221.     public static int trataMensagem(String mensagemRecebida, DatagramPacket PacketLider){
  222.         String[] partes = mensagemRecebida.split(DIVISOR_STRING);
  223.         String operacao = partes[0];
  224.         String mensagem = partes[1];
  225.         IDRecebido = Integer.parseInt(mensagem);
  226.         if(operacao.equals(LIDER_ELEITO_STRING)){
  227.             //IDRecebido = Integer.parseInt(mensagem);
  228.             setPortIPLider(recv,mensagem);
  229.             return LIDER_ELEITO;
  230.         }
  231.         else if(operacao.equals(VERIFICA_COORDENADOR_STRING)){
  232.             return RESPONDER_VERIFICACAO_LIDER;
  233.         }else if(operacao.equals(ELEICAO_STRING)){
  234.             if(Integer.parseInt(mensagem) == IDProcesso){ //foi o proprio processoq que iniciou a eleicao, ignora sua propria mensagem
  235.                 return IGNORAR;
  236.             }
  237.             else{
  238.                 IDRecebido = Integer.parseInt(mensagem);
  239.                 return RESPONDER_ELEICAO;
  240.             }
  241.         }else if(operacao.equals(DESCONECTAR_STRING)){
  242.             if(Integer.parseInt(mensagem) == IDProcesso){
  243.                 return DESCONECTAR;
  244.             }
  245.             else return IGNORAR;
  246.         }else if(operacao.equals(OK_STRING)){
  247.             if(Integer.parseInt(mensagem) == IDProcesso){ //se foi ele mesmo que enviou o OK ou se nao esta mais na eleicao, ignora
  248.                 return IGNORAR;
  249.             }
  250.             else{
  251.                // eleicaoEmAndamento = false;  //processo para de participar da eleicao, tem alguem maior
  252.                //setPortIPLider(PacketLider, mensagem);
  253.                String idRecebido = partes[2];
  254.                IDRecebido = Integer.parseInt(idRecebido);
  255.                
  256.                if(Integer.parseInt(idRecebido) == IDProcesso){
  257.                  return OK;
  258.                }
  259.                else{
  260.                 return IGNORAR;
  261.                }
  262.             }
  263.         }else if(operacao.equals("")){
  264.             return ERRO_SOCKET;
  265.         }else{
  266.             // mensagem ignorada
  267.             return IGNORAR;
  268.         }
  269.     }
  270.    
  271.     public static void setPortIPLider(DatagramPacket PacketLider, String mensagemIDLider){
  272.         IDLider = Integer.parseInt(mensagemIDLider);
  273.         IPLider = PacketLider.getAddress();
  274.         PortLider = PacketLider.getPort();
  275.        
  276.     }
  277.    
  278.     public static void realizarEleicao(){
  279.         //Quando coordenador for eleito, envia mensagem para o grupo,
  280.         //dessa mensagem todos pegaram o IP e porta para poder realizar a conexão unicast
  281.        
  282.         //Etapas: Enviar mensagem de eleicao = e;ID. Todos recebem, se tiverem ID menor ignora
  283.         // Quem tiver ID maior ou por algum motivo tiver flag de lider ligada, responde
  284.         mensagem = ELEICAO_STRING+DIVISOR_STRING+IDProcesso;
  285.         sendMessageGroup(mensagem);
  286.         eleicaoEmAndamento = true;
  287.     }
  288.    
  289.     public static boolean responderEleicao(){
  290.         //IDRecebido = Integer.parseInt(mensagemRecebida);
  291.         if(IDProcesso >= IDRecebido){
  292.            // isLeader = true;
  293.             mensagem = OK_STRING+DIVISOR_STRING+IDProcesso+DIVISOR_STRING+IDRecebido;
  294.             sendMessageGroup(mensagem);
  295.             return true;
  296.         }
  297.         else{
  298.             //ignora mensagem
  299.             eleicaoEmAndamento = false; //sai da eleicao
  300.             isLeader = false;           //nao é mais o lider
  301.             return false;
  302.         }
  303.     }
  304.    
  305.     public static boolean verificaCoordenador() throws SocketException{
  306.         //envia mensagem para coordenador, se nao receber resposta dentro do timeout faz eleicao
  307.         /*
  308.         //Se receber resposta do coordenador
  309.         if(liderVivo()){
  310.             return true;
  311.         }
  312.         else {
  313.             realizarEleicao();
  314.             return false;
  315.         }
  316.         */
  317.         mensagem = VERIFICA_COORDENADOR_STRING+DIVISOR_STRING+IDProcesso;
  318.         sendMessageGroup(mensagem); //envia mensagem de verificaçao para o lider responder caso esteja vivo
  319.         TimerProcessos tempoEsperaPorOkLider = new TimerProcessos(1);
  320.         while(!tempoEsperaPorOkLider.shouldCreate)
  321.         {
  322.            mensagem = receiveMessageGroup();  // espera resposta do lider, pelo delay/timeout definido
  323.            if (!mensagem.equals("")){ //teve resposta, verificar qual foi
  324.                String[] partes = mensagem.split(DIVISOR_STRING);
  325.                String operacao = partes[0];
  326.                String conteudo = partes[1];
  327.                if(operacao.equals(OK_LIDER)){ //lider respondeu
  328.                    tempoEsperaPorOkLider.cancelTimer();
  329.                    setPortIPLider(recv,conteudo);
  330.                    return true;
  331.                }
  332.            }
  333.            else{
  334.                tempoEsperaPorOkLider.cancelTimer();
  335.                return false; //teve timeout, nao existe lider
  336.            }
  337.         }
  338.         tempoEsperaPorOkLider.cancelTimer();
  339.         return false;
  340.     }
  341.  
  342.     public static boolean liderVivo(){
  343.         try {
  344.             serverSocket = new DatagramSocket();
  345.             String toSend= PERGUNTA_LIDER_VIVO;
  346.             byte[] buffer=toSend.getBytes();
  347.             DatagramPacket pergunta=new DatagramPacket(buffer, buffer.length,
  348.                         IPLider, PortLider);
  349.             serverSocket.send(pergunta);
  350.             s.setSoTimeout(TIMEOUT);
  351.             while(true){
  352.             s.receive(pergunta);
  353.             String mensagemRecebida = new String(pergunta.getData(),pergunta.getOffset(),pergunta.getLength());
  354.                 if(mensagemRecebida.equals(LIDER_EXISTE_STRING)){
  355.                     serverSocket.close();
  356.                   return true; //Se a mensagem for a confirmacao do lider, sai da espera
  357.                 }
  358.             }
  359.         } catch (SocketException ex) {
  360.             Logger.getLogger(ProcessoSender.class.getName()).log(Level.SEVERE, null, ex);
  361.         } catch (IOException ex) {
  362.             Logger.getLogger(ProcessoSender.class.getName()).log(Level.SEVERE, null, ex);
  363.         }
  364.         serverSocket.close();
  365.         return true;
  366.     }
  367.    
  368.     public static String receiveMessageGroupWithDelay() throws SocketException{
  369.         byte[] buf=new byte[1000];
  370.         recv=new DatagramPacket(buf, buf.length);
  371.         try {
  372.             s.setLoopbackMode(true);  //evita de ler a propria mensagem
  373.             s.setSoTimeout(TIMEOUT);
  374.            // System.out.println("Timeout no receive com timeout: " + s.getSoTimeout());
  375.             s.receive(recv);
  376.             byte[] dest=new byte[recv.getLength()];
  377.             System.arraycopy(recv.getData(), 0, dest, 0, dest.length);
  378.             String mensagemRecebida = new String(recv.getData(),recv.getOffset(),recv.getLength());
  379.             //System.err.println("Mensagen recebida do delay: "+ mensagemRecebida);
  380.             s.setLoopbackMode(false);  //habilita ler a propria mensagem
  381.             return mensagemRecebida;
  382.         }catch (SocketTimeoutException e) {
  383.             // timeout exception.
  384.             //System.out.println("Timeout reached!!! " + e);
  385.             //System.out.println("TIMEOUUTTT");
  386.             s.setSoTimeout(0);
  387.             s.setLoopbackMode(false);
  388.             return "x;0;0";
  389.         } catch (IOException ex) {
  390.             Logger.getLogger(ProcessoSender.class.getName()).log(Level.SEVERE, null, ex);
  391.             s.setSoTimeout(0);
  392.             s.setLoopbackMode(false);
  393.             return "x;0;0";
  394.         }
  395.     }
  396.    
  397.     public static void main(String[] args) {
  398.         try {
  399.             defineIDProcesso();
  400.             setUp();
  401.             TimerProcessos timerVerificacaoLider = new TimerProcessos(tempoDeVerificacao);
  402.             //sendMessage("Novo membro no grupo");
  403.             while(!pararExecucao) {
  404.                 //If passou x segundos - Verificar lider
  405.                 if (eleicaoEmAndamento){
  406.                    // timerVerificacaoLider.cancelTimer();
  407.                     boolean idMaior = responderEleicao();
  408.                     if(idMaior){
  409.                         realizarEleicao();
  410.                         // timeout nao funciona ja que esta tud9o nomesmo ip. Usar classe de timer e, enquanto o timer nao der o valor de timeout, aguardar algo que seja "OK"
  411.                        TimerProcessos tProcesso = new TimerProcessos(1);
  412.                        aguardarResposta = true;
  413.                         while(!tProcesso.shouldCreate && aguardarResposta){
  414.                             //System.out.println("Aguardando resposta da eleicao");
  415.                             switch (trataMensagem(receiveMessageGroupWithDelay(),recv)) {
  416.                                 case OK: //teve Ok de outro processo
  417.                                     isLeader = false;
  418.                                     aguardarResposta = false;
  419.                                   //  System.out.println("OK da eleicao recebida");
  420.                                     break;
  421.                                 case RESPONDER_ELEICAO:
  422.                                     idMaior = responderEleicao();
  423.                                    // System.out.println("Respondendo eleicao");
  424.                                     if(!idMaior){
  425.                                         aguardarResposta = false;
  426.                                         isLeader = false;
  427.                                     }
  428.                                     break;
  429.                                 case LIDER_ELEITO:
  430.                                     if(IDRecebido>IDProcesso){
  431.                                         aguardarResposta = false;
  432.                                         isLeader = false;
  433.                                     }
  434.                                     break;
  435.                                 default:
  436.                                   //  System.out.println("default da eleicao");
  437.                                     //sendMessageGroup("a;0");
  438.                                     break;
  439.                             }
  440.                         }
  441.                         //if(tProcesso.shouldCreate){
  442.                         if(aguardarResposta){ //se saiu enquanto aguardava resposta, é lider
  443.                             System.out.println("Processo "+IDProcesso+" é novo lider");
  444.                             isLeader=true;
  445.                             mensagem = LIDER_ELEITO_STRING+DIVISOR_STRING+IDProcesso;
  446.                             sendMessageGroup(mensagem);
  447.                         }else{
  448.                             System.out.println("Nao é lider");
  449.                             isLeader = false;
  450.                         }
  451.                         tProcesso.cancelTimer();
  452.                     }
  453.                     eleicaoEmAndamento = false;
  454.                     System.out.println("Eleicao acabou");
  455.                     timerVerificacaoLider = new TimerProcessos(tempoDeVerificacao);
  456.  
  457.                 }
  458.                 else{
  459.                   //  System.out.println("Voltou a ouvir mensagens");
  460.                   //  System.out.println("Timeout no main: " + s.getSoTimeout());
  461.                   if (timerVerificacaoLider.shouldCreate && !isLeader && !eleicaoEmAndamento){
  462.                       //acabou tempo, verificar lider
  463.                     boolean liderVivo = verificaCoordenador();
  464.                    
  465.                     if(!liderVivo){
  466.                         System.out.println("Nao ha lider!");
  467.                         eleicaoEmAndamento = true; //inicia eleicao
  468.                         mensagem = ELEICAO_STRING+DIVISOR_STRING+IDProcesso;
  469.                         sendMessageGroup(mensagem);
  470.                     }else{
  471.                         System.out.println("Lider existe! Lider: [Processo "+IDLider+"]");
  472.                     }
  473.                    
  474.                     timerVerificacaoLider = new TimerProcessos(tempoDeVerificacao); // novo timer
  475.                   }
  476.                     switch(trataMensagem(receiveMessageGroup(), recv)){
  477.                     case VERIFICA_COORDENADOR:
  478.                             //Verificar Coordenador
  479.                         /*
  480.                             boolean liderVivo = verificaCoordenador();
  481.                             if(!liderVivo){
  482.                                 System.out.println("Nao ha lider!");
  483.                                 eleicaoEmAndamento = true; //inicia eleicao
  484.                                 mensagem = ELEICAO_STRING+DIVISOR_STRING+IDProcesso;
  485.                                 sendMessageGroup(mensagem);
  486.                             }
  487. */
  488.                             break;
  489.                     case RESPONDER_ELEICAO:
  490.                             //responderEleicao();
  491.                             if(IDRecebido < IDProcesso){
  492.                                 System.out.println("Eleicao em andamento");
  493.                                 eleicaoEmAndamento = true;
  494.                             }
  495.                             break;
  496.                     case LIDER_ELEITO:
  497.                         //System.out.println("ID recebido: "+IDRecebido);
  498.                         if(IDRecebido < IDProcesso)
  499.                         {
  500.                             eleicaoEmAndamento = true;
  501.                         }
  502.                         else{
  503.                             eleicaoEmAndamento = false;
  504.                             if(IDLider != IDProcesso){
  505.                                 isLeader = false;
  506.                                 System.out.println("[Processo "+IDProcesso+"] Nao sou lider!");
  507.                             }
  508.                             System.out.println("Novo lider eleito, ID do lider: "+IDLider
  509.                                                 + ", IP do lider: " +IPLider
  510.                                                 + ", Porta do lider: " +PortLider);
  511.                         }
  512.                             break;
  513.                     case RESPONDER_VERIFICACAO_LIDER:
  514.                             if(isLeader){
  515.                                 mensagem = OK_LIDER+DIVISOR_STRING+IDProcesso;
  516.                                 sendMessageGroup(mensagem);
  517.                                 System.out.println("Respondendo verificacao de lider vivo");
  518.                                 System.out.println("[Processo "+IDProcesso+"] Sou lider!");
  519.                             }
  520.                             else{
  521.                                 System.out.println("[Processo "+IDProcesso+"] Nao sou lider!");
  522.                             }
  523.                             break;
  524.                     case IGNORAR:
  525.                     //  System.err.print("mensagem ignorada");
  526.                             break;
  527.                     case ERRO_SOCKET:
  528.                             System.err.print("Mensagem nao recebida");
  529.                             break;
  530.                     case DESCONECTAR:
  531.                             System.err.println("Processo "+IDProcesso+" saindo do grupo...");
  532.                             s.leaveGroup(grupo);
  533.                             System.err.println("Desconectado do grupo.");
  534.                             pararExecucao = true;
  535.                             break;
  536.                     default:
  537.                            // System.err.print("Case default");
  538.                             break;
  539.                     }
  540.                 }
  541.             }
  542.         } catch(IOException exc) {
  543.             exc.printStackTrace();
  544.         }
  545.         System.out.println("Processo encerrado");
  546.         System.exit(0);
  547.     }
  548. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement