Trasferir arquivos via socket

Bom dia, estou tentando trasferir arquivos via sockets, consultei vários tópicos aqui do forum sobre trasferência de arquivos via sockets, todos eles trasferem apenas um arquivo e fecham a conexão. Eu preciso de um servidor, que envie um arquivo que o cliente pedir, e continue ativo, esperando mais requisições de clientes. Mas quando tento fazer isso, só da certo a primeira trasferência de arquivo, quando o cliente pede o segundo arquivo é lançada um exception informando que o socket está fechado ( logo na linha em cima de onde deu a exception, fiz um teste socket.isConnected () e a resposta foi true! )

Nesse caso, ao terminar a trasferencia do primeiro arquivo, devo fechar o fluxo? Devo fechar o DataInputStream do Cliente e o DataOutputStream do server? Mesmo fechando os fluxos ( usando closed ) e instanciando novos, sempre na tranferencia do segundo arquivo, é lançada um excessão quando tento utilizar novamente o fluxo…

Desde já agradeço, Felipe.

Mande o código da sua classe ae pra gente ver melhor.

Tem que utilizar threads para isso…

Tipo… um servidor fica lendo uma porta…
Quando o cliente acessa o servidor, é lançada uma thread do servidor para atender o cliente e retorna a esperar outro cliente,…

Já estou usando Threads, e já fiz varios testes, consigo conectar com vários clientes. Acredito que o problema esteja na trasferencia do aruivo, só consgio enviar um arquivo para cada cliente. Aqui está uma parte da lógica do server:

while ( true )
		{
			System.out.println("Inicio do Servidor...");
		
			try
			{
				
				System.out.println("Status do Socket: " + cliente.isConnected());
				
				DataInputStream input = new DataInputStream ( cliente.getInputStream() );
				String fileName = input.readUTF();
				
				System.out.println("Nome de arquivo recebido: " + fileName );
				
				File file = new File ( fileName );
				
				BufferedOutputStream output = new BufferedOutputStream ( cliente.getOutputStream() );
				
			                BufferedInputStream in = new BufferedInputStream( new FileInputStream (fileName) );   
			                byte[] buf = new byte[ 512 ];   
			         
			                while( true ) 
			               {   
			   
			    	    int len = in.read(buf);
			    	    if ( len == -1 ) break;
			    	  
			                    output.write(buf, 0, len ); 
			       
			              } 
			      
			              System.out.println("Arquivo enviado pelo server");
			           
			              output.flush();
			              output.close();
			}
			
			catch ( IOException e )
			{
				e.printStackTrace();
                                                                break;

                                                }

Esse é um trecho do server, que esta num laço…A primeira iteração no laço corre tudo bem, a segunda não consegue instanciar um novo fluxo…É lançada um excessão da instanciaçao do DataInputStream ( Socket is closed ).

Aqui está a parte do cliente que requisita e recebe um arquivo:

public void receberArquivo ( File file )
	{
		try 
		{
			System.out.println("Início de recebeimnto de arquivos!");
			System.out.println("Status socket: "+ socket.isConnected() );
			
			DataOutputStream output = new DataOutputStream ( socket.getOutputStream() );
			String fileName = new String ( file.getAbsolutePath() );
			output.writeUTF (fileName);
			
			System.out.println("Nome do Arquivo Enviado!!");
			
			BufferedInputStream input = new BufferedInputStream ( socket.getInputStream() );
			
			BufferedOutputStream fos = new BufferedOutputStream ( new FileOutputStream( this.diretorioDeDownloads + "\\" + file.getName()))   ;
		    byte[] buf = new byte[ 512 ];   
		      
		    while(true) 
		    {   
		         int len = input.read(buf); /
		         
		         if( len == -1  ) 
		         {	 
		        	 break;   
		         }
		         
		         fos.write(buf, 0, len);   
		         
		    }   
		    
		    fos.flush();   
		    fos.close();   
		    
		    output.flush();
		    //output.close();
		    //input.close();
		    
		    System.out.println("Trasferencia concluída.");   
		} 

O Cliente também gera a mesma exception ao instanciar pela segunda vez o DataOutputStream…

Kd as threads?

Resolvei fazer um programa menor e simples para testar o erro, e descobri que o Closed de um fluxo faz o socket fechar. Vejam esse código:

Server:

public class Server 
{

	public Server() 
	{
		try 
		{
			ServerSocket server = new ServerSocket (8080);
			Socket cliente = server.accept();
			
			System.out.println("Server conectado ao cliente!");
			
			while ( true )
			{
				ObjectInputStream in = new ObjectInputStream ( cliente.getInputStream() );
				String texto = in.readUTF ();
				
				System.out.println("String recebida: " + texto );
				
				in.close();
			}

		}
	 	
		catch (IOException e) 
		{
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		Server s = new Server ();

	}

Cliente:

public class Client {

	public Client() 
	{
		try 
		{
			Socket socket = new Socket ("Val", 8080);
			System.out.println("Cliente Conectado....");
			
			start ( socket );
			
		} catch (UnknownHostException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	public void start ( Socket s )
	{
		for ( int i = 0; i < 10; i++ )
		{
			try 
			{
				ObjectOutputStream out = new ObjectOutputStream ( s.getOutputStream() );
				out.writeUTF("Desejo enviar " +  i);
				System.out.println("Enviado!");
				
				out.close();
			} 
			catch (IOException e) 
			{
				e.printStackTrace();
			}
			
		}
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Client client = new Client ();
		
	}

Queria saber porque esse código não funciona…So consigo receber 1 valor do cliente…depois disse é lançada a excessão Socket is closed. Alguém sabe porque?

PS:Na classe client é preciso colocar o nome do computador no construtor, no lugar de “Val”.

kd as threads no servidor???
Claro que não vai dar…
Quando vc aceita um cliente no servidor, tem que lançar uma thread para tratar das requisições do cliente… e não tratar na thread principal do servidor… senão quando o cliente encerrar a conexão, vai encerrar o socket da thread principal do servidor…

leopoldof ,
Como poderia resolver utilizando threads? Ainda estou pegando o conceito de thread, e tenho um problema parecido com este, consigo fazer a primeira requisição mas a partir daí é retornado socket closed. :?: