elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  C# - Problema en transferencia de datos con Sockets
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: C# - Problema en transferencia de datos con Sockets  (Leído 18,293 veces)
_LooSeR_

Desconectado Desconectado

Mensajes: 48



Ver Perfil
C# - Problema en transferencia de datos con Sockets
« en: 12 Marzo 2010, 21:42 pm »

Hola muy buenas!

Estoy desarrollando una aplicación cliente - servidor basada en sockets con Visual C# 2008 Express.

En una parte de la aplicación, quiero hacer un explorer muy básico, para poder navegar por los directorios del servidor y ver sus archivos.

Desde el servidor creo un Array de Strings, que contiene la ruta completa de los Directorios, o los Ficheros que están en una Ruta indicada.

Como desde el cliente no sé el tamaño de este Array, me envío antes un entero con la longitud de este, para luego poder recibirlo desde el cliente con un For.

El problema es que cuando recibo los "bytes" del entero en el cliente, no me llega un "10" por ejemplo, sino que me llega un "10C". Y evidentemente al pasar el string a int, me salta un error por que no tiene el formato adecuado.

Y aunque le pase la longitud bien (a mano), luego el cliente en el For que va leyendo las rutas que envía el servidor, las omite por completo, termina el método, y vuelve a obtener la longitud para otro listBox con los Archivos. Pero esta vez, para esta longitud, recibe los bytes del String "Ar" (Supongo que de "Archivos de programa", de los directorios que los había omitido anteriormente)

Estos son los códigos conflictivos:

Servidor
Código:
        private void ManageExplorer()
        {
            try
            {
                count = cliente.Receive(bytes);
                String miRuta = Encoding.ASCII.GetString(bytes, 0, count);

                if ((miRuta.Equals("")) || (miRuta==null))
                    miRuta = Directory.GetDirectoryRoot(Directory.GetCurrentDirectory());

                enviar_carpetas(miRuta);
                enviar_archivos(miRuta);
            }
            catch (SocketException) { }
        }

        private void enviar_carpetas(String ruta)
        {
            try
            {
                string[] carpetas = Directory.GetDirectories(ruta);

                //Enviar data con la longitud del array
                int longitud = carpetas.Length;
                bytes = Encoding.ASCII.GetBytes(longitud.ToString());
                cliente.Send(bytes);

                foreach (String carpeta in carpetas)
                {
                    //Enviar data de cada carpeta
                    bytes = Encoding.ASCII.GetBytes(carpeta);
                    cliente.Send(bytes);
                }
            }
            catch (SocketException){}
        }

        private void enviar_archivos(String ruta)
        {
            try
            {
                string[] archivos = Directory.GetFiles(ruta);

                //Enviar data con la longitud del array
                int longitud = archivos.Length;
                bytes = Encoding.ASCII.GetBytes(longitud.ToString());
                cliente.Send(bytes);

                foreach (String archivo in archivos)
                {
                    //Enviar data de cada archivo
                    bytes = Encoding.ASCII.GetBytes(archivo);
                    cliente.Send(bytes);
                }
            }
            catch (SocketException){}
        }



Cliente
Código:
        public void RunExplorer(String ruta, ListBox listBoxCarpetas, ListBox listBoxArchivos)
        {
            try
            {
                bytes = Encoding.ASCII.GetBytes("RunExplorer");
                servidor.Send(bytes);

                if (!ruta.Equals("") && ruta != null)
                    bytes = Encoding.ASCII.GetBytes(ruta);
                else
                    bytes = Encoding.ASCII.GetBytes("C:\\");

                servidor.Send(bytes);

                //Ahora recibimos los listados de carpetas y archivos
                RecibirDatosExplorer(listBoxCarpetas);
                RecibirDatosExplorer(listBoxArchivos);
            }
            catch (SocketException) { }
        }

        private void RecibirDatosExplorer(ListBox listBox)
        {
            try
            {
                //Recogemos la longitud del array
                count = servidor.Receive(bytes);
                data = Encoding.ASCII.GetString(bytes, 0, count);
                log.AppendText(data + "\n");
                int longitud = int.Parse(data);
                
                listBox.Items.Clear();
                
                //Recogemos tantos datos como la longitud del array
                for (int i = 0; i < longitud; i++)
                {
                    count = servidor.Receive(bytes);
                    listBox.Items.Add(Encoding.ASCII.GetString(bytes, 0 ,count));
                }
            }
            catch (SocketException) { }
        }


Todas las otras funciones que había puesto hasta ahora en mi programa, apenas tenían el envío de 2 paquetes de bytes desde el cliente al servidor.

Mi duda es si al hacer un Receive el programa se queda esperando, o si no tiene nada pasa de largo.

Si existe algún problema al ser ambos los que reciben y envían tan seguido.

Por que no entiendo como me salta el bucle y no me actualiza el listBox, ya que no me muestra nada.
Y porque recibo "10C" en la longitud en lugar de la longitud bien.

Un saludo y muchas gracias ;)


« Última modificación: 12 Marzo 2010, 22:24 pm por _LooSeR_ » En línea

[D4N93R]
Wiki

Desconectado Desconectado

Mensajes: 1.646


My software never has bugs. Its just features!


Ver Perfil WWW
Re: C# - Problema en transferencia de datos con Sockets
« Respuesta #1 en: 12 Marzo 2010, 22:41 pm »

Hola,
Bueno, una pregunta: Tienes que hacerlo con sockets? por qué no utilizas TcpListener/TcpClient con NetworkStream y un StreamReader/StreamWriter ...  así te ahorras un poco de trabajo...

En este tuto, que acabo de publicar, puedes ver como utilizar todas las clases que te dije.
http://foro.elhacker.net/net/tutorial_tcpip_sockets_c-t287407.0.html;new


De paso échale un ojo a este tutorial para que le agregues un toque de Threading, si es que ya no lo has hecho, claro está!

http://foro.elhacker.net/net/tutorial_iquestsystemthreading_iexclcomo_y_cuando_c-t277825.0.html

Espero te sirva de ayuda, sino, seguiremos intentándolo.

Saludos!


En línea

_LooSeR_

Desconectado Desconectado

Mensajes: 48



Ver Perfil
Re: C# - Problema en transferencia de datos con Sockets
« Respuesta #2 en: 12 Marzo 2010, 22:48 pm »

Ok muchas gracias ;)

La verdad había Leido algo de eso, pero encontré más informacion sobre sockets y lo intente así.

Con C# he empezado hace poco, ya que en la uni de lenguajes usados actualmente, prácticamente solo he llegado a ver Java... Di que no resulta dificil pasar de uno a otro

Un saludo y ya te comento!
En línea

[D4N93R]
Wiki

Desconectado Desconectado

Mensajes: 1.646


My software never has bugs. Its just features!


Ver Perfil WWW
Re: C# - Problema en transferencia de datos con Sockets
« Respuesta #3 en: 12 Marzo 2010, 22:53 pm »

Excelente, y bueno, fue muy buena tu decisión el pasarte a C# :D

Espero tu comentario..
En línea

raul338


Desconectado Desconectado

Mensajes: 2.633


La sonrisa es la mejor forma de afrontar las cosas


Ver Perfil WWW
Re: C# - Problema en transferencia de datos con Sockets
« Respuesta #4 en: 13 Marzo 2010, 00:28 am »

Mira, la verdad soy fanatico de los sockets y los uso aun en .net :P (salvo algunas exepciones en las que si uso clases, pero cuando se tratan de proyectos personales, uso socket puro)

En cuanto a si se queda esperando, se queda esperando hasta que reciba al menos un paquete de bytes. Para que se quede esperando y puedas hacer alguna otra cosa, puedes usar los metodos asincronicos BeginReceibe, que funcionan como eventos, y saltan cuando reciben algun paquete de bytes.

En cuanto al tamaño "10C", no se porque sera así, deberias revisar el array de bytes antes del envio y apenas se recibe ("en crudo") pero mi recomendacion es que el tamaño te lo envies por bytes y no por strings. Si vas a recibir una cadena de 400 bytes, recibe antes 2 bytes con los valores (255, 145) que recibir el ascii de "400" (3 bytes)

Bueno, a simple vista esta bien hecho. Ahora vere si te hago un ejemplo con sockets puro, y un "sistema de comandos" para que trabajes mejor con sockets
En línea

_LooSeR_

Desconectado Desconectado

Mensajes: 48



Ver Perfil
Re: C# - Problema en transferencia de datos con Sockets
« Respuesta #5 en: 15 Marzo 2010, 05:41 am »

Bueno he estado un rato cambiando la aplicación, para tener la conexión con las clases que me dijiste.

El caso es que me salta una excepción de los sockets:

"Solo se permite un uso de cada dirección de socket (protocolo/dirección de red/puerto)"

Tanto por el lado del cliente como por el del servidor, si antes ya he iniciado el otro.

La verdad no se por qué... Ejecutando el servidor instrucción a instrucción, se me queda escuchando con el
tcpListener.Start();  
socketForServer = tcpListener.AcceptSocket();

Arranco el cliente instrucción a instrucción, y justo cuando crea la instancia del nuevo TcpClient, me salta esa excepción, como diciendo que ese socket ya está usado por el servidor y el cliente no puede usarlo...

Como es el principio del codigo, en el constructor del cliente y servidor os pongo lo que tengo hasta ahora:

Servidor:

Código
  1.  
  2.                //Esto lo tengo porque me dice que el constructor TcpListener con sólo
  3.                //el puerto como parámetro está obsoleto, y hay que meterle una
  4.                //dirección, pero da problema de las dos formas, no es por esto.
  5.                //IPAddress localipAddress = IPAddress.Parse("127.0.0.1");
  6.                //TcpListener tcpListener = new TcpListener(localipAddress, port);
  7.  
  8.                TcpListener tcpListener = new TcpListener(port); //port = 25600
  9.                tcpListener.Start();
  10.  
  11.                log.AppendText("Esperando conexión del cliente...\n");
  12.  
  13.                socketForClient = tcpListener.AcceptSocket();
  14.                //Tras intentar ejecutar esta instrucción, si el cliente había sido ejecutado,
  15.                //salta la excepción


Cliente:
Código
  1.                IPAddress direc = IPAddress.Parse("127.0.0.1");
  2.                IPEndPoint IpEp = new IPEndPoint(direc, 25600);
  3.  
  4.                tcpClient = new TcpClient(IpEp);
  5.                //Tras ejecutar esta instrucción salta la excepción si el server se había ejecutado antes.
  6.  
  7.                while (!tcpClient.Connected)
  8.                {
  9.                    System.Threading.Thread.Sleep(5000);
  10.                    tcpClient.Close();
  11.                    tcpClient = new TcpClient(IpEp);
  12.                }

El while del cliente lo tengo para que siga intentando conectar, con sockets básicos era más sencillo, aqui me saltaba un error por tener ya abierto el tcpServer, también había probado en el bucle con tcpServer.Connect(IpEp) pero como tenia errores, he optado por cerrarlo y volver a crearlo, para que no de problemas con el problema que tengo en general.


Espero que sea una tonteria jeje, que el programa ya lo tengo cambiado del todo, y quiero ver si no me da el error antiguo que tenía al obtener el "int" de la longitud del array.


Gracias!

« Última modificación: 15 Marzo 2010, 06:02 am por _LooSeR_ » En línea

_LooSeR_

Desconectado Desconectado

Mensajes: 48



Ver Perfil
Re: C# - Problema en transferencia de datos con Sockets
« Respuesta #6 en: 15 Marzo 2010, 06:01 am »

Emmm arreglado...

He cambiado en la parte del cliente,

En vez de hacer un IpEndPoint con (ipaddress, puerto) y luego pasárselo al constructor de TcpClient

He puesto como tenías en el tutorial, nombre del host ("localhost") y puerto, y me ha conectado... Lo que no sé porqué, ya que se supone que el constructor también admite el IpEndPoint


El caso es que nada más ver que conectaba, me he metido a ver mi explorador, y funciona, pasa correctamente los parametros enteros, para las longitudes de los array.

Y me muestra las carpetas y archivos perfectamente.
En línea

_LooSeR_

Desconectado Desconectado

Mensajes: 48



Ver Perfil
Re: C# - Problema en transferencia de datos con Sockets
« Respuesta #7 en: 15 Marzo 2010, 18:32 pm »

Tengo una duda ahora, para enviar un fichero.

He visto ejemplos con sockets, pero no he encontrado nada con estas clases.

Hay alguna forma sencilla de hacerlo?

Si no, he visto que desde el objeto TcpClient, su atributo client es un socket, ya que en realidad por lo visto estas clases utilizan los sockets normales, pero con sus métodos te hacen algo más sencillo el trabajo.

Si no se pudiera, cogiendo ese socket "client" podría usar el método SendFile. Pero me gustaría saber si sabéis de otra forma.

Un saludo!
En línea

[D4N93R]
Wiki

Desconectado Desconectado

Mensajes: 1.646


My software never has bugs. Its just features!


Ver Perfil WWW
Re: C# - Problema en transferencia de datos con Sockets
« Respuesta #8 en: 15 Marzo 2010, 18:41 pm »

Para mandar un archivo por un socket soo tienes que tener el Stream del mismo y enviarlo utilizando Network Stream :D

Pero Claro, tienes que construir una especie de protocolo para enviar los archivos y sus metadatas. Ejm:

envias esto: [FileName]Documento.doc
                  [FileLength]52
y luego esto [FileData]<binario del archivo>

Algo asi .. :D
En línea

_LooSeR_

Desconectado Desconectado

Mensajes: 48



Ver Perfil
Re: C# - Problema en transferencia de datos con Sockets
« Respuesta #9 en: 15 Marzo 2010, 19:20 pm »

Ok, voy a echarle un vistazo. Es que con esto de los streams y tal ando un poco perdido xD

Entonces tendría que abrirme el fichero con un FileStream, hacerme un StreamReader con el stream del fichero para poder leer los datos de el. no?

Pero sería un BinaryReader, no? ya que según he leido el otro lee strings solamente.

Y luego esos datos obtenidos tendría que enviarlos a traves del network stream, con otro BinaryWriter asociado al NetworkStream?

Aver si he cogido la idea...  :rolleyes:

Saludos!
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
duda sobre transferencia de datos
PHP
JAJAcker 1 2,627 Último mensaje 10 Mayo 2011, 22:20 pm
por WHK
Transferencia de datos super lenta
Mac OS X
ipcres 4 11,005 Último mensaje 16 Julio 2011, 13:05 pm
por ipcres
Ayuda de transferencia de datos en ASP.NET
.NET (C#, VB.NET, ASP)
jacj0102 2 3,189 Último mensaje 5 Agosto 2011, 02:17 am
por jacj0102
Transferencia de datos de Pc a Pc
Dudas Generales
Zorronde 2 3,389 Último mensaje 25 Noviembre 2011, 16:55 pm
por zhyzura
Motorola Solutions invierte en drones con transferencia segura de datos en ...
Noticias
wolfbcn 0 1,049 Último mensaje 25 Marzo 2015, 21:25 pm
por wolfbcn
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines