Autor
|
Tema: C# - Problema en transferencia de datos con Sockets (Leído 18,929 veces)
|
_LooSeR_
Desconectado
Mensajes: 48
|
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 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 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
|
|
|
|
|
_LooSeR_
Desconectado
Mensajes: 48
|
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
Mensajes: 1.646
My software never has bugs. Its just features!
|
Excelente, y bueno, fue muy buena tu decisión el pasarte a C# Espero tu comentario..
|
|
|
En línea
|
|
|
|
raul338
Desconectado
Mensajes: 2.633
La sonrisa es la mejor forma de afrontar las cosas
|
Mira, la verdad soy fanatico de los sockets y los uso aun en .net (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
Mensajes: 48
|
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: //Esto lo tengo porque me dice que el constructor TcpListener con sólo //el puerto como parámetro está obsoleto, y hay que meterle una //dirección, pero da problema de las dos formas, no es por esto. //IPAddress localipAddress = IPAddress.Parse("127.0.0.1"); //TcpListener tcpListener = new TcpListener(localipAddress, port); TcpListener tcpListener = new TcpListener (port ); //port = 25600 tcpListener.Start(); log.AppendText("Esperando conexión del cliente...\n"); socketForClient = tcpListener.AcceptSocket(); //Tras intentar ejecutar esta instrucción, si el cliente había sido ejecutado, //salta la excepción
Cliente: IPAddress direc = IPAddress.Parse("127.0.0.1"); IPEndPoint IpEp = new IPEndPoint (direc, 25600); tcpClient = new TcpClient (IpEp ); //Tras ejecutar esta instrucción salta la excepción si el server se había ejecutado antes. while (!tcpClient.Connected) { System.Threading.Thread.Sleep(5000); tcpClient.Close(); tcpClient = new TcpClient (IpEp ); }
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
Mensajes: 48
|
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
Mensajes: 48
|
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
Mensajes: 1.646
My software never has bugs. Its just features!
|
Para mandar un archivo por un socket soo tienes que tener el Stream del mismo y enviarlo utilizando Network Stream 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 ..
|
|
|
En línea
|
|
|
|
_LooSeR_
Desconectado
Mensajes: 48
|
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... Saludos!
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
duda sobre transferencia de datos
PHP
|
JAJAcker
|
1
|
2,733
|
10 Mayo 2011, 22:20 pm
por WHK
|
|
|
Transferencia de datos super lenta
Mac OS X
|
ipcres
|
4
|
11,196
|
16 Julio 2011, 13:05 pm
por ipcres
|
|
|
Ayuda de transferencia de datos en ASP.NET
.NET (C#, VB.NET, ASP)
|
jacj0102
|
2
|
3,361
|
5 Agosto 2011, 02:17 am
por jacj0102
|
|
|
Transferencia de datos de Pc a Pc
Dudas Generales
|
Zorronde
|
2
|
3,579
|
25 Noviembre 2011, 16:55 pm
por zhyzura
|
|
|
Motorola Solutions invierte en drones con transferencia segura de datos en ...
Noticias
|
wolfbcn
|
0
|
1,170
|
25 Marzo 2015, 21:25 pm
por wolfbcn
|
|