Page 1 sur 1

probleme entre ReceiveNetworkData et SendNetworkData

Publié : mar. 09/oct./2012 15:02
par supercdfr
Bonjour a tous,

J'essaye depuis 1 semaine de faire un programme de transfert de fichier entre 2 machines en LAN.
Mon but est de transférer des fichiers d'une machine a une autre et inversement (autrement dit, client/serveur serveur/client)

Pour la connexion entre les 2, j'ai réussi sans trop de soucis.

Le soucis maintenant, c'est que le transfert de petit fichier fonctionne, mais le transfert d'un plus gros (j'ai testé sur 1 fichier de 1.7Mo) ne fonctionne pas.

Voici mes codes client/serveur (attention, c'est un peu long) :

Code serveur :

Code : Tout sélectionner

Enumeration
  #reseau
  #repertoire
  #fichier
EndEnumeration

Global taille_buffer.l = 4096
Global Dim Drive_Nom.s(25),nombre_disque
Global adresse_ip_client.s
Global ConnexionID.l

Procedure GetAllDrives()
  MaskDrive = GetLogicalDrives_()
  Mask      = 1                 
  lpFileSystemNameBuffer.s = Space(256)
  nombre_disque=0
  For i.l = 65 To 97
    If MaskDrive & Mask
      wNom$=Chr(i)+":\"
      wNom2$ = Chr(i) + ":"
      wType=GetDriveType_(WNom$)
      If wtype=#DRIVE_FIXED
        nombre_disque=nombre_disque+1
        Drive_Nom(nombre_disque)= wNom2$
      EndIf
    EndIf
  Mask << 1
  Next i
EndProcedure

Procedure.s enumere_repertoire(Directory$)
  Protected Dim fichiers_dans_repertoire.s(10000)
  Protected i_enumere.l = 0
  Protected string_renvoyer.s = "|DD"
  
  If ExamineDirectory(#repertoire, Directory$, "*.*")
    While NextDirectoryEntry(#repertoire)
      If DirectoryEntryType(#repertoire) = #PB_DirectoryEntry_File ; si fichier
        fichiers_dans_repertoire(i_enumere) = DirectoryEntryName(#repertoire)
        i_enumere + 1
      Else ; si repertoire
        If chiffre_depart = 0 And DirectoryEntryName(#repertoire) <> "."
          string_renvoyer = string_renvoyer + "?d.."
          chiffre_depart = 1
        EndIf
        If DirectoryEntryName(#repertoire) <> "."
          string_renvoyer = string_renvoyer + "?d" + DirectoryEntryName(#repertoire)
        EndIf  
      EndIf
    Wend
    FinishDirectory(#repertoire)
    For x_enumere = 0 To i_enumere-1
      string_renvoyer = string_renvoyer + "?f" + fichiers_dans_repertoire(x_enumere)
    Next x_enumere
    OpenFile(#fichier,"c:\test.txt")
    WriteStringN(#fichier,string_renvoyer)
    CloseFile(#fichier)
    ProcedureReturn string_renvoyer
  EndIf
EndProcedure

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

Port = 5900
*Buffer = AllocateMemory(taille_buffer)

If CreateNetworkServer(#reseau, Port)

  MessageRequester("PureBasic - Server", "Server created (Port "+Str(Port)+").", 0)
  
  Repeat
    Delay(10)
    SEvent = NetworkServerEvent()
  
    If SEvent
    
      ClientID = EventClient()
  
      Select SEvent
      
        Case #PB_NetworkEvent_Connect
          ConnexionID = OpenNetworkConnection(IPString(GetClientIP(ClientID)), Port)

        Case #PB_NetworkEvent_Data
          FillMemory(*Buffer, taille_buffer)
          ReceiveNetworkData(ClientID, *Buffer, taille_buffer)
          
          If FindString(PeekS(*Buffer),"|chargeDD",1) = 1 ; si |chargeDD -> renvoi list des disque sur le pc
            If ClientID
              GetAllDrives()
              drive_tempo.s = "|chargerDD"
              For i=1 To nombre_disque
                drive_tempo = drive_tempo + "|" + Drive_Nom(i)
              Next i
              SendNetworkString(ConnexionID, drive_tempo)
            Else
              MessageRequester("","pas de ConnectionID")
            EndIf
          EndIf  
          
          If FindString(PeekS(*Buffer),"|DD",1) = 1 ; si |DD -> renvoi list des disque sur le pc
            SendNetworkString(ConnexionID,enumere_repertoire( Mid(PeekS(*Buffer),4,Len(PeekS(*Buffer))-3)))
          EndIf
          
          If FindString(PeekS(*Buffer),"|renvoi",1) = 1
            fichier.s = "c:\windows\explorer.exe"
            *buffer_fichier = AllocateMemory(FileSize(fichier) )
            ReadFile(#fichier,fichier)
            ReadData(#fichier,*buffer_fichier,FileSize(fichier) )
            MessageRequester("",Str(FileSize(fichier)))
            CloseFile(#fichier)
            SendNetworkData(ConnexionID, *buffer_fichier, FileSize(fichier) )
          EndIf
          
        Case #PB_NetworkEvent_File
          MessageRequester("PureBasic - Server", "Client "+Str(ClientID)+" has send a file via the network !", 0)
          ReceiveNetworkFile(ConnexionID, "C:\TEST_Network.ftp3")
  
        Case #PB_NetworkEvent_Disconnect
          MessageRequester("PureBasic - Server", "Client "+Str(ClientID)+" has closed the connection...", 0)
          Quit = 1
    
      EndSelect
    EndIf
    
  Until Quit = 1 
  
  MessageRequester("PureBasic - Server", "Click to quit the server.", 0)
  
  CloseNetworkServer(#reseau)
Else
  MessageRequester("Error", "Can't create the server (port in use ?).", 0)
EndIf

  
End   


Code CLIENT :

Code : Tout sélectionner

Enumeration
  #reseau
EndEnumeration

Enumeration
  #Window_transfert
EndEnumeration

Enumeration
  #ListView_trans_pclocal
  #Text_trans_pclocal
  #Text_trans_pcdistant
  #ListView_trans_pcdistant
  #Text_trans_message
  #ProgressBar_trans_fichier
  #ProgressBar_trans_total
  #Button_trans_envoi_fichier
  #Button_trans_reception_fichier
EndEnumeration

Enumeration
  #Font_Text_trans_pclocal
  #Font_Text_trans_pcdistant
EndEnumeration

Enumeration
  #fichier
EndEnumeration

; *********************** repertoire

Enumeration
  #Window_transfert
EndEnumeration

Enumeration
  #ListView_trans_pclocal
  #Text_trans_pclocal
  #Text_trans_pcdistant
  #ListView_trans_pcdistant
  #Text_trans_message
  #ProgressBar_trans_fichier
  #ProgressBar_trans_total
  #Button_trans_envoi_fichier
  #Button_trans_reception_fichier
  #repertoire
EndEnumeration

Enumeration
  #Font_Text_trans_pclocal
  #Font_Text_trans_pcdistant
EndEnumeration

DataSection
  Image_ButtonImage_1:
    IncludeBinary ".\dossier.ico"
  Image_ButtonImage_2:
    IncludeBinary ".\fichier.ico"
EndDataSection
  
Global Port = 5900

Global Dim type_fichier.b(200000)
Global fichier_a_recuperer.s
Global ClientID.l

repertoire_de_depart.s = ""


Procedure OpenWindow_Window_transfert()
  If OpenWindow(#Window_transfert, 0, 0, 683, 508, "Transferts", #PB_Window_SizeGadget|#PB_Window_TitleBar|#PB_Window_SystemMenu)
    ExplorerListGadget(#ListView_trans_pclocal, 0, 30, 260, 415,"",#PB_Explorer_MultiSelect)
    TextGadget(#Text_trans_pclocal, 75, 0, 100, 20, "PC LOCAL")
    TextGadget(#Text_trans_pcdistant, 485, 5, 120, 20, "PC DISTANT")
    ListIconGadget(#ListView_trans_pcdistant, 420, 30, 260, 415,"small icon",240,#PB_ListIcon_MultiSelect)
    TextGadget(#Text_trans_message, 0, 445, 680, 20, "Message d'envoi", #PB_Text_Border|#PB_Text_Center)
    ProgressBarGadget(#ProgressBar_trans_fichier, 0, 465, 680, 20, 0, 100, #PB_ProgressBar_Smooth)
    ProgressBarGadget(#ProgressBar_trans_total, -5, 485, 685, 20, 0, 100, #PB_ProgressBar_Smooth)
    ButtonGadget(#Button_trans_envoi_fichier, 270, 160, 140, 25, "Envoi des fichiers >>>")
    ButtonGadget(#Button_trans_reception_fichier, 270, 220, 140, 25, "<<< Reception des fichiers")
    ; Gadget Fonts
    SetGadgetFont(#Text_trans_pclocal, LoadFont(#Font_Text_trans_pclocal, "Microsoft Sans Serif", 14, #PB_Font_Bold|#PB_Font_HighQuality))
    SetGadgetFont(#Text_trans_pcdistant, LoadFont(#Font_Text_trans_pcdistant, "Microsoft Sans Serif", 14, #PB_Font_Bold|#PB_Font_HighQuality))
  EndIf
  SetClassLong_(WindowID(#Window_transfert), #GCL_STYLE, GetClassLong_(WindowID(#Window_transfert), #GCL_STYLE) | #CS_DBLCLKS)
EndProcedure

Procedure.s repertoire_retour(repertoire$)
  nom_temporaire.s
  For k_1=1 To 70
    If StringField(repertoire$, k_1, "\") = ""
      For k_2 = 1 To k_1-2
        nom_temporaire = nom_temporaire + StringField(repertoire$, k_2, "\")
        nom_temporaire = nom_temporaire + "\"
      Next k_2
      ProcedureReturn nom_temporaire
    EndIf
  Next k_1
EndProcedure

Procedure lecteurs_initiaux(recup_init.s)
  ClearGadgetItems(#ListView_trans_pcdistant)
  drive.s
  For i=3 To 26
    drive = StringField(recup_init,i,"|")
    If drive <> ""
      AddGadgetItem(#ListView_trans_pcdistant,-1,drive,ImageID(CatchImage(#PB_Any, ?Image_ButtonImage_1)))
    EndIf
  Next i
EndProcedure

Procedure recuperation_fichier(valeur)
  SetGadgetText(#Text_trans_message,"Envoi en cours")
  WindowEvent()
  transfert_fichier = 1
  ReceiveNetworkFile(ClientID, "C:\TEST_Network.ftp3")
  SetGadgetText(#Text_trans_message,Str( FileSize("C:\TEST_Network.ftp3") ) )
  transfert_fichier = 0
EndProcedure

; **************** repertoire

Global taille_buffer.l = 4096


OpenWindow_Window_transfert()

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

*Buffer = AllocateMemory(taille_buffer)

ConnectionID = OpenNetworkConnection("10.19.10.1", Port) ; adresse ou l'on se connecte
If ConnectionID
  SendNetworkString(ConnectionID, "|chargeDD")
Else
  MessageRequester("PureBasic - Client", "Serveur distant introuvable.", 0)
  End
EndIf

Global pour_test.l = 0

If CreateNetworkServer(#reseau, Port)
;  MessageRequester("PureBasic - Server", "Server created (Port "+Str(Port)+").", 0)
EndIf

Repeat
  Delay(10)
  
  event = WindowEvent()
  SEvent = NetworkServerEvent()
  
  Select event
    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Window_transfert
        CloseWindow(#Window_transfert)
        Quit = 1 
      EndIf
    Case  #WM_LBUTTONDBLCLK
      If GetGadgetState(#ListView_trans_pcdistant) <> -1
        If type_fichier(GetGadgetState(#ListView_trans_pcdistant)) = 0 ; (si repertoire)
          If GetGadgetItemText(#ListView_trans_pcdistant,GetGadgetState(#ListView_trans_pcdistant)) <> ".." ; si pas ..
            repertoire_de_depart = repertoire_de_depart + GetGadgetItemText(#ListView_trans_pcdistant,GetGadgetState(#ListView_trans_pcdistant)) + "\"
            SendNetworkString(ConnectionID, "|DD" + repertoire_de_depart)
          Else
            repertoire_de_depart = repertoire_retour(repertoire_de_depart)
            If Len(repertoire_de_depart) > 0
              SendNetworkString(ConnectionID, "|DD" + repertoire_de_depart)
            Else
              SendNetworkString(ConnectionID, "|chargeDD")
            EndIf
            retour_attente:
            SEvent = NetworkServerEvent()
            If SEvent <> #PB_NetworkEvent_Data
              Goto retour_attente
            EndIf
          EndIf 
        Else ; si fichier
          MessageRequester("","reception")
          fichier_a_recuperer = "|renvoi" + repertoire_de_depart + GetGadgetItemText(#ListView_trans_pcdistant,GetGadgetState(#ListView_trans_pcdistant))
          SendNetworkString(ConnectionID, fichier_a_recuperer)
        EndIf
      EndIf

  EndSelect 
  
    If SEvent
      
      ClientID = EventClient()
  
      Select SEvent
        Case #PB_NetworkEvent_Connect
;          MessageRequester("PureBasic - Server", "Connexion nouveau client ! " + Str(ConnectionID) + "  Port :" + Str(GetClientPort(ConnectionID)), 0)
  
        Case #PB_NetworkEvent_Data
;          MessageRequester("","client - reception")
          FillMemory(*Buffer,taille_buffer)
          NbReAlloc = 1
          res.l
          Debug "********"
          Repeat
            res = ReceiveNetworkData(ClientID, *Buffer + ((NbReAlloc - 1) * taille_buffer),  taille_buffer)
            Debug res
;            If res = taille_buffer
              NbReAlloc + 1
              *Buffer = ReAllocateMemory(*Buffer, NbReAlloc * taille_buffer)
;            EndIf
          Until NetworkServerEvent() <> #PB_NetworkEvent_Data
          

          OpenFile(#fichier,"c:\fichier.txt")
          FileSeek(#fichier,Lof(#fichier))
          WriteString(#fichier,PeekS(*Buffer))
          CloseFile(#fichier)

          If FindString(PeekS(*Buffer),"|chargerDD")
            lecteurs_initiaux(PeekS(*Buffer))
          ElseIf FindString(PeekS(*Buffer),"|DD")
            tempo.s = PeekS(*Buffer)
            ClearGadgetItems(#ListView_trans_pcdistant)
            For i = 2 To 10000
              If StringField(tempo,i,"?") <> ""
                If Mid( StringField(tempo,i,"?") , 1,1) = "d"
                  AddGadgetItem(#ListView_trans_pcdistant,-1,Mid( StringField(tempo,i,"?") , 2, Len( StringField(tempo,i,"?") )-1   ),ImageID(CatchImage(#PB_Any, ?Image_ButtonImage_1)))
                EndIf
                If Mid( StringField(tempo,i,"?") , 1,1) = "f"
                  type_fichier(i-2) = 1
                  AddGadgetItem(#ListView_trans_pcdistant,-1,Mid( StringField(tempo,i,"?") , 2, Len( StringField(tempo,i,"?") )-1   ),ImageID(CatchImage(#PB_Any, ?Image_ButtonImage_2)))
                EndIf
                
              EndIf
            Next i
;            FillMemory(*Buffer, taille_buffer)

          EndIf
;          FreeMemory(*Buffer)

          
        Case #PB_NetworkEvent_File
          MessageRequester("PureBasic - Server", "Client "+Str(ClientID)+" has send a file via the network !", 0)
          CreateThread(@recuperation_fichier(),1)
          
        Case #PB_NetworkEvent_Disconnect
          MessageRequester("PureBasic - Server", "Client "+Str(ClientID)+" deconnecter du client.", 0)
          Quit = 1
    
      EndSelect
    EndIf
    
  Until Quit = 1 
J'ai mis les 2 fichiers icones ici : http://hlm05.free.fr/pb

Si vous voulez tester, prenez 2 de vos pc qui arrivent a communiquer en reseau (c'est le minimum :) ), lancer le serveur sur l'un sans modifier le code et modifier dans le client la ligne :

Code : Tout sélectionner

ConnectionID = OpenNetworkConnection("10.19.10.1", Port) ; adresse ou l'on se connecte
En mettant l'adresse de votre pc qui a lancé le serveur.

En fait, mon exemple va tenter de copier le fichier c:\windows\explorer.exe du pc SERVEUR vers le pc CLIENT quand vous cliquez 2 fois sur un fichier.

Si vous n’êtes pas bloqué, vous devriez arriver sur une fenêtre avec des transfert possible.
Si vous choisissez, a droite, d'aller dans C:\ puis essayer de cliquer sur un fichier, le transfert va s’exécuter.
Et la est le problème. Il va se lancer mais ne va jamais récupérer l’intégralité de explorer.exe. Il peut bloquer a 10Ko ou 500Ko, mais ne va jamais au bout.

En fait, je pense que le réseau (au boulot) est tellement lent (si, si, 5 Ko/s, c'est très lent) qu'il envoi bien le fichier sur le réseau, mais finit par se perdre.

Quelqu'un connaitrait une solution ?

Je sais, le sujet est très long, mais la, je sèche.

Re: probleme entre ReceiveNetworkData et SendNetworkData

Publié : mar. 09/oct./2012 16:36
par Golfy
Sans entrer dans les détails de ton code :
1) tu a mis un thread, donc pense à compiler avec la bonne option
2) tu mémorises le fichier complet à transmettre, peut-être vaudrait-il mieux le lire par bloc s'il dépasse une certaine taille ?
3) dans le client, plutôt qu'un delay(10) puis windowevent(), préferrer waitwindowevent(10)
4) attention aux goto (bon ça, ça dépend des programmeurs)

Après, il faut que je creuse...

[Edit]
pendant que j'y suis, je ne suis pas sûr que cela fonctionne :

Code : Tout sélectionner

WriteString(#fichier,PeekS(*Buffer))
En effet, une chaine doit se terminer par un chr(0), c'est à dire un caractère NULL... or, il est certain que dans le buffer, tu auras plusieurs caractères NULL.
Pour ma part, j'aurais plutôt utilisé WriteData(#Fichier, *Buffer, Longueur) :roll:

Re: probleme entre ReceiveNetworkData et SendNetworkData

Publié : mar. 09/oct./2012 20:23
par supercdfr
Après quelques heures, j'ai réussi a la faire marcher (merci VMWARE qui permet de regler le debit de son reseau).
Voici les 2 codes corrigés :

code CLIENT :

Code : Tout sélectionner

Enumeration
  #reseau
EndEnumeration

Enumeration
  #Window_transfert
EndEnumeration

Enumeration
  #ListView_trans_pclocal
  #Text_trans_pclocal
  #Text_trans_pcdistant
  #ListView_trans_pcdistant
  #Text_trans_message
  #ProgressBar_trans_fichier
  #ProgressBar_trans_total
  #Button_trans_envoi_fichier
  #Button_trans_reception_fichier
EndEnumeration

Enumeration
  #Font_Text_trans_pclocal
  #Font_Text_trans_pcdistant
EndEnumeration

Enumeration
  #fichier
EndEnumeration

; *********************** repertoire

Enumeration
  #Window_transfert
EndEnumeration

Enumeration
  #ListView_trans_pclocal
  #Text_trans_pclocal
  #Text_trans_pcdistant
  #ListView_trans_pcdistant
  #Text_trans_message
  #ProgressBar_trans_fichier
  #ProgressBar_trans_total
  #Button_trans_envoi_fichier
  #Button_trans_reception_fichier
  #repertoire
EndEnumeration

Enumeration
  #Font_Text_trans_pclocal
  #Font_Text_trans_pcdistant
EndEnumeration

DataSection
  Image_ButtonImage_1:
    IncludeBinary ".\dossier.ico"
  Image_ButtonImage_2:
    IncludeBinary ".\fichier.ico"
EndDataSection
  
Global Port = 5900

Global Dim type_fichier.b(200000)
Global fichier_a_recuperer.s
Global ClientID.l

repertoire_de_depart.s = ""
Global test_taille.l = 0
Global taille_buffer.l = 4096


Procedure OpenWindow_Window_transfert()
  If OpenWindow(#Window_transfert, 0, 0, 683, 508, "Transferts", #PB_Window_SizeGadget|#PB_Window_TitleBar|#PB_Window_SystemMenu)
    ExplorerListGadget(#ListView_trans_pclocal, 0, 30, 260, 415,"",#PB_Explorer_MultiSelect)
    TextGadget(#Text_trans_pclocal, 75, 0, 100, 20, "PC LOCAL")
    TextGadget(#Text_trans_pcdistant, 485, 5, 120, 20, "PC DISTANT")
    ListIconGadget(#ListView_trans_pcdistant, 420, 30, 260, 415,"small icon",240,#PB_ListIcon_MultiSelect)
    TextGadget(#Text_trans_message, 0, 445, 680, 20, "Message d'envoi", #PB_Text_Border|#PB_Text_Center)
    ProgressBarGadget(#ProgressBar_trans_fichier, 0, 465, 680, 20, 0, 100, #PB_ProgressBar_Smooth)
    ProgressBarGadget(#ProgressBar_trans_total, -5, 485, 685, 20, 0, 100, #PB_ProgressBar_Smooth)
    ButtonGadget(#Button_trans_envoi_fichier, 270, 160, 140, 25, "Envoi des fichiers >>>")
    ButtonGadget(#Button_trans_reception_fichier, 270, 220, 140, 25, "<<< Reception des fichiers")
    ; Gadget Fonts
    SetGadgetFont(#Text_trans_pclocal, LoadFont(#Font_Text_trans_pclocal, "Microsoft Sans Serif", 14, #PB_Font_Bold|#PB_Font_HighQuality))
    SetGadgetFont(#Text_trans_pcdistant, LoadFont(#Font_Text_trans_pcdistant, "Microsoft Sans Serif", 14, #PB_Font_Bold|#PB_Font_HighQuality))
  EndIf
  SetClassLong_(WindowID(#Window_transfert), #GCL_STYLE, GetClassLong_(WindowID(#Window_transfert), #GCL_STYLE) | #CS_DBLCLKS)
EndProcedure

Procedure.s repertoire_retour(repertoire$)
  nom_temporaire.s
  For k_1=1 To 70
    If StringField(repertoire$, k_1, "\") = ""
      For k_2 = 1 To k_1-2
        nom_temporaire = nom_temporaire + StringField(repertoire$, k_2, "\")
        nom_temporaire = nom_temporaire + "\"
      Next k_2
      ProcedureReturn nom_temporaire
    EndIf
  Next k_1
EndProcedure

Procedure lecteurs_initiaux(recup_init.s)
  ClearGadgetItems(#ListView_trans_pcdistant)
  drive.s
  For i=3 To 26
    drive = StringField(recup_init,i,"|")
    If drive <> ""
      AddGadgetItem(#ListView_trans_pcdistant,-1,drive,ImageID(CatchImage(#PB_Any, ?Image_ButtonImage_1)))
    EndIf
  Next i
EndProcedure

Procedure recuperation_fichier(taille_a_recuperer.l)
  taille_en_cours.l = 0
  OpenFile(#fichier,GetGadgetText(#ListView_trans_pclocal) + GetGadgetItemText(#ListView_trans_pcdistant,GetGadgetState(#ListView_trans_pcdistant)) )
  *Buffer = AllocateMemory(taille_buffer)
  Repeat
    NetworkServerEvent()
    NbReAlloc = 1
    taille_tempo.l = ReceiveNetworkData(ClientID, *Buffer,  taille_buffer)
    If taille_tempo <> -1
      taille_en_cours = taille_en_cours + taille_tempo
      WriteData(#fichier,*Buffer,taille_tempo)
          Debug taille_en_cours
          Debug taille_a_recuperer
          Debug "*************"
        EndIf
        FillMemory(*Buffer,taille_buffer)
      Until taille_en_cours >= taille_a_recuperer
      CloseFile(#fichier)
EndProcedure

; **************** repertoire


OpenWindow_Window_transfert()

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

*Buffer = AllocateMemory(taille_buffer)

ConnectionID = OpenNetworkConnection("192.168.102.129", Port) ; adresse ou l'on se connecte
If ConnectionID
  SendNetworkString(ConnectionID, "|chargeDD")
Else
  MessageRequester("PureBasic - Client", "Serveur distant introuvable.", 0)
  End
EndIf

Global pour_test.l = 0

If CreateNetworkServer(#reseau, Port)
;  MessageRequester("PureBasic - Server", "Server created (Port "+Str(Port)+").", 0)
EndIf

Repeat
  Delay(10)
  
  event = WindowEvent()
  Gevent = EventGadget()
  SEvent = NetworkServerEvent()
  
  If event = #PB_Event_CloseWindow
    EventWindow = EventWindow()
    If EventWindow = #Window_transfert
      CloseWindow(#Window_transfert)
      Quit = 1 
    EndIf
   EndIf
   If event = #WM_LBUTTONDBLCLK And Gevent = #ListView_trans_pcdistant
    If GetGadgetState(#ListView_trans_pcdistant) <> -1
      If type_fichier(GetGadgetState(#ListView_trans_pcdistant)) = 0 ; (si repertoire)
        If GetGadgetItemText(#ListView_trans_pcdistant,GetGadgetState(#ListView_trans_pcdistant)) <> ".." ; si pas ..
          repertoire_de_depart = repertoire_de_depart + GetGadgetItemText(#ListView_trans_pcdistant,GetGadgetState(#ListView_trans_pcdistant)) + "\"
          SendNetworkString(ConnectionID, "|DD" + repertoire_de_depart)
        Else
          repertoire_de_depart = repertoire_retour(repertoire_de_depart)
          If Len(repertoire_de_depart) > 0
            SendNetworkString(ConnectionID, "|DD" + repertoire_de_depart)
          Else
            SendNetworkString(ConnectionID, "|chargeDD")
          EndIf
          retour_attente:
          SEvent = NetworkServerEvent()
          If SEvent <> #PB_NetworkEvent_Data
            Goto retour_attente
          EndIf
        EndIf 
      Else ; si fichier
        fichier_a_recuperer = "|renvoi|" + repertoire_de_depart + GetGadgetItemText(#ListView_trans_pcdistant,GetGadgetState(#ListView_trans_pcdistant))
        SendNetworkString(ConnectionID, fichier_a_recuperer)
      EndIf
    EndIf
  EndIf
  
    If SEvent
      
      ClientID = EventClient()
  
      Select SEvent
        Case #PB_NetworkEvent_Connect
          MessageRequester("PureBasic - Server", "Connexion nouveau client ! " + Str(ConnectionID) + "  Port :" + Str(GetClientPort(ConnectionID)), 0)
  
        Case #PB_NetworkEvent_Data
          FillMemory(*Buffer,taille_buffer)
          NbReAlloc = 1
          res.l
          Repeat
            res = ReceiveNetworkData(ClientID, *Buffer + ((NbReAlloc - 1) * taille_buffer),  taille_buffer)
            test_taille + res
            NbReAlloc + 1
            *Buffer = ReAllocateMemory(*Buffer, NbReAlloc * taille_buffer)
          Until NetworkServerEvent() <> #PB_NetworkEvent_Data

          If FindString(PeekS(*Buffer),"|chargerDD",1)
            lecteurs_initiaux(PeekS(*Buffer))
          ElseIf FindString(PeekS(*Buffer),"|DD",1)
            tempo.s = PeekS(*Buffer)
            ClearGadgetItems(#ListView_trans_pcdistant)
            For i = 2 To 10000
              If StringField(tempo,i,"?") <> ""
                If Mid( StringField(tempo,i,"?") , 1,1) = "d"
                  AddGadgetItem(#ListView_trans_pcdistant,-1,Mid( StringField(tempo,i,"?") , 2, Len( StringField(tempo,i,"?") )-1   ),ImageID(CatchImage(#PB_Any, ?Image_ButtonImage_1)))
                EndIf
                If Mid( StringField(tempo,i,"?") , 1,1) = "f"
                  type_fichier(i-2) = 1
                  AddGadgetItem(#ListView_trans_pcdistant,-1,Mid( StringField(tempo,i,"?") , 2, Len( StringField(tempo,i,"?") )-1   ),ImageID(CatchImage(#PB_Any, ?Image_ButtonImage_2)))
                EndIf
              EndIf
            Next i
            FillMemory(*Buffer, NbReAlloc * taille_buffer)
          ElseIf FindString(PeekS(*Buffer),"|taille" ,1)
            recuperation_fichier( Val(StringField(PeekS(*Buffer),3,"|")) )
          EndIf

        Case #PB_NetworkEvent_Disconnect
          MessageRequester("PureBasic - Server", "Client "+Str(ClientID)+" deconnecter du client.", 0)
          Quit = 1
    
      EndSelect
    EndIf
    
  Until Quit = 1 
Code serveur :

Code : Tout sélectionner

Enumeration
  #reseau
  #repertoire
  #fichier
EndEnumeration

Global taille_buffer.l = 4096
Global Dim Drive_Nom.s(25),nombre_disque
Global adresse_ip_client.s
Global ConnexionID.l

Procedure GetAllDrives()
  MaskDrive = GetLogicalDrives_()
  Mask      = 1                 
  lpFileSystemNameBuffer.s = Space(256)
  nombre_disque=0
  For i.l = 65 To 97
    If MaskDrive & Mask
      wNom$=Chr(i)+":\"
      wNom2$ = Chr(i) + ":"
      wType=GetDriveType_(WNom$)
      If wtype=#DRIVE_FIXED
        nombre_disque=nombre_disque+1
        Drive_Nom(nombre_disque)= wNom2$
      EndIf
    EndIf
  Mask << 1
  Next i
EndProcedure

Procedure.s enumere_repertoire(Directory$)
  Protected Dim fichiers_dans_repertoire.s(10000)
  Protected i_enumere.l = 0
  Protected string_renvoyer.s = "|DD"
  
  If ExamineDirectory(#repertoire, Directory$, "*.*")
    While NextDirectoryEntry(#repertoire)
      If DirectoryEntryType(#repertoire) = #PB_DirectoryEntry_File ; si fichier
        fichiers_dans_repertoire(i_enumere) = DirectoryEntryName(#repertoire)
        i_enumere + 1
      Else ; si repertoire
        If chiffre_depart = 0 And DirectoryEntryName(#repertoire) <> "."
          string_renvoyer = string_renvoyer + "?d.."
          chiffre_depart = 1
        EndIf
        If DirectoryEntryName(#repertoire) <> "."
          string_renvoyer = string_renvoyer + "?d" + DirectoryEntryName(#repertoire)
        EndIf  
      EndIf
    Wend
    FinishDirectory(#repertoire)
    For x_enumere = 0 To i_enumere-1
      string_renvoyer = string_renvoyer + "?f" + fichiers_dans_repertoire(x_enumere)
    Next x_enumere
    OpenFile(#fichier,"c:\test.txt")
    WriteStringN(#fichier,string_renvoyer)
    CloseFile(#fichier)
    ProcedureReturn string_renvoyer
  EndIf
EndProcedure

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

Port = 5900
*Buffer = AllocateMemory(taille_buffer)

If CreateNetworkServer(#reseau, Port)

  MessageRequester("PureBasic - Server", "Server created (Port "+Str(Port)+").", 0)
  
  Repeat
    Delay(10)
    SEvent = NetworkServerEvent()
  
    If SEvent
    
      ClientID = EventClient()
  
      Select SEvent
      
        Case #PB_NetworkEvent_Connect
          ConnexionID = OpenNetworkConnection(IPString(GetClientIP(ClientID)), Port)
          MessageRequester("PureBasic - Server", "Connexion nouveau client ! " + Str(ConnectionID) + "  Port :" + Str(GetClientPort(ConnectionID)), 0)

        Case #PB_NetworkEvent_Data
          FillMemory(*Buffer, taille_buffer)
          ReceiveNetworkData(ClientID, *Buffer, taille_buffer)
          
          If FindString(PeekS(*Buffer),"|chargeDD",1) = 1 ; si |chargeDD -> renvoi list des disque sur le pc
            If ClientID
              GetAllDrives()
              drive_tempo.s = "|chargerDD"
              For i=1 To nombre_disque
                drive_tempo = drive_tempo + "|" + Drive_Nom(i)
              Next i
              SendNetworkString(ConnexionID, drive_tempo)
            Else
              MessageRequester("","pas de ConnectionID")
            EndIf
          EndIf  
          
          If FindString(PeekS(*Buffer),"|DD",1) = 1 ; si |DD -> renvoi list des disque sur le pc
            SendNetworkString(ConnexionID,enumere_repertoire( Mid(PeekS(*Buffer),4,Len(PeekS(*Buffer))-3)))
          EndIf
          
          If FindString(PeekS(*Buffer),"|renvoi",1) = 1
            fichier.s = "c:\str\gds32.dll"
            *buffer_fichier = AllocateMemory(FileSize(fichier) )
            ReadFile(#fichier,fichier)
            ReadData(#fichier,*buffer_fichier,FileSize(fichier) )
            MessageRequester("",Str(FileSize(fichier)))
            CloseFile(#fichier)
            SendNetworkData(ConnexionID, *buffer_fichier, FileSize(fichier) )
          EndIf
  
        Case #PB_NetworkEvent_Disconnect
          MessageRequester("PureBasic - Server", "Client "+Str(ClientID)+" has closed the connection...", 0)
          Quit = 1
    
      EndSelect
    EndIf
    
  Until Quit = 1 
  
  MessageRequester("PureBasic - Server", "Click to quit the server.", 0)
  
  CloseNetworkServer(#reseau)
Else
  MessageRequester("Error", "Can't create the server (port in use ?).", 0)
EndIf
En gros :
- le client envoi le nom du fichier a recuperer
- le serveur renvoi en retour la taille et attends 1 seconde.
- pendant cette seconde, le client a recuperer la taille et attends le reste du serveur
- le serveur envoi par petit paquet le fichier.
- tant que le fichier n'est pas complet, on scrute le reseau en boucle.

C'est pas trés propre, ca peut certainement bloquer (je rajouterais un timeout plus tard), mais au moins, ca fonctionne.
Il faudrait que les auteurs de purebasic renvoie leur instruction ReceiveNetworkFile, parceque je suis pas le 1er a avoir des soucis avec.

En tout cas, merci Golfy, Ca m'a bien aidé.