Java - Problema con sockets de Java

 
Vista:
sin imagen de perfil

Problema con sockets de Java

Publicado por Lorenzo (3 intervenciones) el 01/06/2017 09:44:43
Bueno gente, es la primera vez que comento en un foro como este pero no tengo otra opción más que acudir a la generosa comunidad.
Estoy haciendo un sistema cliente - servidor al cual, cuando un cliente se conecta, puede subir archivos, por el momento sólo de texto (varios por sesion, lo que implica que el codigo esta en un bucle), pero la idea es simple.
Como quiero que pueda haber más de un cliente a la vez, armo un Socket que vaya escuchando y levantando los diversos clientes en hilos.
Todo funciona perfecto, el cliente se conecta, sube su archivo. Pero luego, por algún motivo que no me puedo dar cuenta, una vez que se sube el primer archivo, invocando al método "Put" el socket se cierra.
Lo curioso de todo esto es que, dentro del método "Put", del lado del cliente, abro los file stream correspondientes y, al final del método, los cierro, pero, si comento el cierre de estos stream, el socket no se cierra, sigue funcionando pero no envía los archivos. A mi me resulta raro, por ahí la solución es tonta.
Ojalá puedan ayudarme. Acá dejo los códigos recortados para que no tengan que leer mucho.
Desde ya, muchísimas gracias por su tiempo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
SERVIDOR:
 
package Test;
 
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
 
public class Server {
    ServerSocket serverSocket;
    ServerSocket replicSocket;
    int	numClient;
 
    public Server(int port) throws IOException {
    	numClient = 0;
    	serverSocket = new ServerSocket(port);
        System.out.println("SERVIDOR: Servidor corriendo...");
        System.out.println("SERVIDOR: Esperando una conexion...");
        while(true){
        	new Thread (new ServerThread (serverSocket.accept(), numClient)).start();
        	numClient++;
       	}
	}
 
    public static void main(String a[]) throws IOException {
        Server server = new Server(8000);
    }
}
 
THREADS:
 
package Test;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;;
 
public class ServerThread implements Runnable{
	Socket clientSocket;
	PrintWriter outServer;
	BufferedReader inServer;
	int numClient;
 
	ServerThread (Socket clientSocket, int numClient){
		this.clientSocket = clientSocket;
		this.numClient = numClient;
	}
 
	@Override
	public void run() {
		System.out.println("SERVIDOR: Cliente conectado!");
		try {
			inServer = new BufferedReader (new InputStreamReader(clientSocket.getInputStream()));
			outServer = new PrintWriter (clientSocket.getOutputStream(), true);
			boolean bool = true;
			while(bool){
				String msj = inServer.readLine();
				switch (msj){
					case "1" :
						msj = inServer.readLine();
						put(clientSocket, msj);
						break;
					default :
						bool = false;
						System.out.println("Cerrando conexion con el cliente " + numClient + "...");
						break;
				}
			}
			inServer.close();
			outServer.close();
			clientSocket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
 
	private void put(Socket socket, String nomArchivo) throws IOException {
        	InputStream in = socket.getInputStream();
	        FileOutputStream out = new FileOutputStream(new File(".\\Archivos Servidor\\" + nomArchivo));
        	byte[] buf = new byte[1024];
	        int len;
        	while ((len = in.read(buf)) > 0)
	            	out.write(buf, 0, len);
        	in.close();
	        out.close();
	}
}
 
CLIENTE:
 
package Test;
 
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
 
public class Client {
	Socket clientSocket;
	PrintWriter outClient;
	BufferedReader inClient;
 
    public Client() throws UnknownHostException, IOException, ClassNotFoundException{
   		System.out.println("CLIENTE: Connectando...");
		clientSocket = new Socket("localhost",8000);
		System.out.println("CLIENTE: Conexion establecida");
		outClient = new PrintWriter (clientSocket.getOutputStream(), true);
		inClient = new BufferedReader (new InputStreamReader (clientSocket.getInputStream()));
		Scanner sc = new Scanner(System.in);
		boolean bool = true;
		while(bool){
			System.out.println("Menu: 1. Put - Otro. Exit: ");
			String op = sc.nextLine();
			outClient.println(op);
			switch (op){
				case "1" :
					System.out.println("Ingrese el nombre del archivo: ");
					op = sc.nextLine();
					outClient.println(op);
					put(clientSocket, op);
					break;
				default :
					bool = false;
					outClient.println("0");
					System.out.println("Cerrando cliente...");
					break;
			}
		}
		outClient.close();
		inClient.close();
		clientSocket.close();
    }
 
	private void put(Socket socket, String nomArchivo) throws IOException {
		FileInputStream in = new FileInputStream(new File(".\\Archivos Cliente\\" + nomArchivo));
        	FileOutputStream out = (FileOutputStream)socket.getOutputStream();
	        socket.sendUrgentData(100);
        	byte[] buf = new byte[1024];
	        int len;
        	while ((len = in.read(buf)) > 0)
	            out.write(buf, 0, len);
        	in.close();
	        out.close();
	}
 
	public static void main(String a[]) throws UnknownHostException, IOException, ClassNotFoundException {
        new Client();
    }
}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Problema con sockets de Java

Publicado por Tom (1831 intervenciones) el 01/06/2017 11:29:28
Es lógico. Si tienes un socket "cliente" conectado con un socket "server" cuando cierra las parte del cliente el server lo detectará (recibirás un error en las operaciones de lectura) y ese socket "server" ya será inválido, lo cerrarás tú o lo cerrará java por su cuenta.
O sea que si cierras el socket cliente tras enviar un archivo, debes establecer otra conexión para enviar el siguiente.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Problema con sockets de Java

Publicado por Lorenzo (3 intervenciones) el 01/06/2017 18:52:14
Si te fijás en el código, toda la ejecución del cliente se encuentra dentro de un while ya que la idea es poder hacer todas las transferencias de archivos deseadas en un solo socket. Del ciclo while se sale solamente si no se invoca al método "Put", de modo que, las instrucciones de cierre de los streams de entrada y salida, así como la del propio socket, se encuentran una vez que se salió del ciclo.
El socket se está cerrando por otro motivo y no puedo darme cuenta de cuál es.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Problema con sockets de Java

Publicado por Tom (1831 intervenciones) el 01/06/2017 21:20:19
¿ Por qué pìensas que no estás cerrando el socket ? Cada vez que terminas de enviar un fichero en el método put(), cierras el socket cliente.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Problema con sockets de Java

Publicado por Lorenzo (3 intervenciones) el 02/06/2017 01:33:17
public void close()
throws IOException

Closes this file input stream and releases any system resources associated with the stream.
If this stream has an associated channel then the channel is closed as well.

Es decir, cuando yo hago in.close() y out.close(), no sólo cierro los streams sino que también cierro el socket?
Eso no lo sabía!
Voy a intentar arreglarlo! Gracias!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar