![]() |
¿procesos que charlan entre ellos usando tuberias con nombre?
hola amigos, leyendo un escrito donde hablan sobre las tuberias con nombre para la comunicacion entre procesos pero bajo linux, me ha entrado la curiosidad. Como se haria eso bajo windows usando C o C++? Tambien vi que esto mismo se puede hacer con conexion tcp/ip y tambien me comentaron que se podia hacer con hilos y semaforos. He estado buscando info pero todo lo que encuentro va dirigido a linux. Me interesan todos y si pudieran indicarme escritos donde se expliquen y si conocen mas alternativas, y pros y contras entre usar uno u otro? Desde ya gracias.
|
Mira este tema sobre los archivos de memoria compartida. Aquí realizé una especie de chat entre dos aplicaciones que se comunican con texto usando memoria compartida. También puede ser útil el mensaje Windows WM_COPYDATA, lee este artículo: Cómo pasar datos de cadena entre aplicaciones mediante SendMessage. También te puede servir este artículo orientado a delphi.
También debes leer algo sobre los Pipes de Windows y por supuesto la comunicación por Sockets en Windows: Winsock. Saludos. |
Si lo que buscas es conectar procesos y no necesariamente usando name pipes, una excelente opcion es usando
http://zeromq.org/ o usando HTTP+REST |
Mil gracias amigos, acabo de terminar un pequeño ejemplo con tuberias con nombre y va genial.
Mi intencion es seguir probando el resto de modos de hacer esto para ir viendo como funcionan. Una cosa, si las tuberias usan memoria compartida ¿en que se diferencia de usar memoria compartida como indicas? |
1 Archivos Adjunto(s)
Vale, ya lo he conseguido tambien con SendMessage pero me gustaria que fuera sincronico y con consolas en C. Yo lo he hecho con dos forms en C++builder y es asincronico, o sea, que puedes enviar sin haber recibido. No se si me explico.
¿Alguien puede echarle un vistazo y ayudarme con eso? |
Para sincronizar las app puedes enviar el dato y luego esperar una respuesta antes de enviar mas datos. Esa respuesta debe actuar como semáforo.
Si usas sokets síncronos el sincronismo te viene dado pero te bloquea la app mientras espera una respuesta. Saludos. |
o sea que me creo por ejemplo una variable booleana global que uso como semaforo para indicar si ya he recibido respuesta o no ¿Es eso? Y cuando dices congelado ¿Te refieres a que no puedo escribir? ¿O te refieres a que se queda el form totalmente bloqueado? Lo de los sockets no tengo ni idea y pensaba mirarlo el ultimo pero ¿podria ejecutarse en hilos independientes para evitar el bloqueo? Sobre lo que estoy ahora, me gustaria seguir mirando la opcion del wm_copydata con sendmessage pero hacerlo con aplicaciones de consola (preferiblemente en c). Se que para capturar esos mensajes tengo que usar un callback donde se gestione el mensaje que yo desee y usar el WindowProc del proceso pero ¿Como hago eso en una aplicacion de consola?
|
Cita:
Cita:
Cita:
Saludos. |
Te recomiendo que leas un poco sobre como es la arquitectura de apps distribuidas, para que no hagas vueltas innecesarias como usar variables boolean tratando de implementar (macheteramente!) un lock, osea: La sugerencia que te dan y las ideas de este thread son la forma incorrecta - e innecesaria- de implementar lo que buscas. A proposito, seria bueno que tuvieras claro exactamente que es lo que quieres. Ademas, es mejor primero definir como son las cosas y LUEGO definir que tecnologia usas, no vaya ser que pelees contra la corriente y trates de hacer en X lo que seria natural en Y. Por ejemplo, es un sinsentido intentar que un protocolo asincronico se vuelva sincronico... sabiendo que podrias usar un sincronico desde el inicio.
Un excelente compendio de muchas de esas arquitecturas esta en la guia de 0mq: http://zguide.zeromq.org/page:all P.D: Mira si lo que buscas se acomoda a uno de los estilos que se plantean aqui, como un modelo PUSH-SUB, REQ-REP, FAN-OUT, etc Te recomiendo que si no sabes exactamente que usar, 0mq es una buena eleccion que cubre casi de todo, a menos que necesites que funcione a escala internet. En ese caso, usa HTTP (sincro) o WebSocket (async). |
bueno, necesitar no necesito ninguno, solo queria conocer las opciones y probarlas para ver como son per esta pregunta no surge por necesidad. Es pura curiosidad y definir como son las cosas... Pues no puedo hacerlo porque la idea es ir probando todas las opciones o al menos las mas interesantes.
|
He conseguido hacerlo sincronico y he puesto el link en el tema donde pregunto como marcar un checkbox en otro proceso ya que eso era parte de esto asi que tambien lo pongo aqui el enlace.
Link: Aqui Si lo abris y veis algo raro que cambiariais o mejorariais (sin cambiar el modo de comunicacion con WM_COPYDATA y SendMessage) soy todo oidos. Ya digo que soy muy nobel en todo esto y seguro veis salvajadas en el codigo, por eso pido que si alguien puede lo mire y me indique que corregir. |
1 Archivos Adjunto(s)
Bueno amigos, ahora estoy liado con el tema de sockets y lo veo muy complejo aunque he encontrado un escrito que me ha ayudado mucho pero no lo tengo todo lo claro que deberia para seguir.
Ya he conseguido enviar y recibir mensajes de forma sincronica pero tengo un problema, el codigo de enviar y recibir lo hago a traves de un solo boton con lo que si envio no recibo hasta que vuelvo a enviar y algun que otro problema que se me presenta por este tema. Supongo que habrá que gestionarlo con mensajes en vez de con los eventos de un boton para poder separar el envio y la recepcion pero hasta ahi he llegado. ¿alquien puede ayudarme con esto? Este es el escrito que he encontrado y en el que me he apoyado para hacer lo que tengo hasta ahora: Pinchar aquí Adjunto lo que tengo para que podais ojearlo a ver si podeis ayudarme. Me gustaria hacerlo de forma sincronica y, cuando ya lo tenga, a ver si podeis ayudarme tambien con el modo asincronico que con lo que explica el escrito no lo tengo nada claro ;) Gracias por adelantado. :) |
|
1 Archivos Adjunto(s)
Bueno, despues de mucho trabajo lo hice funcionar y va genial aunque seguramente tendrá fallos que no haya visto.
Ahora estoy liado con el envio y recepcion de archivos y para eso hago esto: Para recibir: Código PHP:
Código PHP:
|
Veo que te has puesto manos a la obra.
He estado ocupado pero en un ratito libre he preparado un ejemplo a bajo nivel con WinSock en programas de consola. Se trata de un pequeño prototipo de chat con modelo cliente servidor y protocolo TCP aceptando una sola conexión, para no liar la cosa. Dejo el código muy comentado por si más adelante te interesa el manejo a bajo nivel sin componentes: Servidor: Código PHP:
Código PHP:
|
amigo ya he conseguido hacer eso pero ahora quiero enviar archivos y como en c++builder para el chat lo tengo asincronico pues no puedo ir recibiendo trozos e indicar al servidor que ya llegó para que siga ya que me los manda todos de golpe y lo mando en bloques de 1024 bytes y si pasa de 8192 bytes (8 bloques) el servidor da error al enviar y ademas al usar retval = Socket->ReceiveBuf(buffer,lenBuff); lo que obtengo es tanto la cadena que envio como flag para indicar que es un archivo lo que quiero enviar, como el contenido del archivo, todo en un bloque de 8192 y luego vuelve a entrar en el evento y me muestra el resto como mensajes de texto. ¿como hago para mandar bloques de un archivo y que el cliente lo reciba como tal y luego los una y obtenga un archivo igual que el original? Para archivos pequeños he hecho esto:
Código PHP:
|
A ver, para archivos pequeño he hecho esto y funciona:
Código PHP:
|
Bueno, he conseguido transferir archivos aunque no creo que sea del todo correcto lo que hago para conseguirlo :p. Primero paso una mascara para indicar que es un envio de archivo y a continuacion mando una estructura donde indico el nombre del archivo, su tamaño, y el número de bloques a enviar. He colocado un Sleep para poder enviar sin perder datos por el camino. Os adjunto el fuente para que si alguien quiere mirarlo y ayudarme a mejorarlo para hacerlo funcionar correctamente pues se lo agradeceria ya que a veces se pierden bytes por el camino aunque la mayor parte de las veces llega el fichero correctamente pero otras veces se queda el receptor esperando como si faltara algun bloque por llegar.
Aqui el link |
No creo que estés usando el método adecuado. Es mejor que la comunicación sea síncrona y ten en cuenta que los paquetes se pueden unir o separar. No tengo ahora tiempo de realizar un ejemplo. Puedes, también, usar la API TransmitFile
Te dejo un fragmento de código funcional para recibir ficheros por esta vía, previamente debes haber comunicado el tamaño del fichero y nombre a transferir (SizeFile y lpPathName): Código PHP:
|
Bueno, te he preparado un rápido ejemplo sobre el chat que te envié antes y sin usar componentes de VCL. Sokets "a pelo".
En el chat, si el cliente envía "Envia Fichero" (sin acento para no confundir caracteres), el servidor envía un fichero llamado Prueba0.bmp que es un bmp grande. El cliente lo recibe y lo guarda como Prueba.bmp. A continuación el server recibe la palabra y sigue la comunicación... Te expongo las funciones que envían y reciben el fichero: TransmitFile.h Código PHP:
Código PHP:
PD/ Borro el anterior chat porque este es idéntico, añadiendo la nueva funcionalidad Saludos. |
Amigo he estado haciendo pruebas con la api que comentas pero claro, tu usas un tipo SOCKET y yo intento hacer lo mismo con un TSocketServer y un TSocketClient y la verdad es que todo lo que pruebo acaba retornandome false en TransmitFile. He probado esto:
Código PHP:
Código PHP:
Código PHP:
|
Para poder usar la API de winsocket desde los componentes VCL TServerSocket y TClientSocket, debes usar ServerSocket->Socket->SocketHandle o ClientSocket->Socket->SocketHandle
Saludos. |
1 Archivos Adjunto(s)
Bueno amigo, he estado viendo el modo en que me indicabas y he modificado mi funcion para que use lo que me indicabas, o sea, uso TransmitFile y una funcion propia llamada ReceiveFile. El problema es que el archivo que recibo es corrupto porque termina la funcion de recepcion pero no recibo todos los bytes. He comprobado que en la funcion ReceiveFile salgo del bucle con el break en vez de salir porque nBytes sea igual a FileSize. Lo que pienso es que se pueden estar perdiendo bytes por el camino pero no tengo ni idea ya que uso TransmitFile y no se como funciona esta por dentro. Adjunto el proyecto por si quereis mirarlo a ver que puede estar pasando.
|
Tienes un eror de concepto. Cuando esperas recibir el archivo y se dispara el evento SocketRead, en tu código, primero lees cosas (estructura del archivo, MD5...) con lo que estás perdiendo datos, pues en ese momento ya estás recibiendo los primeros bloques del archivo. Fíjate en este cambio que realizo en tu código y verás que ya funciona. Seguramente este error lo tenías en otras formas de leer tu archivo:
Código PHP:
|
Aprovecho para mostrarte como obtener el Hash MD5 de un archivo con la API de Windows tal y como lo utilicé en este ejemplo para cazar un virus: TerminateMD5_Process, a la caza de un virus...
Código PHP:
|
Un detalle más que olvidé al publicar la solución a tu problema es que ha añadido un guión bajo al nombre del archivo recibido puesto que se escribe en el mismo path que el original y puede ocurrir una doble apertura del mismo:
Código PHP:
Saludos. |
estos dias no voy a poder tocar el pc porque voy a estar fuera y la verdad es que no veo el cambio que realizaste en el codigo a simple vista. ¿Podrias explicar que cambiaste y cual era el problema? Sobre lo del md5... Sabia que python lo ponia muy facil pero no sabia que la api de windows ya lo tenia y la verdad es que es de gran utilidad. Muchisimas gracias por todo.
|
Puse delante de todo, el código que lee el fichero, antes de las lecturas del flag y cabeceras. Viendo que esas variables eran globales, me salté su lectura, puesto que en el anterior evento ya se han leído.
El oroblema es que si lees del socket datos, cuando esperas un fichero, no se vuelven a leer después y pierdes esa información, que es del propio fichero. Debes organizar un poco codo el código. Saludos. |
ok amigo, mil gracias, ya contaré que tal va pero se me olvidó comentar algo y es que la funcion que pusiste para leer la llegada del fichero habia muy rara vez que salia antes de leer todo el fichero porque recibia un -1 antes de tiempo. Pude comprobar que si al final del bucle ponia un Sleep(1) ya no fallaba nunca. Ya digo que sin el Sleep fallaba muy rara vez, quizas una de 10 o mas veces. ¿por que podia pasar eso? la funcion transmitfile ya habia salido con true con lo que se supone que la cola de la que estamos descargando tiene ya todos los datos necesarios ¿no?
Otra cosa ¿Algun voluntario para probar si funciona online? es que solo lo he probado en mi pc y me gustaria ver como se hace para que funcione en online. ¿que pongo en TServerSocket->Host? ¿y que pongo en el cliente? ¿que diferencia hay entre Host, Address, y Service? Creo que en los tres puedo poner la direccion y funcionaria igual ¿no? |
| La franja horaria es GMT +2. Ahora son las 11:04:21. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi