Socket Error - Sistema de Cloud

Estou a tentar fazer um sistema de cloud pessoal. Ao tentar pedir ao servidor uma lista dos ficheiros no armazenamento recebo este erro:

java.net.SocketException: Socket is closed
	at java.net.Socket.getInputStream(Socket.java:903)
	at me.mauro.m4cloud.client.CloudClient.listarArquivos(CloudClient.java:122)
	at me.mauro.m4cloud.client.ClientUI.jPanel3MouseClicked(ClientUI.java:179)
	at me.mauro.m4cloud.client.ClientUI.access$500(ClientUI.java:14)
	at me.mauro.m4cloud.client.ClientUI$6.mouseClicked(ClientUI.java:122)
	at java.awt.Component.processMouseEvent(Component.java:6538)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
	at java.awt.Component.processEvent(Component.java:6300)
	at java.awt.Container.processEvent(Container.java:2236)
	at java.awt.Component.dispatchEventImpl(Component.java:4891)
	at java.awt.Container.dispatchEventImpl(Container.java:2294)
	at java.awt.Component.dispatchEvent(Component.java:4713)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4534)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
	at java.awt.Container.dispatchEventImpl(Container.java:2280)
	at java.awt.Window.dispatchEventImpl(Window.java:2750)
	at java.awt.Component.dispatchEvent(Component.java:4713)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.awt.EventQueue$4.run(EventQueue.java:731)
	at java.awt.EventQueue$4.run(EventQueue.java:729)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Servidor:

			System.out.println("Recebendo um pedido de lista de arquivos: " + client.getInetAddress().getHostAddress());
			File[] files = new File(PATH_ARMAZENAMENTO).listFiles();
			StringBuilder filesName = new StringBuilder();
			for (File file : files) {
				filesName.append(file.getName());
				filesName.append(", ");
			}
			PrintStream ps = new PrintStream(client.getOutputStream());
			ps.println(filesName.toString());
			ps.close();

Cliente:

public String[] listarArquivos() {
    if (!iniciarCliente()) {
        JOptionPane.showMessageDialog(null, "Não foi possivel estabelecer conxeão com o servidor", "M4CLOUD", JOptionPane.ERROR_MESSAGE);
        return new String[]{"Não foi possivel estabelecer conxeão com o servidor"};
    }
    Ficheiro ficheiro = new Ficheiro();
    ficheiro.setTipo(Ficheiro.LISTA_ARQUIVOS);

    try {
        try (ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream())) {
            oos.writeObject(ficheiro);
        }
        try (Scanner scanner = new Scanner(client.getInputStream())) {
            String[] arquivos = (String[]) scanner.nextLine().split(", ");
            client.close();
            return arquivos;
        }
    } catch (IOException ex) {
        Logger.getLogger(CloudClient.class.getName()).log(Level.SEVERE, null, ex);
    }
    return new String[]{"Não foram encontrados arquivos"};
}

Linha do Erro: try (Scanner scanner = new Scanner(client.getInputStream()))

vamos la

o seu servidor esta listando arquivos em um string builder e so depois de listar todos vc manda escrever no stream do cliente.

seu cliente aparentemente conecta mas na hora de ler vc recebe um Socket is closed

eu acho que, OU vc nunca conectou, OU vc demora tanto para listar pois esta escrevendo no string buffer e depois no stream que o cliente desconecta por inatividade.

precisa ver como vc esta conectando.

nao ha necessidade desse string buffer. vc vai colocar coisas em memoria pra depois escrever no stream. escreve direto no stream ou talvez considerar usar um BufferedOutputStream

sem ver mais detalhes da implementação fica dificil

1 curtida

Que detalhes da implementação precisa ver?

ah entendi

existe uma diferença entre try{} e try()

o try(expressao) vai chamar o metodo close dessa expressao no final.

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

ai vc pega o outputstream do seu client (presumo q seja um socket) e cria um ObjectOutputStream.

com try() isso vai chamar o close o stream q vai fechar o output stream do socket. e vai fechar o socket

https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#getOutputStream()

public OutputStream getOutputStream()
                             throws IOException
Returns an output stream for this socket.
If this socket has an associated channel then the resulting output stream delegates all of its operations to the channel. If the channel is in non-blocking mode then the output stream's write operations will throw an IllegalBlockingModeException.

Closing the returned OutputStream will close the associated socket.

sugestao: feche o socket no final de forma explicita, nao use try with resources a menos q vc saiba o q esta fazendo. faça uso de finally se precisar

Muito obrigado. Funcionou!!!