Trasferir arquivos via socket

7 respostas
M

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.

7 Respostas

geovanebg

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

L

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,…

M

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…

L

Kd as threads?

M

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”.

L

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…

V

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. :?:

Criado 12 de setembro de 2008
Ultima resposta 2 de ago. de 2012
Respostas 7
Participantes 4