Escolar Documentos
Profissional Documentos
Cultura Documentos
PROJETO 2022/2023:
FUNDAMENTOS DE SISTEMAS DISTRIBUÍDOS
PL1 – Grupo 4
3ª ENTREGA
Relatório de Código
Guilherme José de Sousa Inês Capa de Barros Maria Beatriz Garcez Morais
Barbosa
PresencesServer
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
while (true) {
try {
Socket ligacao = servidor.accept();
AtendePedidoTCP atendePedidoTCP = new
AtendePedidoTCP(ligacao, presencesServer);
atendePedidoTCP.start();
listaUtilizadores.add(atendePedidoTCP);//adiciona um
novo utilizador à lista de atendePedidoTCP
} catch (IOException e) {
System.out.println("Erro na execucao do servidor: " +
e);
System.exit(1);
}
}
}
}
}, 1 * 1000, 10 * 1000); //repete-se a cada segundo
}
}
Presences
import java.security.PublicKey;
import java.util.Base64;
import java.util.Date;
import java.util.Hashtable;
import java.util.Vector;
}
return result;
}
class IPInfo {
private String nickname; //guardar o nickname também
private String ip;
private long lastSeen;
private boolean rmi;
private PublicKey publicKey;
presencesServer.getPresences().getPresences(String.valueOf(ligacao.get
InetAddress()), nickname, rmi, publicKey); //atualizamos com a publick
key
System.out.println(ligacao.getInetAddress());
}
this.rmi = Boolean.valueOf(sp[1]);
//fazer a mesma cena para ir buscar a public key
try {
//Vamos ter que apartir de uma string, obter os bytes e
posteriormente a chave publica do cliente.
KeyFactory factory = KeyFactory.getInstance("RSA",
"SunRsaSign");
byte[] decodedBytes =
Base64.getDecoder().decode(publicKeyString);
publicKey = (PublicKey) factory.generatePublic(new
X509EncodedKeySpec(decodedBytes));
System.out.println(publicKey);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
if (nickname == null) {
nickname = sp[0];
; //se ele nao tiver nickname, entao o nickname é igual ao
que ele mandou para o servidor
}
atualizarPresencas(); //cada vez que ele faz um
sessionUpdateRequest atualizamos o tempo.
enviarSessionUpdateParaTodosUtilizadores(); //passo 9
}
out.println(presencesServer.getPresences().getNicknameIpRmiPublicKey()
.get(i)); //enviar o nickname de cada cliente
}
int tamanhoMensagens =
presencesServer.getDezMensagensMaisRecentes().size();
if (tamanhoMensagens <= 10) {
out.println(Integer.toString(tamanhoMensagens));
for (int i = 0; i < tamanhoMensagens; i++) {
out.println(presencesServer.getDezMensagensMaisRecentes().get(i));
}
} else {
out.println(Integer.toString(10));
int inicio =
presencesServer.getDezMensagensMaisRecentes().size() - 10; //vemos a
primeira mensagem a enviar
int fim =
presencesServer.getDezMensagensMaisRecentes().size(); //
vemos o fim
out.println(presencesServer.getDezMensagensMaisRecentes().get(i));
}
}
}
}
InterfaceCliente
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.Socket;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
import java.util.Timer;
if (rmi == false) {
table3.setVisible(false);
sendPrivateMessageBtn.setVisible(false);
tfSendPrivateMessage.setVisible(false);
sendButton.setVisible(false);
} else {
table3.setModel(model3);
model3.addColumn("Mensagens Privadas: ");
}
table1.setModel(model);
model.addColumn("Mensagens"); //cabeçalho da tabela de
mensagens
table2.setModel(model2);
model2.addColumn("Utilizadores Online:"); //cabeçalho da
tabela de utilizadores online
if (usernameTf.getText().isBlank()) { //erro se se
tentar conectar com o campo do nickname vazio
JOptionPane.showMessageDialog(null, "Escolha um
nickname!", "ERRO!", JOptionPane.ERROR_MESSAGE);
} else {
inicarLoop(nickname, timer);
receberMensagem();
}
}
});
sendPrivateMessageBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int coluna = 0;
int linha = table2.getSelectedRow();
if (linha == -1) {
JOptionPane.showMessageDialog(null, "Selecione um
utilizador para enviar mensagem privada!", "ERRO!",
JOptionPane.ERROR_MESSAGE);
} else {
separarNicknameIpRmi(linha, coluna, true); //
temos de separar os argumentos dos clientes.
String mensagemPorTratar =
model2.getValueAt(linha, coluna).toString();
String[] sp = mensagemPorTratar.split(" "); //
dividir as string num array de strings
String nick = sp[0]; //nickame
tfSendPrivateMessage.setUI(new
HintTextFieldUI("Enviar para " + nick, true));
}
}
});
sendButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int coluna = 0;
int linha = table2.getSelectedRow();
if (linha == -1) {
JOptionPane.showMessageDialog(null, "Selecione um
utilizador para enviar mensagem privada!", "ERRO!",
JOptionPane.ERROR_MESSAGE);
} else {
separarNicknameIpRmi(linha, coluna, false); //
temos de separar os argumentos dos clientes.
String mensagemPorTratar =
model2.getValueAt(linha, coluna).toString();
String[] sp = mensagemPorTratar.split(" "); //
dividir as string num array de strings
String nick = sp[0]; //nickame
tfSendPrivateMessage.setUI(new
HintTextFieldUI("Enviar para " + nick, true));
}
}
});
}
sp = mensagemPorTratar.split(" ");
ip = sp[0].substring(1);
indexOfSpace = mensagemPorTratar.indexOf(" ");
rmi = Boolean.valueOf(mensagemPorTratar.substring(indexOfSpace
+ 1));
System.out.println(ip);
}
}
String clienteQueRecebeu =
privateMessaging.sendMessage(nickname, mensagemEnviar);// escrever na
tabela para quem vamos enviar a mensagem a enviar
//adicionamos diretamente na tabela o que vamos enviar
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
String encodedString =
Base64.getEncoder().encodeToString(cipherText); //passar o sumario
enctiptado para uma string atraves do base64
PrivateMessaging privateMessaging = (PrivateMessaging)
LocateRegistry.getRegistry(ip).lookup(SERVICE_NAME); //acedemos à
interface de quem vai receber
String clienteQueRecebeu =
privateMessaging.sendMessageSecure(nickname, mensagemEnviar,
encodedString);// escrever na tabela para quem vamos enviar a mensagem
a enviar
System.out.println(nickname.toUpperCase(Locale.ROOT) + "\n" +
publicKey);
}
while (ligacao.isConnected()) {
try {
mensagemRecebida = in.readLine();
if (mensagemRecebida.equals("SESSION_UPDATE"))
{
model.getDataVector().removeAllElements();
model2.getDataVector().removeAllElements();
receberSessionUpdate();
} else if
(mensagemRecebida.equals("SESSION_TIME_OUT")) {
in.close();
out.close();
ligacao.close();
timer.cancel();
model.getDataVector().removeAllElements();
model2.getDataVector().removeAllElements();
model.fireTableDataChanged();
model2.fireTableDataChanged();
int dialogButton =
JOptionPane.showConfirmDialog(null, "Gostaria de se reconectar? ",
"voce foi desconectado", JOptionPane.YES_NO_OPTION);
if (dialogButton ==
JOptionPane.YES_OPTION) {
iniciar(false);
Timer timer2 = new Timer(); //
inicializamos o timer que vai fazer o SESSION_Update_request a cada
20s
inicarLoop(nickname, timer2);
receberMensagem();
} else {
dispose();
}
break;
} else {
}
} catch (IOException | NoSuchAlgorithmException e)
{
System.out.println("Erro ao comunicar com o
servidor ");
}
}
}
}).start();
} catch (IOException e) {
throw new RuntimeException(e);
}
//percorre o array de presenças e imprime o nickname dos
utilizadores online / o metodo conectar(...) retorna um array c os
nicknames todos
for (int i = 0; i < tamanhoPresencas; i++) {
try {
String mensagem = in.readLine(); // ler o que vêm do
socket
atualizarNicknamePublicKey(nick, publicKeyString);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
int tamanhoMensagens = 0;
try {
tamanhoMensagens = Integer.parseInt(in.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
for (int i = 0; i < tamanhoMensagens; i++) {
try {
model.addRow(new String[]{in.readLine()}); //listar na
tabela cada mensagem
} catch (IOException e) {
throw new RuntimeException(e);
}
}
connectBtn.setEnabled(false);
}
public ConfiguracoesCliente() {
setTitle("Configurações do Cliente");
setSize(700, 300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setContentPane(panel1);
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
}
});
}
@Override
public String sendMessage(String name, String message) throws
RemoteException {
tableModel.addRow(new String[]{name + ": " + message});
return nickname; // temos de retornar quem recebe a mensagem
}
return nickname;
}