Ver Mensaje Individual
  #17  
Antiguo 03-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Reputación: 14
aguml Va por buen camino
A ver, para archivos pequeño he hecho esto y funciona:
Código PHP:
char flagFile[SIZEFLAG] = {"\n\n_File_\n\n\0"};
struct{
        
char name[256];
        
long size;
}
archivo;

bool recvFilerecvStructFile;

void __fastcall TChatForm::ButtonSendFileClick(TObject *Sender)
//Aqui se envia el fichero

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

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

                
fseek(hFile0SEEK_SET);

                if(
hFile)
                {
                   
strcpy(archivo.nameExtractFileName(OpenDialog1->FileName).c_str());
                   
archivo.size tamanio;

                   if(
IsServer){
                      
retval ServerSocket->Socket->Connections[0]->SendBuf(flagFileSIZEFLAG);
                      
retval += ServerSocket->Socket->Connections[0]->SendBuf(&archivosizeof(archivo));
                   }else{
                      
retval ClientSocket->Socket->SendBuf(flagFileSIZEFLAG);
                      
retval += ClientSocket->Socket->SendBuf(&archivosizeof(archivo));
                   }

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

                                if(
IsServer){
                                   
retval ServerSocket->Socket->Connections[0]->SendBuf(bufferleidos);
                                }else{
                                   
retval ClientSocket->Socket->SendBuf(bufferleidos);
                                }

                                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.");
                   }
                }
        }
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 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
  
unsigned char *buffer;
  
int size,lenBuff;

  
lenBuff Socket->ReceiveLength();
  
buffer = new char[lenBuff 1];
  
memset(buffer,0,sizeof(buffer));

  
size Socket->ReceiveBuf(buffer,lenBuff);

  if(
strcmp(bufferflagFile) == 0)
  {
        
recvFile true;
  }

  else if(
recvFile == true && size == (sizeof(archivo.name) + sizeof(archivo.size)))
  {
        
memcpy(archivo.namebuffersizeof(archivo.name));
        
memcpy(&archivo.sizebuffer sizeof(archivo.name), sizeof(archivo.size));
        
recvStructFile true;
  }else if(
recvFile == true && recvStructFile == true){
        
FILE *salida;
        
salida fopen(AnsiString(ExtractFilePath(Application->ExeName) + "\\\\" archivo.name).c_str(),"wb");
        
fwrite(buffersize1salida);
        
fclose(salida);
  }else{
     
//Si no es una imagen mostramos el mensaje enviado
     
RichEdit1->SelStart RichEdit1->Text.Length();
     
RichEdit1->SelLength 0;
     
RichEdit1->SelAttributes->Color clGreen;
     
RichEdit1->Lines->Add(EditServer->Text ": " AnsiString( (char*)buffer));  // Añadir los datos al memo de recepción
  
}
  
delete [] buffer;
}

//---------------------------------------------------------------------------
// Se produce cuando el socket de servidor debe leer la información de un socket cliente.
//---------------------------------------------------------------------------
void __fastcall TChatForm::ServerSocketClientRead(TObject *Sender,
      
TCustomWinSocket *Socket)
{
  
// Cuando el cliente envia datos al servidor y este los ha de procesar
  
unsigned char *buffer;
  
int size,lenBuff;

  
lenBuff Socket->ReceiveLength();
  
buffer = new char[lenBuff 1];
  
memset(buffer,0,sizeof(buffer));

  
size Socket->ReceiveBuf(buffer,lenBuff);

  if(
strcmp(bufferflagFile) == 0)
  {
        
recvFile true;
  }

  else if(
recvFile == true && size == (sizeof(archivo.name) + sizeof(archivo.size)))
  {
        
memcpy(archivo.namebuffersizeof(archivo.name));
        
memcpy(&archivo.sizebuffer sizeof(archivo.name), sizeof(archivo.size));
        
recvStructFile true;
  }else if(
recvFile == true && recvStructFile == true){
        
FILE *salida;
        
salida fopen(AnsiString(ExtractFilePath(Application->ExeName) + "\\\\" archivo.name).c_str(),"wb");
        
fwrite(buffersize1salida);
        
fclose(salida);
  }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 ": " AnsiString( (char*)buffer));  // Añadir los datos al memo de recepción
  
}

Tiene un problema y es que cuando se hace un SendBuf, al ser asincronico, no espera respuesta y como tarde mas de la cuenta en llegar el bloque, se acumulan y se añaden los bloques unos a otros, o sea, si el primer paquete mide 11 y el segundo mide 260, como tarde mucho en llegar el primero llegara un solo paquete de 271 y asi con todo lo que se envie. Ese es el problema que tengo para poder enviar archivos mas grandes tambien. No se como hacer para que no envie otro paquete hasta que reciba el cliente el anterior y lo procese y asi con todos.
Responder Con Cita