Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 29-09-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.941
Poder: 28
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
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).
__________________
El malabarista.

Última edición por mamcx fecha: 29-09-2014 a las 22:42:37.
Responder Con Cita
  #2  
Antiguo 29-09-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 14
aguml Va por buen camino
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.

Última edición por aguml fecha: 29-09-2014 a las 23:00:31.
Responder Con Cita
  #3  
Antiguo 30-09-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 14
aguml Va por buen camino
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.
Responder Con Cita
  #4  
Antiguo 01-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 14
aguml Va por buen camino
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.
Archivos Adjuntos
Tipo de Archivo: rar Conexion entre procesos con Sockets.rar (9,5 KB, 5 visitas)
Responder Con Cita
  #5  
Antiguo 02-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 14
aguml Va por buen camino
me acabo de enterar que el builder tiene componentes para eso y he encontrado dos sitios interesantes que tengo que examinar bien: sitio 1 y sitio 2

Última edición por aguml fecha: 02-10-2014 a las 14:44:16.
Responder Con Cita
  #6  
Antiguo 03-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 14
aguml Va por buen camino
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:
//---------------------------------------------------------------------------
// Se produce cuando un socket de cliente debe leer la información de la conexión de socket.
//---------------------------------------------------------------------------
void __fastcall TChatForm::ClientSocketRead(TObject *Sender,
      
TCustomWinSocket *Socket)
{
  
// Cuando el servidor envia datos al ciente y este los ha de procesar
  
AnsiString MensajeRecibido;
  
char aux[10];
  
char buffer[1024];
  
int retval;

  
MensajeRecibido = Socket->ReceiveText();
  
memcpy(aux,MensajeRecibido.c_str(),10);

  if(
strncmp(aux, flagFile,10) == 0)
  {
     do{
        
memset(buffer,0,sizeof(buffer));
        
//Aqui gestiono para recibir el archivo
        
retval = Socket->ReceiveBuf(buffer,SIZEBLOCK);
     }while(
retval != -1);

  }else{
     
//Si no es una imagen mostramos el mensaje enviado
     
RichEdit1->SelStart = RichEdit1->Text.Length();
     
RichEdit1->SelLength = 0;
     
RichEdit1->SelAttributes->Color = clGreen;
     
MensajeRecibido = EditServer->Text + ": " + MensajeRecibido;
     
RichEdit1->Lines->Add(MensajeRecibido);  // Añadir los datos al memo de recepción
  
}
}

//---------------------------------------------------------------------------
// Se produce cuando el socket de servidor debe leer la información de un socket cliente.
//---------------------------------------------------------------------------
void __fastcall TChatForm::ServerSocketClientRead(TObject *Sender,
      
TCustomWinSocket *Socket)
{
  
AnsiString MensajeRecibido;
  
char aux[10];
  
char buffer[1024];
  
int retval;

  
MensajeRecibido = Socket->ReceiveText();
  
memcpy(aux,MensajeRecibido.c_str(),10);

  if(
strncmp(aux, flagFile,10) == 0)
  {
     do{
        
memset(buffer,0,sizeof(buffer));
        
//Aqui gestiono para recibir el archivo
        
retval = Socket->ReceiveBuf(buffer,SIZEBLOCK);
     }while(
retval != -1);

  }else{
     
// Cuando el cliente envia datos al servidor y este los ha de procesar
     
RichEdit1->SelStart = RichEdit1->Text.Length();
     
RichEdit1->SelLength = 0;
     
RichEdit1->SelAttributes->Color = clGreen;
     
RichEdit1->Lines->Add(Socket->RemoteHost + ": " + MensajeRecibido);  // Añadir los datos al memo de recepción
  
}
} 
Para enviar:
Código PHP:
void __fastcall TChatForm::ButtonSendFileClick(TObject *Sender)
{ 
//Aqui se envia el fichero

        
long tamanio = 0;
        
char buffer[SIZEBLOCK];
        
FILE *hFile;
        
int enviados = 0, leidos = 0, retval = 0;

        if(
OpenDialog1->Execute())
        {
                
hFile = fopen(OpenDialog1->FileName.c_str(),"rb");
                
fseek(hFile, 0, SEEK_END);
                
tamanio = ftell(hFile);

                
fseek(hFile, 0, SEEK_SET);

                if(
hFile)
                {
                   if(
IsServer){
                      
retval = ServerSocket->Socket->Connections[0]->SendBuf(flagFile, sizeFlag);
                   }else{
                      
retval = ClientSocket->Socket->SendBuf(flagFile, sizeFlag);
                   }

                   if(
retval == sizeFlag)
                   {
                           while(!
feof(hFile))
                           {
                                
//voy por aqui y no funciona
                                
leidos = fread(buffer, sizeof(char), SIZEBLOCK,hFile);

                                if(
IsServer){
                                   
retval = ServerSocket->Socket->Connections[0]->SendBuf(buffer, leidos);
                                }else{
                                   
retval = ClientSocket->Socket->SendBuf(buffer, leidos);
                                }

                                if(
retval != leidos)
                                {
                                   
RichEdit1->SelStart = RichEdit1->Text.Length();
                                   
RichEdit1->SelLength = 0;
                                   
RichEdit1->SelAttributes->Color = clRed;
                                   
RichEdit1->Lines->Add("Error en el envio del fichero");
                                   break;
                                }else{
                                   
enviados += retval;
                                }

                                if(
ferror(hFile))
                                {
                                   
RichEdit1->SelStart = RichEdit1->Text.Length();
                                   
RichEdit1->SelLength = 0;
                                   
RichEdit1->SelAttributes->Color = clRed;
                                   
RichEdit1->Lines->Add("Error durante la lectura del fichero. Vuelva a intentarlo.");
                                   break;
                                }
                           }
                   }else{
                        
RichEdit1->SelStart = RichEdit1->Text.Length();
                        
RichEdit1->SelLength = 0;
                        
RichEdit1->SelAttributes->Color = clRed;
                        
RichEdit1->Lines->Add("Error inesperado al enviar el archivo.");
                   }
                   
fclose(hFile);

                   if(
tamanio != enviados)
                   {
                      
RichEdit1->SelStart = RichEdit1->Text.Length();
                      
RichEdit1->SelLength = 0;
                      
RichEdit1->SelAttributes->Color = clRed;
                      
RichEdit1->Lines->Add("Error en el envio del fichero. El tamaño del fichero original no coincide con el tamaño del fichero enviado.");
                   }
                }
        }
} 
El que manda el archivo da los errores "Error en el envio del fichero" y "Error en el envio del fichero. El tamaño del fichero original no coincide con el tamaño del fichero enviado." mientras que el que recibe, que lo que hace simplemente es una prueba recuperando toda la pila sin guardar nada, cuando termina da una excepcion. ¿que se me escapa para poder enviar un archivo? Adjunto el proyecto a ver si podeis mirarlo y me echan un cable.
Archivos Adjuntos
Tipo de Archivo: rar Chat con sockets en C++Builder.rar (9,8 KB, 2 visitas)
Responder Con Cita
  #7  
Antiguo 03-10-2014
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
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:
int main(int argc, char* argv[])
{
  
WSADATA Wsa;
  
SOCKET Sock_e;   // Sock de escucha
  
SOCKET Sock_c;   // Sock de comunicación
  
struct sockaddr_in Server, Client, AddrEnRoute;
  
int Len=0;
  
char Buffer[1024];
  
DWORD Port = 9999;

  
// Inicializamos
  
printf("Inicializando el servidor...\n");
  if(
WSAStartup(MAKEWORD(2, 0), &Wsa) != 0) return 0;

  
//Creamos el socket
  
if((Sock_e = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) != INVALID_SOCKET){
    
// Dirección IP y puerto
    
Server.sin_family = AF_INET;
    
Server.sin_addr.s_addr = INADDR_ANY;
    
Server.sin_port = htons(Port);
    
AddrEnRoute = Server;
    
AddrEnRoute.sin_addr = *((struct in_addr *)gethostbyname("localhost")->h_addr);

    
// Asociamos el socket al puerto
    
if(bind(Sock_e, (SOCKADDR*)&Server, sizeof(Server)) != -1){
      
// Bucle principal del servidor
      // Este servidor nunca termina, siempre escuchará
      
while(true){
        
// Escuchando puerto
        
printf("\nEscuchando por el puerto %d\n", Port);
        if (
listen(Sock_e, 1) != -1){
          
//hay una conexión entrante y la aceptamos
          
Len = sizeof(sockaddr);
          
Sock_c = accept(Sock_e,(sockaddr*)&Client, &Len);
          if(
Sock_c == INVALID_SOCKET) continue;
          
strcpy(Buffer, "Aceptada conexión\n\n");
          
printf(Buffer);

          
// Bucle de comunicación
          
do{
            
// Leemos los datos entrantes
            
Len = recv(Sock_c, Buffer, sizeof(Buffer), 0); //recibimos los datos que envie
            
if(Len<0) continue;
            
// Si tenemos datos seguimos
            
printf("- "); printf(Buffer);
            if(!
strnicmp(Buffer, "Adios", 5)) break;
            
printf("\n>> ");
            
gets(Buffer);
            
strcat(Buffer, "\n");
            
send(Sock_c, Buffer, lstrlen(Buffer)+1, 0);
          } while(
Len && Len!=-1);

          
closesocket(Sock_c);
        }
      } 
// While(true)
      
closesocket(Sock_e);
    } 
// if(bind)
  
} // if(Sock_e)

  
WSACleanup();
  return 
0;
} 
Cliente:
Código PHP:
int main(int argc, char* argv[])
{
  
WSADATA Wsa;
  
SOCKET  Sock;
  
struct hostent *host;
  
struct sockaddr_in direc;
  
DWORD Port = 9999;
  
char Buffer[1024];
  
int Len;
  
bool Salir = false;

  
//Inicializamos la librería winsock
  
printf("Inicializando Cliente....\n\n");
  
WSAStartup(MAKEWORD(2,2),&Wsa);

  
//creamos el Sock y comenzamos el bucle principal
  
while(!Salir){
    
Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(
Sock !=-1){
      
//Dirección IP del servidor y Puerto
      
host = gethostbyname("localhost");
      
direc.sin_family=AF_INET;
      
direc.sin_port = htons(Port);
      
direc.sin_addr = *((struct in_addr *)host->h_addr);
      
ZeroMemory(direc.sin_zero, 8);

      
// Pedimos conexión al servidor
      
printf("Esperando conexión al servidor...\n\n");
      while(
connect(Sock, (sockaddr *)&direc, sizeof(sockaddr))){Sleep(200);}

      
printf("Conexión aceptada\n\n");
      
// Saludamos
      
strcpy(Buffer, "Gracias por aceptar la conexión\n");
      
printf(">> "); printf(Buffer);
      
send(Sock, Buffer, lstrlen(Buffer)+1, 0);

      
//mientras el Sock no se haya desconectado
      
do {
        
Len = recv(Sock, Buffer, sizeof(Buffer), 0);
        if(
Len<0) continue;
        
// Si hay satos, seguimos
        
printf("- "); printf(Buffer);
        if(!
strnicmp(Buffer, "Adios", 5)) {Sleep(400); Salir = true; break;}
        
printf("\n>> ");
        
gets(Buffer);
        
strcat(Buffer, "\n");
        
send(Sock, Buffer, lstrlen(Buffer)+1, 0);
      } while(
Len && Len!=-1);
      
closesocket(Sock);
    }
    
Sleep(500);
  }

  
WSACleanup();
  return 
0;
} 
Saludos.

Última edición por escafandra fecha: 04-10-2014 a las 18:25:44.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Ellas y Ellos jcarteagaf Humor 1 06-08-2011 03:43:05
Llamada entre ventana usando paquetes. PittyDelphi OOP 3 27-01-2011 12:28:37
¿Saben algo de ellos? roman La Taberna 11 18-11-2008 18:59:07
Comunicación TCP/IP entre dos programas usando componentes INDY Roger_Delphi Internet 2 20-10-2008 14:02:49
Comunicacion entre procesos walito Varios 0 14-11-2007 21:55:53


La franja horaria es GMT +2. Ahora son las 04:15:23.


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
Copyright 1996-2007 Club Delphi