correção de bugs

This commit is contained in:
GustavoHMDS committed 2026-10-09 13:51:06 -03:00
1 parent e25d3a425d
commit ab3840e4a4
8 files changed
+201 -33

No files matched your search

@@ -24,7 +24,7 @@ public class ConnectionManager {
private TcpManager tcpManager; private TcpManager tcpManager;
private SocketUDP socketUDP; private SocketUDP socketUDP;
private String username; private String username;
private InetAddress address; private final InetAddress address;
private int port; private int port;
public ConnectionManager(String username, PluginManager pluginManager, int port) throws UnknownHostException { public ConnectionManager(String username, PluginManager pluginManager, int port) throws UnknownHostException {
@@ -44,8 +44,12 @@ public class ConnectionManager {
return tcpManager.getClient(serverData, pluginId, username); return tcpManager.getClient(serverData, pluginId, username);
} }
public TcpServer getTcpServer(String pluginId) { public TcpServer getTcpServer(String serverName, String pluginId) {
return tcpManager.getServer(pluginId, username, address, port); return tcpManager.getServer(serverName, pluginId, username, address, port);
}
public void closeTcpServer(TcpServer tcpServer) {
tcpManager.closeServer(tcpServer);
} }
public boolean sendTcp(Message message, InetAddress destinationAddress) { public boolean sendTcp(Message message, InetAddress destinationAddress) {
+53 -6
View File
@@ -2,26 +2,33 @@ package pitiupi.models;
import java.io.Serializable; import java.io.Serializable;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Objects;
import java.util.UUID; import java.util.UUID;
public class ConnectionData implements Serializable { public final class ConnectionData implements Serializable {
private final UUID uuid; private final UUID uuid;
private final int port; private final int port;
private final String connectionName;
private final String ownerName; private final String ownerName;
private final InetAddress ownerAddress; private final InetAddress ownerAddress;
private final String plugin; private final String pluginId;
private final boolean isServer; private final boolean isServer;
public ConnectionData(String ownerName, InetAddress ownerAddress, String plugin, int port, boolean isServer) { public ConnectionData(String connectionName, String ownerName, InetAddress ownerAddress, String pluginId, int port, boolean isServer) {
uuid = UUID.randomUUID(); uuid = UUID.randomUUID();
this.port = port; this.port = port;
this.connectionName = connectionName;
this.ownerName = ownerName; this.ownerName = ownerName;
this.ownerAddress = ownerAddress; this.ownerAddress = ownerAddress;
this.plugin = plugin; this.pluginId = pluginId;
this.isServer = isServer; this.isServer = isServer;
} }
public UUID getUuid() { public UUID getUuid() {
return uuid; return uuid;
} }
@@ -29,16 +36,56 @@ public class ConnectionData implements Serializable {
public int getPort() { public int getPort() {
return port; return port;
} }
public String getConnectionName() {
return connectionName;
}
public String getOwnerName() { public String getOwnerName() {
return ownerName; return ownerName;
} }
public InetAddress getOwnerAddress() { public InetAddress getOwnerAddress() {
return ownerAddress; return ownerAddress;
} }
public String getPlugin() { public String getPluginId() {
return plugin; return pluginId;
} }
public boolean isServer() { public boolean isServer() {
return isServer; return isServer;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ConnectionData that = (ConnectionData) o;
if (port != that.port) return false;
if (!uuid.equals(that.uuid)) return false;
if (!connectionName.equals(that.connectionName)) return false;
if (!Objects.equals(ownerName, that.ownerName)) return false;
if (!Objects.equals(ownerAddress, that.ownerAddress)) return false;
if (!Objects.equals(pluginId, that.pluginId)) return false;
return isServer == that.isServer;
}
@Override
public int hashCode() {
return Objects.hash(
uuid,
port,
connectionName,
ownerName,
ownerAddress,
pluginId,
isServer
);
}
@Override
public String toString() {
return connectionName + ": " + pluginId;
}
} }
+5 -2
View File
@@ -15,11 +15,14 @@ public final class TcpClient extends TcpPitiupi {
ConnectionData serverData, ConnectionData serverData,
Socket socket, Socket socket,
DataInputStream input, DataInputStream input,
DataOutputStream output) DataOutputStream output
{ ) throws IllegalArgumentException {
super(socket, input, output); super(socket, input, output);
if (clientData == null) throw new IllegalArgumentException("clientData is null");
if (serverData == null) throw new IllegalArgumentException("ServerData is null");
this.clientData = clientData; this.clientData = clientData;
this.serverData = serverData; this.serverData = serverData;
} }
+16 -7
View File
@@ -4,24 +4,26 @@ import pitiupi.models.ConnectionData;
import java.io.*; import java.io.*;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
final class TcpFactory { final class TcpFactory {
private static final int HANDSHAKE_TIMEOUT = 1000; private static final int HANDSHAKE_TIMEOUT = 3000;
private static final int DISABLE_TIMEOUT = 0; private static final int DISABLE_TIMEOUT = 0;
TcpManager manager; private final TcpManager manager;
TcpFactory(TcpManager manager) { TcpFactory(TcpManager manager) {
this.manager = manager; this.manager = manager;
} }
TcpPitiupi createPitiupiConnection(InetAddress receiverAddress, int port) { TcpPitiupi createPitiupiConnection(InetAddress receiverAddress, int port) {
Socket socket = null; Socket socket = new Socket();
try { try {
socket = new Socket(receiverAddress, port); socket = new Socket(receiverAddress, port);
socket.connect(new InetSocketAddress(receiverAddress, port), HANDSHAKE_TIMEOUT);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
@@ -36,7 +38,7 @@ final class TcpFactory {
Logger.getLogger(TcpFactory.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(TcpFactory.class.getName()).log(Level.SEVERE, null, e);
} }
if (socket != null) tryClose(socket); tryClose(socket);
return null; return null;
} }
@@ -44,10 +46,12 @@ final class TcpFactory {
Socket socket = null; Socket socket = null;
try { try {
socket = new Socket(receiverAddress, port); socket = new Socket(receiverAddress, port);
socket.connect(new InetSocketAddress(receiverAddress, port), HANDSHAKE_TIMEOUT);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
ConnectionData clientData = new ConnectionData( ConnectionData clientData = new ConnectionData(
"Connection to " + serverData.getConnectionName() + " (" + serverData.getOwnerAddress() + ")",
username, username,
receiverAddress, receiverAddress,
pluginIdentifier, pluginIdentifier,
@@ -69,8 +73,9 @@ final class TcpFactory {
return null; return null;
} }
TcpServer createServer(String pluginIdentifier, String username, InetAddress receiverAddress, int port) { TcpServer createServer(String serverName, String pluginIdentifier, String username, InetAddress receiverAddress, int port) {
ConnectionData data = new ConnectionData( ConnectionData data = new ConnectionData(
serverName,
username, username,
receiverAddress, receiverAddress,
pluginIdentifier, pluginIdentifier,
@@ -112,12 +117,16 @@ final class TcpFactory {
} }
catch (IOException | ClassNotFoundException e) { catch (IOException | ClassNotFoundException e) {
Logger.getLogger(TcpFactory.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(TcpFactory.class.getName()).log(Level.SEVERE, null, e);
} try {
sendHandshakeResponse(false, dataOutputStream); sendHandshakeResponse(false, dataOutputStream);
}
catch (IOException e1) {
Logger.getLogger(TcpFactory.class.getName()).log(Level.INFO, null, e1);
}
tryClose(socket); tryClose(socket);
return null; return null;
} }
}
private void sendHandshake(DataOutputStream output, ConnectionData serverData, ConnectionData clientData) throws IOException { private void sendHandshake(DataOutputStream output, ConnectionData serverData, ConnectionData clientData) throws IOException {
TcpHandshake handshake = TcpHandshake.createPrivate(serverData, clientData); TcpHandshake handshake = TcpHandshake.createPrivate(serverData, clientData);
+69 -8
View File
@@ -5,6 +5,8 @@ import pitiupi.models.Messages.Message;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@@ -17,17 +19,23 @@ public final class TcpManager extends Thread{
private final TcpFactory tcpFactory; private final TcpFactory tcpFactory;
private final Map<ConnectionData, TcpServer> servers; private final Map<ConnectionData, TcpServer> servers;
// TODO: Atualizar a identificação das conexões públicas quando
// a identificação de usuário/processo for revisada.
// Atualmente, o mapa permite apenas uma conexão pública por endereço IP.
private final Map<InetAddress, TcpPitiupi> connections; private final Map<InetAddress, TcpPitiupi> connections;
private final List<TcpClient> clients;
private final ExecutorService connectionExecutor; private final ExecutorService connectionExecutor;
private final ServerSocket serverSocket; private final ServerSocket serverSocket;
private final Consumer<byte[]> handleMessage; private final Consumer<byte[]> handleMessage;
private boolean isRunning; private volatile boolean isRunning;
public TcpManager(int port, Consumer<byte[]> handleMessage) throws IOException { public TcpManager(int port, Consumer<byte[]> handleMessage) throws IOException {
servers = new ConcurrentHashMap<>(); servers = new ConcurrentHashMap<>();
connections = new ConcurrentHashMap<>(); connections = new ConcurrentHashMap<>();
clients = new ArrayList<>();
tcpFactory = new TcpFactory(this); tcpFactory = new TcpFactory(this);
@@ -37,20 +45,27 @@ public final class TcpManager extends Thread{
this.handleMessage = handleMessage; this.handleMessage = handleMessage;
} }
public TcpServer getServer(String pluginIdentifier, String username, InetAddress userAddress, int port) { public TcpServer getServer(String serverName, String pluginIdentifier, String username, InetAddress userAddress, int port) {
TcpServer tcpServer = tcpFactory.createServer(pluginIdentifier, username, userAddress, port); TcpServer tcpServer = tcpFactory.createServer(serverName, pluginIdentifier, username, userAddress, port);
servers.put(tcpServer.getConnectionData(), tcpServer); servers.put(tcpServer.getConnectionData(), tcpServer);
return tcpServer; return tcpServer;
} }
public TcpClient getClient(ConnectionData serverData, String pluginIdentifier, String username) { public TcpClient getClient(ConnectionData serverData, String pluginIdentifier, String username) {
return tcpFactory.createClient(serverData, pluginIdentifier, username, serverData.getOwnerAddress(), serverData.getPort()); TcpClient tcpClient = tcpFactory.createClient(serverData, pluginIdentifier, username, serverData.getOwnerAddress(), serverData.getPort());
if (tcpClient == null) return null;
clients.add(tcpClient);
return tcpClient;
} }
private TcpPitiupi createConnection(InetAddress receiverAddress, int port) { private TcpPitiupi createConnection(InetAddress receiverAddress, int port) {
TcpPitiupi tcpPitiupi = tcpFactory.createPitiupiConnection(receiverAddress, port); TcpPitiupi tcpPitiupi = tcpFactory.createPitiupiConnection(receiverAddress, port);
if (tcpPitiupi == null) return null;
manageConnectionList(tcpPitiupi, receiverAddress); manageConnectionList(tcpPitiupi, receiverAddress);
startConnectionReceiver(tcpPitiupi); startConnectionReceiver(tcpPitiupi);
@@ -58,8 +73,12 @@ public final class TcpManager extends Thread{
} }
public boolean send(Message message, InetAddress receiverAddress, int port) { public boolean send(Message message, InetAddress receiverAddress, int port) {
synchronized (connections) {
TcpPitiupi tcpPitiupi = findConnection(receiverAddress); TcpPitiupi tcpPitiupi = findConnection(receiverAddress);
if (tcpPitiupi == null || tcpPitiupi.isClosed()) tcpPitiupi = createConnection(receiverAddress, port); if (tcpPitiupi == null || tcpPitiupi.isClosed()) tcpPitiupi = createConnection(receiverAddress, port);
if (tcpPitiupi == null) return false;
try { try {
tcpPitiupi.send(message.toByteArray()); tcpPitiupi.send(message.toByteArray());
return true; return true;
@@ -69,6 +88,8 @@ public final class TcpManager extends Thread{
return false; return false;
} }
} }
}
private void receive() { private void receive() {
while (isRunning) { while (isRunning) {
Socket socket = null; Socket socket = null;
@@ -89,6 +110,7 @@ public final class TcpManager extends Thread{
} }
private void processConnection(Socket socket) { private void processConnection(Socket socket) {
connectionExecutor.submit(() -> {
try { try {
TcpPitiupi tcpPitiupi = tcpFactory.createFromReceiver(socket); TcpPitiupi tcpPitiupi = tcpFactory.createFromReceiver(socket);
@@ -96,17 +118,21 @@ public final class TcpManager extends Thread{
if (tcpPitiupi instanceof TcpClient client) { if (tcpPitiupi instanceof TcpClient client) {
ConnectionData serverData = client.getServerData(); ConnectionData serverData = client.getServerData();
TcpServer tcpServer = servers.get(serverData);
TcpServer tcpServer;
tcpServer = servers.get(serverData);
clients.add(client);
tcpServer.addClient(client); tcpServer.addClient(client);
} } else {
else {
manageConnectionList(tcpPitiupi, socket.getInetAddress()); manageConnectionList(tcpPitiupi, socket.getInetAddress());
startConnectionReceiver(tcpPitiupi); startConnectionReceiver(tcpPitiupi);
} }
} catch (IOException e) { } catch (IOException e) {
Logger.getLogger(TcpClient.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(TcpClient.class.getName()).log(Level.SEVERE, null, e);
} }
});
} }
public void closeManager() { public void closeManager() {
@@ -118,8 +144,29 @@ public final class TcpManager extends Thread{
Logger.getLogger(TcpManager.class.getName()).log(Level.WARNING, null, e); Logger.getLogger(TcpManager.class.getName()).log(Level.WARNING, null, e);
} }
for (TcpClient tcpClient : clients) {
try {
tcpClient.close();
}
catch (IOException e) {
Logger.getLogger(TcpManager.class.getName()).log(Level.WARNING, null, e);
}
}
for (TcpPitiupi tcpPitiupi : connections.values()) {
try {
tcpPitiupi.close();
}
catch (IOException e) {
Logger.getLogger(TcpManager.class.getName()).log(Level.WARNING, null, e);
}
}
servers.clear(); servers.clear();
clients.clear();
connections.clear(); connections.clear();
connectionExecutor.shutdown();
} }
public void closeServer(TcpServer tcpServer) { public void closeServer(TcpServer tcpServer) {
@@ -132,25 +179,39 @@ public final class TcpManager extends Thread{
private TcpPitiupi findConnection(InetAddress receiverAddress) { private TcpPitiupi findConnection(InetAddress receiverAddress) {
return connections.get(receiverAddress); return connections.get(receiverAddress);
} }
public TcpServer findServer(ConnectionData serverData) { public TcpServer findServer(ConnectionData serverData) {
return servers.get(serverData); return servers.get(serverData);
} }
private void manageConnectionList(TcpPitiupi tcpPitiupi, InetAddress receiverAddress) { private void manageConnectionList(TcpPitiupi tcpPitiupi, InetAddress receiverAddress) {
synchronized (connections) {
TcpPitiupi oldPitiupiConnection = connections.put(receiverAddress, tcpPitiupi); TcpPitiupi oldPitiupiConnection = connections.put(receiverAddress, tcpPitiupi);
if (oldPitiupiConnection != null) { if (oldPitiupiConnection != null) {
tcpFactory.tryClose(oldPitiupiConnection.getSocket()); tcpFactory.tryClose(oldPitiupiConnection.getSocket());
} }
} }
}
private void startConnectionReceiver(TcpPitiupi tcpPitiupi) { private void startConnectionReceiver(TcpPitiupi tcpPitiupi) {
connectionExecutor.submit(() -> { connectionExecutor.submit(() -> {
while (!tcpPitiupi.isClosed()) { while (!tcpPitiupi.isClosed()) {
try { try {
handleMessage.accept(tcpPitiupi.receive()); handleMessage.accept(tcpPitiupi.receive());
} catch (IOException e) { }
catch (IOException e) {
Logger.getLogger(TcpManager.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(TcpManager.class.getName()).log(Level.SEVERE, null, e);
break; break;
} }
finally {
connections.remove(tcpPitiupi.getSocket().getInetAddress());
try {
tcpPitiupi.close();
} catch (IOException ex) {
Logger.getLogger(TcpManager.class.getName()).log(Level.INFO, null, ex);
}
}
} }
}); });
} }
+33 -3
View File
@@ -2,19 +2,28 @@ package pitiupi.net.tcp;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
class TcpPitiupi { class TcpPitiupi {
private static final int MAX_MESSAGE_SIZE = 1_048_576;
protected final Socket socket; protected final Socket socket;
protected final DataInputStream input; protected final DataInputStream input;
protected final DataOutputStream output; protected final DataOutputStream output;
protected boolean isClosed;
public TcpPitiupi(Socket socket, DataInputStream input, DataOutputStream output) { public TcpPitiupi(Socket socket, DataInputStream input, DataOutputStream output) {
this.socket = socket; this.socket = socket;
this.input = input; this.input = input;
this.output = output; this.output = output;
this.isClosed = socket.isClosed();
} }
/** /**
@@ -27,9 +36,17 @@ class TcpPitiupi {
* @throws IOException se ocorrer um erro durante o envio * @throws IOException se ocorrer um erro durante o envio
*/ */
public void send(byte[] message) throws IOException { public void send(byte[] message) throws IOException {
if (message.length > MAX_MESSAGE_SIZE) throw new IOException("Oversized message");
try {
output.writeInt(message.length); output.writeInt(message.length);
output.write(message); output.write(message);
output.flush(); output.flush();
} catch (EOFException e) {
Logger.getLogger(TcpPitiupi.class.getName()).log(Level.INFO, null, e);
isClosed = true;
throw new IOException("Socket closed");
}
} }
/** /**
@@ -43,21 +60,34 @@ class TcpPitiupi {
* for encerrada antes que a mensagem seja completamente recebida * for encerrada antes que a mensagem seja completamente recebida
*/ */
public byte[] receive() throws IOException { public byte[] receive() throws IOException {
try {
int length = input.readInt(); int length = input.readInt();
if (length < 0) throw new IOException("Invalid message length."); if (length < 0 || length > MAX_MESSAGE_SIZE) throw new IOException("Invalid message length.");
byte[] message = input.readNBytes(length); byte[] message = input.readNBytes(length);
if (message.length != length) { if (message.length != length) {
throw new IOException("Connection closed before receiving the complete message."); Logger.getLogger(TcpPitiupi.class.getName()).log(Level.INFO, null, "Socket closed");
isClosed = true;
throw new IOException("Socket closed");
} }
return message; return message;
} }
catch (EOFException e) {
Logger.getLogger(TcpPitiupi.class.getName()).log(Level.INFO, null, e);
isClosed = true;
throw new IOException("Socket closed");
}
}
public boolean isClosed() { public boolean isClosed() {
return socket.isClosed(); if (socket.isClosed()) isClosed = true;
if (socket.isInputShutdown()) isClosed = true;
if (socket.isOutputShutdown()) isClosed = true;
return isClosed;
} }
Socket getSocket() { Socket getSocket() {
+12 -2
View File
@@ -29,13 +29,13 @@ public final class TcpServer {
clients.put(tcpClient.getClientData(), tcpClient); clients.put(tcpClient.getClientData(), tcpClient);
} }
public TcpClient receive() { public TcpClient receive() throws IOException {
try { try {
return buffer.take(); return buffer.take();
} }
catch (InterruptedException e) { catch (InterruptedException e) {
Logger.getLogger(TcpServer.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(TcpServer.class.getName()).log(Level.SEVERE, null, e);
return null; throw new IOException(e);
} }
} }
@@ -43,6 +43,16 @@ public final class TcpServer {
return clients.keySet().stream().toList(); return clients.keySet().stream().toList();
} }
public void removeClient(ConnectionData clientData) {
TcpClient client = clients.remove(clientData);
try {
client.close();
}
catch (IOException e) {
Logger.getLogger(TcpServer.class.getName()).log(Level.INFO, null, e);
}
}
public ConnectionData getConnectionData() { public ConnectionData getConnectionData() {
return connectionData; return connectionData;
} }
+6 -2
View File
@@ -33,14 +33,18 @@ public class Pitiupi {
return connectionManager.sendTcp(message, address); return connectionManager.sendTcp(message, address);
} }
public TcpServer openTcpServer(String pluginId) { public TcpServer openTcpServer(String serverName, String pluginId) {
return connectionManager.getTcpServer(pluginId); return connectionManager.getTcpServer(serverName, pluginId);
} }
public TcpClient connectToTcpServer(ConnectionData connectionData, String pluginId) { public TcpClient connectToTcpServer(ConnectionData connectionData, String pluginId) {
return connectionManager.connectToTcpServer(connectionData, pluginId); return connectionManager.connectToTcpServer(connectionData, pluginId);
} }
public void closeTcpServer(TcpServer tcpServer) {
connectionManager.closeTcpServer(tcpServer);
}
public String getUserName() { public String getUserName() {
return connectionManager.getUserName(); return connectionManager.getUserName();
} }