![]() |
![]() |
![]() |
![]() |
![]() |
FTP | ![]() |
![]() |
CCD | ![]() |
![]() |
Buscar | ![]() |
![]() |
Trucos | ![]() |
![]() |
Trabajo | ![]() |
![]() |
Foros | ![]() |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Buscar | Temas de Hoy | Marcar Foros Como Leídos |
![]() |
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
||||
|
||||
Usar TServerSocket y TClientSocket para enviar "streams" más o menos "grandes"
Hola,
Por favor, ¿alguien podría proporcionarme un ejemplo de cómo usar los componentes "TServerSocket" y "TClientSocket" para enviar y recibir "streams" más o menos "grandes"? Hablo de enviar un "stream" que no pueda enviarse de una sola vez, en un sólo paquete "TCP/IP", sino que, necesariamente, haya que tratar (como parece exigir dicho protocolo) dicho "stream" con el cuidado correspondiente, tanto a la hora de enviarlo como de recibirlo. Estoy usando estos componentes en uno de mis proyectos, pero, al limitarme a usar los métodos "SendText" y "ReceiveText" de los "Sockets", ahora me encuentro conque no tengo ni idea de cómo hacer para enviar cadenas de texto "grandes", tal vez en un "MemoryStream" o "StringStream". Comprendo el problema, he buscado soluciones, pero, al cabo no consigo algo que funcione y que me permita implementarlo en mi proyecto. Ya, ya sé que yo mismo podría hacer que funcionase,... pero me temo que a esto no llego... ![]() ¿Alguien se acuerda de tener guardado por ahí algún ejemplo que envíe y reciba archivos, por ejemplo, y donde se usen estos componentes? Cualquier otra ayuda sería bien recibida, puesto que tengo que encontrar una solución para este asunto, y, pienso que lo del ejemplo podría ser ideal (claro, algo que funcione... debe ser sencillo de hacer funcionar en otro lugar), pero, no por ello dejaré de buscar (como ya he hecho) otras posibles soluciones. Así que si no es un ejemplo pero se os ocurre cualquier otra cosa, por favor, no dejéis de comentarla. Muchas gracias de antemano a todos. |
#2
|
||||
|
||||
Hola dec.
Te aclaro que mis roces con ClientSocket y ServerSocket no pasaron de una prueba hace algunos años. ![]() Por si alguno se te escurrió, encontré estos enlaces que me parecieron tener relación con el asunto:
Saludos ![]()
__________________
Daniel Didriksen Guía de estilo - Uso de las etiquetas - La otra guía de estilo .... |
#3
|
||||
|
||||
Hola,
Cita:
![]() |
#4
|
||||
|
||||
Hola,
Sigo liado con este asunto. Finalmente, parece que he conseguido algo que funciona relativamente bien. Me he limitado a copiar y pegar cierto código de Remy Lebeau, para qué vamos a engañarnos. Yo creo comprender "el conceto", pero, no soy capaz de implementar una solución por mí mismo. Ahora bien, el caso es que parece que ahora sí puedo enviar y recibir grandes cadenas de texto, de hecho cadenas de texto de más de 100 MB... Aunque realmente esto no ha solucionado mi problema (porque mi proyecto es una DLL que funciona en una aplicación de terceros, y, aunque yo consigo enviar estas grandes cadenas de texto en la aplicación de Delphi que uso para las pruebas, el mismo código no funciona de la misma manera en dicha DLL -cuelga la aplicación si se envían digamos que más de 200 KB) me gustaría que echárais un vistazo a la aplicación de pruebas hecha en Delphi. El objetivo de subir dicha aplicación de pruebas aquí es, sobre todo, que podáis echar un vistazo a dos métodos en particular: 1º TMainForm.SendFromClientButtonClick() 2º TMainForm.ServerClientRead() El primer método envía la cadena de texto, teniendo en cuenta que acaso no pueda hacerse de una vez. Al mismo tiempo envía la cadena añadiendo al final de esta una especie de "token" (los caracteres #6#7) que después utilizaremos en el segundo método, de manera que podamos "leer" hasta llegar al final de la cadena, identificado por dichos caracteres. Me interesa de veras que echéis un vistazo y acaso podáis decirme si existe alguna forma de mejorar dichos métodos, puesto que de este modo pueda lograr que dicho código fuente en mi proyecto de mejor manera. Me preocupa especialmente la siguiente línea del primer método:
En efecto, el código original de Remy era tal que así:
Sin embargo, si dejo dicho código tal cual se produce el error: Código:
[DCC Error] UMainForm.pas(225): E2197 Constant object cannot be passed as var parameter Para probar la aplicación que adjunto no tenéis sino compilarla y ejecutarla dos veces: la misma aplicación puede hacer de servidor y de cliente. Así que escoger la instancia que hará de servidor y hacer clic en el botón "Active the server". A continuación, en la otra instancia del programa clic en el botón "Connect to the server". Hecho eso ya podréis hacer clic (también en esta última instancia, la que hacer de cliente) en el botón "Send from client". Si os fijáis lo que hago es leer un determinado archivo de texto (a.txt) y mandar su contenido al servidor. Este a su vez tomará dicho texto y lo guardará en un archivo de nombre "b.txt". Ambos archivos deben ser al final iguales. Podéis probar a aumentar el tamaño del archivo "a.txt", simplemente, añadiendo más texto al mismo, para ver hasta dónde es capaz el programa. Y, como digo, sobre todo, acaso alguien pueda darme alguna indicación para mejorar los dos métodos que he mencionado arriba, y que resumen el problema de enviar y recibir grandes cantidades de texto mediante "sockets" TCP. Por favor, no dejéis de comentar cualquier problema (puedo enviaros los binarios del programa si queréis) y/o si necesitáis más información o cualquier otra cosa. Muchas gracias. Última edición por dec fecha: 17-10-2013 a las 21:15:56. |
#5
|
||||
|
||||
¡Arriba!
![]() |
#6
|
||||
|
||||
Hola,
No sé si al final lograré algo mejor que lo que tengo ahora, empero, me parece más menos claro que el "cuello de botella" está a la hora de recibir el texto enviado. Dicho texto se "recorre byte a byte", puesto que el "protocolo" manda, y, es preciso buscar los dos últimos "bytes" del final, que, son los que nos sirven para determinar que el texto se terminó de enviar. Parece claro que el asunto sería mejor si en lugar de necesitar leer "byte a byte" pudiéramos leer directamente un "stream" mayor. Pero hete aquí que el problema sigue siendo que es menester conocer el tamaño de nuestro "stream", y, para esto sólo parece haber dos soluciones: enviar primero el tamaño de nuestro "stream" y a continuación enviar el "stream" mismo. Sin embargo lo dicho no parece sencillo (para mí) de llevar a cabo. Tal como está ahora, incluso cuando el código no es mío y hay bastantes cosas que se me escapan, por lo menos creo comprender lo que se trata de hacer. Es lento, sí, pero, funciona. Lo malo es que en mi proyecto (una DLL que se encaja en otro programa) no funciona tan bien como en una aplicación de Delphi. Aún cuando tenemos que recorrer byte a byte el texto que se envía, una aplicación Delphi puede hacerlo relativamente rápido incluso cuando hablamos de una cadena de texto de más de 100 MB... pero mi proyecto DLL no puede siquiera recibir 1 MB sin colgar a la aplicación en cuya DLL reside. De ahí la necesidad de probar con "streams", de enviar "algo" y sobre todo recibir "algo" que no tengamos que revisar "byte a byte". Y en esas estamos... no sé si alguien ha leído todos estos mensajes y si me explico lo suficiente. En todo caso si logro algún avance lo comentaré por aquí. Y si alguien puede y quiere echarme una mano será bienvenida. ![]() |
![]() |
Herramientas | Buscar en Tema |
Desplegado | |
|
|
![]() |
||||
Tema | Autor | Foro | Respuestas | Último mensaje |
El programa se queda "colgado" mientras copia y luego "despierta" | NeWsP | OOP | 5 | 10-03-2010 22:05:40 |
"OBJECT OR CLASS TYPE REQUIRED" en "APPLICATION EXENAME" | Xavierator | Varios | 3 | 27-10-2008 09:09:50 |
Necesito llamar a métodos de clases "hija" desde su clase "padre" | Flecha | OOP | 17 | 20-04-2007 00:03:53 |
Firebir y usar "IF" en la clausula "SELECT" | papulo | SQL | 6 | 25-07-2006 21:38:04 |
![]() |
|