Java - ¿cómo dividir un DatagramPacket ?

   
Vista:

¿cómo dividir un DatagramPacket ?

Publicado por Tomas (63 intervenciones) el 11/03/2016 23:41:44
Estoy programando un servidor TFTP en java el problema es que no puedo extraer el fileName del datagramPacket que envia el cliente, porque no puedo saber la longitud original del paquete que me envia, porque cuando el paquete llegua al servidor lo tendré que guardar en un datagrampacket con un buffer previamente definido (byte[] packet) en el servidor.
Me extrae el fileName + bytes que no me sirven.
Este es el codigo con problemas. No hace falta queponga lo demas. Pueden dar por hecho que el paquete llega al servidor. Para la compocición de paquetes me baso en http://i.stack.imgur.com/6dTH6.png, en este caso solo estoy trabajando con el primero y en modo "octet"
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
public void metodoData() throws IOException{
		byte[] packet = new byte[516];
 
		byte binariMode = (byte) "octet".length();
		DatagramSocket datagramSocket = new DatagramSocket(5000);
 
		//mientras reciba
		while (true) {
			boolean ackRecibidos=true;
			int i=0;
			DatagramPacket datagramPacket = new DatagramPacket(packet,packet.length);
			datagramSocket.receive(datagramPacket);
			System.out.println("servidor: llego un paquete!!:");
 
			//creamos un byte[] de la longitud original del contenido --> MENTIRA esto me da la longitud del paquete creado en la clase server
			byte[] inData = new byte[datagramPacket.getLength()];
			inData = datagramPacket.getData();
 
		System.out.println("el fichero mide "+inData.length);
 
			// comprobamos si es un paquete RRQ
			byte code;
			code = inData[1];
			System.out.println("servidor: codigo "+code);
 
			//si es una peticion de lectura
			if (code == RRQ) {
				System.out.println("servidor: Es un RRQ!!");
				String fileName = this.getFileName(inData);
				System.out.println(fileName);
 
 
}
 
//este metodo me lo copie de internet - me devuelve el fileName+valoresNulos , los valores nulos son el resto de bytes del byte[ ] packet 
public String getFileName(byte[] inData) {
		byte[] aux = new byte[inData.length - 7];
		for (int i = 0; i < aux.length; i++) {
		aux[i] = inData[i + 2];
	}
	return new String(aux);
}
Entonces en el metodo getFileName pensé en agregar un if que me detectara valores nulos (porsupuesto fracasé) y me devoliera el fileName nada mas detectar un valor nulo (sin el valor nulo).
1
2
3
4
5
6
7
8
9
10
11
12
public String getFileName(byte[] inData) {
		byte[] emptyByte = new byte[0];
		byte[] aux = new byte[inData.length - 7];
		for (int i = 0; i < aux.length; i++) {
			if(inData[i+2] != 0){
			aux[i] = inData[i + 2];
			}
	}
		System.out.println("server: el nombre del fichero mire: "+aux.length);
 
		return new String(aux);
}
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

¿cómo dividir un DatagramPacket ?

Publicado por Tom (911 intervenciones) el 12/03/2016 09:37:57
DatagramPacket.getLength() funciona como debe.
Tu problema está, probablemente, en que no usas correctamente DatagramPacket.setLength() al _enviar_ los paquetes.
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

¿cómo dividir un DatagramPacket ?

Publicado por Tomas (63 intervenciones) el 13/03/2016 18:34:06
No entiendo en que casos tengo que usar el DatagramPcket.setLenght, visto que en la clase server si hago un getLength va a ser del datagrampaquet que tengo credo en esa clase , no del que me llega del cliente. El que me llega del cliente lo tengo que guardar si o si en un predefinido en el servidor.
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

¿cómo dividir un DatagramPacket ?

Publicado por Tom (911 intervenciones) el 14/03/2016 11:38:42
¿ No sabes como funciona esto de los datagramas -UDP- ?
Un paquete, al transmitirse por la red, contiene información sobre su tamaño.
El emisor rellena un DatagramPacket con los datos que quiere enviar, e informa del tamaño a transmitir usando setLength().
En destino, cuando recibes un DatagramPacket recibes también su tamaño, que obtienes con getLength().
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

¿cómo dividir un DatagramPacket ?

Publicado por Tomas (63 intervenciones) el 14/03/2016 03:42:33
Solucionado. En lugar de buscar la longitud original del paquete recibido, le agregamos "\n" a la String del fileName en la clase cliente, entonces si leemos con un BufferedReader, nos guardará el fileName cuando encuentre un salto de linea.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public String getFileName(byte[] inData) throws IOException {
 
    //obtenemos un sub-array, desde la pocicion [2] (porque no queremos el opCode) hasta el final de inData
 
		byte[] b =Arrays.copyOfRange(inData, 2, inData.length);
 
		InputStream is = new ByteArrayInputStream(b);
		BufferedReader bf = new BufferedReader(new InputStreamReader(is));
 
    //leemos una palabra que se guardará en cuanto encuentre un "\n"
    (sumado previamente a la String del nombre del fichero que pide desde la clase cliente)
 
		String filename = bf.readLine();
		bf.close();
		is.close();
		System.out.println("server: el nombre del fichero mide: "+filename.length());
		return filename;
}
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