Synchronize Server/Client data transfer

Just starting out? Need help? Post your questions and find answers here.
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

Synchronize Server/Client data transfer

Post 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
Dear Optimist, Pessimist,
and Realist,

While you guys were
busy arguing about the
glass of water, I DRANK IT !

Sincerely,
the Opportunist
infratec
Always Here
Always Here
Posts: 7576
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Synchronize Server/Client data transfer

Post by infratec »

Hi,

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

Bernd
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Synchronize Server/Client data transfer

Post 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
The Stone Age did not end due to a shortage of stones !
infratec
Always Here
Always Here
Posts: 7576
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Synchronize Server/Client data transfer

Post 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
Post Reply