perdón que me cuelgue tan tarde de estos mails, pero hay un problema que suele ser bastante común y que no encuentro en la cadena de mails que lo hayas verificado.
cuando vos ejecutás: sw.ReadLine(); (y entiendo que 'sw' es un error de tipeo) la clase espera encontrar un "\r\n" en el stream para dar por completa una línea. ¿Tenés por seguro que del otro lado están enviando esto? C.S. Original Message: ----------------- From: Carlos Peix [email protected] Date: Wed, 1 Jul 2009 08:39:24 -0300 To: [email protected] Subject: [puntonet] TcpClient envio y recepcion de mensajes Hola Marcel, Perdona que no conteste tus preguntas en forma exacta, me resulta mas facil exponer las ideas como me vienen, de todas maneras creo que estan tratadas todas tus inquietudes, caso contrario, consulta de nuevo en forma especifica. Definitivamente es necesario que sepas cual es el "protocolo" de comunicacion, esto es, la documentacion que establace como enviar los mensajes al servidor y como el servidor te los envia. En este protocolo debe definirse el "mensaje" que usualmente tiene una estructura definida, por ejemplo: * secuencia de inicio de mensaje (uno o mas caracteres o bytes) * cuerpo del mensaje * secuencia de fin de mensaje (uno o mas caracteres o bytes) En algunos casos el cuerpo de mensaje se divide en una seccion header, con estructura fija y una seccion que le sigue cuya interpretacion depende de los valores del header pero asumo que tu caso es mas sencillo. Entonces, seguro necesitas saber con que caracteres se limitan los mensajes de ida y de vuelta. Esto es necesario ya que, de otra manera, seria imposible identificar los mensajes en el stream continuo del socket. Cambiando de tema, en cuanto a la implementacion, la division de sockets en sincronicos o asincronicos se refiere a si tu codigo se bloquea (sincronico) o no (asincronico) mientras el mensaje se envia entre los sockets del cliente y del servidor. Esto es a nivel de TCP/IP y no tiene nada que ver con el tiempo que demore el servidor en responder un mensaje recibido. El tiempo entre sockets es del orden de los milisegundos en una red LAN mientras que el servidor, una vez recibido el mensaje, puede tardar muchos segundos en procesar y responder. Creo que para empezar y si estas en una red confiable, rapida y de baja latencia (tipicamente una LAN o red local) y si, ademas, el trafico no es intenso, podes trabajar con sockets sincronicos. Luego viene un nivel superior, la capa de aplicacion. Segun decis, tu aplicacion, una vez que envia el mensaje se queda esperando (bloqueada) la respuesta. Esto es un comportamiento sincronico de nivel superior al que comente en el parrafo anterior. Creo que un comportamiendo sincronico a esta nivel es mucho mas riesgoso y no te va a servir para construir un servicio confiable. Carlos Peix _____ De: [email protected] [mailto:[email protected]] En nombre de Marcel Felix Enviado el: Martes, 30 de Junio de 2009 08:36 p.m. Para: [email protected] Asunto: [puntonet] Re: [puntonet] RE: [puntonet] TcpClient envío y recepcion de mensajes Hola Carlos, gracias por la respuesta. Estoy viendo los links. La aplicacion cliente que tengo ahora ya tiene implementado un thread para recibir los mensajes del Servidor. Para el envío de mensajes, utilizo un timer que se repite cada x segundos. Esto lo hago asi porque necesito hacer una cola de espera con las peticiones de mi cliente al servidor, de manera que solo haya una petición a la vez.. Utilizo un objeto tcpclient y ya cambié de utilizar streamwriter y streamreader a Networkstream para mandar la informacion como arreglos de bytes. La primera duda que tengo es con la cuestión de, si utilizar métodos sincronos o asincronos. Hasta ahorita no he usado métodos asincronos porque requiero esperar la respuesta del servidor forzosamente para poder continuar con el procesamiento en mi programa. Un caso simple de lo que hago es que mando una solicitud de eco y tengo que esperar a que el servidor me regrese el mensaje para poder continuar. Mientras mi programa espera por la respuesta, no tengo necesidad de hacer otras cosas. ¿En este tipo de escenario es conveniente mantenerme con métodos síncronos? Por otro lado. Como comentaba en mi mensaje anterior, yo solo tengo que implementar el cliente. No sé cómo esté implementado el servidor. No sé en qué lenguaje esté desarrollado, tampoco sé cómo es que tiene implementado el envio y recepción de mensajes (si usan streams, networkstreams, si envian y reciben las cadenas de texto o los arreglos de bytes, en una sola instrucción o de uno en uno). El hecho de implementar métodos sincronos o asincronos en el cliente ¿lo determina en mayor o menor medida la manera en que estén implementados los métodos en el servidor? ¿Tengo que saber de antemano como envia y recibe datos el servidor? O bien, mientras haya información en el stream, ¿da igual cómo se acceda a esa información? Es decir, si el servidor me mandase la información de un byte a la vez, y yo uso el método read del networstream ¿eso no ocasiona problemas? Todo esto lo pregunto porque sospecho que podría estar relacionado con el hecho de que puedo enviar mensajes pero no veo lo que me mandan. En mi entorno de pruebas, como yo desarrolle tanto el cliente como el simulador del servidor, todo funciona muy bien, pero nada más me conecté al servidor, y empezó el problema De cualquier manera, hablaré con la gente que tiene levantado el servidor para ver si pueden y/o quieren platicarme algunos detalles de su implementación. Te agradecería infinitamente si pudieses comentar algo de todo esto que me inquieta. ¡Gracias! El 29 de junio de 2009 18:42, Carlos Peix <[email protected]> escribió: Hola Marcel, Lo primero que me surge decirte es que vas a tener que dedicar un buen tiempo a aprender sobre threads, sockets, metodos asincronicos y demas temas relacionados. No es facil implementar comunicacion por sockets solida. Luego, mas que ayudarte con tu consulta, te refiero estos articulos que a mi me sirvieron bastante. // Asynchronous Client Socket Example // http://msdn2.microsoft.com/en-us/library/bew39x2a(VS.71).aspx // Using an Asynchronous Client Socket // http://msdn2.microsoft.com/en-us/library/bbx2eya8(VS.71).aspx // Asynchronous Server Socket Example // http://msdn2.microsoft.com/en-us/library/fx6588te(VS.71).aspx // Using an Asynchronous Server Socket // http://msdn2.microsoft.com/en-us/library/5w7b7x5f(VS.71).aspx // http://www.csharphelp.com/archives3/archive486.html Hay dos maneras de implementar lo que vos queres hacer, una de mas alto nivel usando TcpClient y TCPListener y otra usando Socket directamente. Yo cai en la segunda porque la primera me limitaba y no era eficiende con trafico elevado. Suerte Carlos Peix _____ De: [email protected] [mailto:[email protected]] En nombre de Marcel Felix Enviado el: Lunes, 29 de Junio de 2009 08:32 p.m. Para: [email protected] Asunto: [puntonet] TcpClient envío y recepcion de mensajes Hola a todos. Les platico el problema. Tengo una aplicación de consola hecha en c# que funciona como cliente de un Servidor remoto el cual no tengo idea de cómo esté programado, pero sé que recibe peticiones en un puerto de un socket. Mi aplicación al iniciar crea un objeto tcpClient que abre una conexión con el servidor y envía como mensajes cadenas de texto plano. Hasta aqui no hay problema. Mando mi mensaje y el servidor lo recibe. El envío de mensajes lo hago a través de un streamwriter, mediante una función que se llama EnviarMensaje : StreamWriter sw; sw = new streamWriter(tcpClient.getStream()); sw.WriteLine(mensaje) sw.flush(); Para la recepción de los mensajes que me manda el servidor, he creado un streamReader que lee los datos del mismo stream del tcpClient. Algo como; StreamReader sr; sr = new StreamReader(tclClient.getStream()); string respuesta = sw.ReadLine(); El envío de mensajes funciona ok. El problema es que no recibo los mensajes que me manda el servidor. La recepción de mensajes del servidor se hace en un thread que dentro de un ciclo while (mientras esté conectado), debe guardar en un string lo que obtenga de sr.ReadLine(); Esta aplicación funciona bien en mi entorno de desarrollo, junto con una aplicación de prueba que hice para simular al servidor real al que tengo que conectarme. El problema surgió ahora que ya tuve que conectarme al servidor real. Recibe mis mensajes pero mi aplicación no recibe los del servidor. Parece que nunca se cumple la condición while(conected) ¿cómo es posible que todo funcione sin problemas en mi entorno y no reciba nada cuando intento comunicación con el servidor real? Un detalle es que sí recibí las respuestas del servidor, pero solo hasta que la aplicación del servidor se cerró, ¿No es correcto que use el mismo tcpclient para leer y escribir del Stream? ¿Tendría que tener en mi aplicación cliente un tcpListener para recibir los mensajes? Pero si así fuera, no tendría que funcionar tampoco en mi entorno de prueba ¿o si? ¿y por que funcionaría solo cuando la aplicación remota se cierra? Gracias de antemano. -------------------------------------------------------------------- mail2web.com - Microsoft® Exchange solutions from a leading provider - http://link.mail2web.com/Business/Exchange
