Page 1 of 1

Synchronize Server/Client data transfer

Posted: Fri Aug 09, 2013 2:31 pm
by Guimauve
Hello everyone,

I have to create a small program for my job. This program as to be able to get file from a specific computer in the network to my computer.

So I have created a small server program running on the specific computer and the client program on my computer. It work with small file only but when I want to transfer a bmp image file the transfer fail. This is the code I use in both, Server and Client programs, to transfer files :

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; CODE GÉNÉRÉ AUTOMATIQUEMENT, NE PAS MODIFIER À
; MOINS D'AVOIR UNE RAISON TRÈS TRÈS VALABLE !!!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code généré par : Dev-Type V4.1.1
; Nom du projet : Le nom du projet ici
; Nom du fichier : Nom du fichier
; Version du fichier : 0.0.0
; Programmation : À vérifier
; Programmé par : Guimauve
; Date : 09-08-2013
; Mise à jour : 09-08-2013
; Codé pour : PureBasic 5.20 beta 9
; Plateforme : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

#HEADER_CHUNK_SIZE = 32767

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Déclaration de la Structure <<<<<

Structure Header
  
  FileSize.q
  CRC32.l
  ChunkCount.l
  ChunkRest.l
  
EndStructure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les observateurs <<<<<

Macro GetHeaderFileSize(HeaderA)
  
  HeaderA\FileSize
  
EndMacro

Macro GetHeaderCRC32(HeaderA)
  
  HeaderA\CRC32
  
EndMacro

Macro GetHeaderChunkCount(HeaderA)
  
  HeaderA\ChunkCount
  
EndMacro

Macro GetHeaderChunkRest(HeaderA)
  
  HeaderA\ChunkRest
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les mutateurs <<<<<

Macro SetHeaderFileSize(HeaderA, P_FileSize)
  
  GetHeaderFileSize(HeaderA) = P_FileSize
  
EndMacro

Macro SetHeaderCRC32(HeaderA, P_CRC32)
  
  GetHeaderCRC32(HeaderA) = P_CRC32
  
EndMacro

Macro SetHeaderChunkCount(HeaderA, P_ChunkCount)
  
  GetHeaderChunkCount(HeaderA) = P_ChunkCount
  
EndMacro

Macro SetHeaderChunkRest(HeaderA, P_ChunkRest)
  
  GetHeaderChunkRest(HeaderA) = P_ChunkRest
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Reset <<<<<

Macro ResetHeader(HeaderA)
  
  SetHeaderFileSize(HeaderA, 0)
  SetHeaderCRC32(HeaderA, 0)
  SetHeaderChunkCount(HeaderA, 0)
  SetHeaderChunkRest(HeaderA, 0)
  
  ; ClearStructure(HeaderA, Header)
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Macro de déboguage <<<<<

Macro DebugHeader(HeaderA)
  
  Debug "FileSize : " + Str(GetHeaderFileSize(HeaderA))
  Debug "CRC32 : " + Str(GetHeaderCRC32(HeaderA))
  Debug "ChunkCount : " + Str(GetHeaderChunkCount(HeaderA))
  Debug "ChunkRest : " + Str(GetHeaderChunkRest(HeaderA))
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code généré en : 00.015 secondes (7333.33 lignes/seconde) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Macro SendNetworkFileHeader(ClientID, HeaderA)
  
  SendNetworkData(ClientID, HeaderA, SizeOf(Header))
  
EndMacro

Macro ReciveNetworkFileHeader(ConnectionID, HeaderA)
  
  ReceiveNetworkData(ConnectionID, HeaderA, SizeOf(Header))
  
EndMacro

Procedure SendNetworkFile(ClientID, FileName.s)
  
  FileHandle = ReadFile(#PB_Any, FileName)
  
  If IsFile(FileHandle)
    
    SetHeaderFileSize(Header.Header, Lof(FileHandle))
    SetHeaderChunkCount(Header, GetHeaderFileSize(Header) / #HEADER_CHUNK_SIZE)
    SetHeaderChunkRest(Header, GetHeaderFileSize(Header) % #HEADER_CHUNK_SIZE)
    
    *FileDataBuffer = AllocateMemory(GetHeaderFileSize(Header))
    
    If *FileDataBuffer <> #Null
      
      *ChunkPtr = *FileDataBuffer
      ReadData(FileHandle, *FileDataBuffer, GetHeaderFileSize(Header))
      SetHeaderCRC32(Header, CRC32Fingerprint(*FileDataBuffer, GetHeaderFileSize(Header)))
      
      ;Debug "SendNetworkFileHeader"
      ;DebugHeader(Header)
      
      SendNetworkFileHeader(ClientID, Header)
      
      For ChunkID = 0 To GetHeaderChunkCount(Header)
        
        If ChunkID <> GetHeaderChunkCount(Header)
          SendNetworkData(ClientID, *ChunkPtr, #HEADER_CHUNK_SIZE)
          *ChunkPtr + #HEADER_CHUNK_SIZE
        Else
          SendNetworkData(ClientID, *ChunkPtr, GetHeaderChunkRest(Header))
        EndIf
        
      Next
      
      FreeMemory(*FileDataBuffer)
      CloseFile(FileHandle)
      
    EndIf
    
  EndIf
  
EndProcedure

Procedure.i ReciveNetworkFile(ConnectionID, FileName.s = "")
  
  ReciveNetworkFileHeader(ConnectionID, Header.Header)
  
  ;Debug "ReciveNetworkFileHeader"
  ;DebugHeader(Header)
  
  *FileDataBuffer = AllocateMemory(GetHeaderFileSize(Header))
  
  If *FileDataBuffer <> #Null
    
    *ChunkPtr = *FileDataBuffer
    
    For ChunkID = 0 To GetHeaderChunkCount(Header)
      
      If ChunkID <> GetHeaderChunkCount(Header)
        ReceiveNetworkData(ConnectionID, *ChunkPtr, #HEADER_CHUNK_SIZE)
        *ChunkPtr + #HEADER_CHUNK_SIZE
      Else
        ReceiveNetworkData(ConnectionID, *ChunkPtr, GetHeaderChunkRest(Header))
      EndIf
      
    Next
    
    If CRC32Fingerprint(*FileDataBuffer, GetHeaderFileSize(Header)) = GetHeaderCRC32(Header)
      
      If FileName <> ""
        
        FileHandle = CreateFile(#PB_Any, FileName)
        
        If IsFile(FileHandle)
          WriteData(FileHandle, *FileDataBuffer, GetHeaderFileSize(Header))
          CloseFile(FileHandle)
        Else
          ; Impossible to create file
          Output.i = -3
          FreeMemory(*FileDataBuffer)
        EndIf
        
      Else
        
        Output = *FileDataBuffer
        
      EndIf
      
    Else
      
      ; The CRC 32 don't match 
      Output = -2
      
    EndIf
    
  Else
    
    ; Impossible to allocate the memory
    Output = -1
    
  EndIf
  
  ProcedureReturn Output
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
My guess about the problem : No synchronization between the server and the client program.
If so, how can I modify my SendNetworkFile() and ReceiveNetworkFile() procedures to have synchronization between them since the server use SendNetworkFile() and the client use ReceiveNetworkFile().

Thanks beforehand!
Guimauve

Re: Synchronize Server/Client data transfer

Posted: Fri Aug 09, 2013 6:07 pm
by infratec
Hi,

you don't check first with NetworkClientEvent() if there is something.
Than you don't check the result of ReceiveNetworkData()

Bernd

Re: Synchronize Server/Client data transfer

Posted: Sun Aug 11, 2013 1:35 pm
by StarBootics
Hello everyone,

I have accept the challenge but so far it didn't work yet. I have try with a small *.csv file (about 374 bytes) the header is sent correctly by the server and the client receive it correctly too. At least the Header content are the same for both, Server and Client.

But the file data it's self don't work. The file data CRC32FingerPrint on the server side is -1932118461, but from the data received on the client side is 1670242692. Looks like a bug under Linux to me but I'm not sure.

Can someone tell us if SendNetworkData() - ReceiveNetworkData() have their memory buffer reset between each call.

Thanks
StarBootics

Re: Synchronize Server/Client data transfer

Posted: Sun Aug 11, 2013 2:44 pm
by infratec
StarBootics wrote:Hello everyone,Can someone tell us if SendNetworkData() - ReceiveNetworkData() have their memory buffer reset between each call.
:?: :?: :?:

The *Buffer which you use depends on you.
But it doesnt matter, if you receive something, the same *Buffer is overwritten by the new received data.
Also for send:
If you not fill the *Buffer with new data, it stays.


Btw.
If no working code is provided, I'll test nothing, since the work to write a code around costs to much of my free time.
So I only look above the snippets and mention my thoughts.

Bernd