Page 1 sur 1

mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 11:55
par celtic88
Salut! :) ;

Voilla je m explique :
j'essaie de créer un programme de communication "Tcp" entre serveur et client .

mon problème ci que mon programme ce bloque coté client et pas serveur sur la function "ReceiveNetworkData" ,sachant que j utilise les mem fonction de transfert et de recevoir les données avec les deux code ?

merci.

voila mes deux code
serveur

Code : Tout sélectionner

EnableExplicit

Structure TCPRdinfo
  PbConnectionid.i
  RecvThreadiD.i
  SendThreadiD.i
  RecvThreadMutex.i
  SendThreadMutex.i
  *PsendData
EndStructure

Global TCPInfo.TCPRdinfo\PbConnectionid = #False
Global RecevRate=1024
Global  ServerId
Global  PortListen=8888

Global  String_0 ,Window_0,Editor_0

Global PacketChat.s = "[Packet_Chat]"
Global EndPacket.s = "[End_Packet]" 

Procedure _TCP_Send_Data(*Coi.TCPRdinfo)
  Protected cOurMutex,Send,Sendinc,Sizedata
  Protected *cOurMem
  cOurMutex=*Coi\SendThreadMutex
  *cOurMem=*Coi\PsendData
  LockMutex(cOurMutex)
  Sizedata=MemorySize(*cOurMem)
  Repeat
    If *Coi\PbConnectionid = #False : Break : EndIf
    Send=  SendNetworkData(*Coi\PbConnectionid, *cOurMem+Sendinc,Sizedata)
    If Not Send  : Break : EndIf
    Sendinc+Send
  Until Sendinc=Sizedata
  FreeMemory(*cOurMem)
  UnlockMutex(cOurMutex)
EndProcedure 

Procedure _TCP_Recev_Data(*Coi.TCPRdinfo)
  Protected.s DataString,Selectdata,Datatype,Getdata
  Protected cOurMutex,Recv,Recvinc,ko
  Protected *Memalloc
  cOurMutex=*Coi\RecvThreadMutex
  LockMutex(cOurMutex)
  *Memalloc=AllocateMemory(RecevRate)
  If *Memalloc
    Repeat
      If *Coi\PbConnectionid = #False : Break : EndIf
      Recv=ReceiveNetworkData(*Coi\PbConnectionid, *Memalloc+Recvinc, RecevRate)
      ;If Not Recv  : Break : EndIf
      Recvinc+Recv
      If PeekS(*Memalloc+Recvinc-24,12,#PB_Unicode) = EndPacket
        Break
      Else
        *Memalloc=ReAllocateMemory(*Memalloc,Recvinc+RecevRate)
        If Not *Memalloc  : Break : EndIf
      EndIf
    ForEver
    If Recvinc > 0
      DataString=PeekS(*Memalloc,-1,#PB_Unicode)
      For ko=1 To CountString(DataString, EndPacket)
        Selectdata= StringField(DataString, ko, EndPacket)
        Datatype= Left(Selectdata,13)
        Getdata=Mid(Selectdata, 13+1) 
        
        Select Datatype
          Case PacketChat
            AddGadgetItem(Editor_0,-1,Getdata)
            
        EndSelect
        
      Next
    EndIf
    If *Memalloc : FreeMemory(*Memalloc) : EndIf
  EndIf
  UnlockMutex(cOurMutex)
EndProcedure 

Procedure _TCP_Send_String(*Coi.TCPRdinfo,Pstring.s)
  If *Coi\PbConnectionid
    If Not IsThread(*Coi\SendThreadiD)
      Protected Strlen=StringByteLength(Pstring, #PB_Unicode)
      *Coi\PsendData=AllocateMemory(Strlen+1)
      If *Coi\PsendData
        PokeS(*Coi\PsendData,Pstring,-1,#PB_Unicode)
        *Coi\SendThreadMutex=CreateMutex()
        *Coi\SendThreadiD=CreateThread(@_TCP_Send_Data(),*Coi)
      Else
        ProcedureReturn -3
      EndIf
    Else
      ProcedureReturn -2
    EndIf
  Else
    ProcedureReturn -1
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure _TCP_Server_Event_LOOp(*mOpt)
  Protected Getevettcp,GetServerId,GetClientId
  Repeat
    Delay(20)
    Getevettcp = NetworkServerEvent()
    If Getevettcp = #PB_NetworkEvent_None : Continue:EndIf
    GetServerId = EventServer()
    GetClientId = EventClient()
    Select Getevettcp
      Case #PB_NetworkEvent_Connect
        TCPInfo\PbConnectionid = GetClientId
        AddGadgetItem(Editor_0,-1,"Client is connected..")
      Case #PB_NetworkEvent_Data 
        If Not IsThread(TCPInfo\RecvThreadiD)
          TCPInfo\RecvThreadMutex=CreateMutex()
          TCPInfo\RecvThreadiD=CreateThread(@_TCP_Recev_Data(),@TCPInfo)
        EndIf
      Case #PB_NetworkEvent_Disconnect
        ClearStructure(@TCPInfo,TCPRdinfo)
        TCPInfo\PbConnectionid = #False
        AddGadgetItem(Editor_0,-1,"Client Disconnected..")
    EndSelect
  ForEver
EndProcedure

Procedure _SendTxt()
  Protected  GetTxt.s = GetGadgetText(String_0)
  If GetTxt = #NUL$ :ProcedureReturn:EndIf
  GetTxt= PacketChat+ GetTxt+EndPacket
  Protected  Sendmsg=_TCP_Send_String(@TCPInfo,GetTxt)
  Select Sendmsg
    Case -3
      Debug "Error ===> AllocateMemory()."
    Case -2
      MessageRequester("","waiting for client response..")
    Case -1
      MessageRequester("","No client!..")
  EndSelect
EndProcedure

Procedure _Exit()
  CloseNetworkServer(ServerId)
  End
EndProcedure

Window_0 = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 490,  410, "Server", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
BindEvent(#PB_Event_CloseWindow , @_Exit(),Window_0)
Editor_0 = EditorGadget(#PB_Any, 10, 10, 470, 340,#PB_Editor_ReadOnly)
String_0 = StringGadget(#PB_Any, 20, 370, 320, 25, "")
Define Button_1 = ButtonGadget(#PB_Any, 360, 370, 100, 25, "Send")
BindGadgetEvent(Button_1, @_SendTxt(), #PB_EventType_LeftClick ) 
SetActiveGadget(String_0)

If Not InitNetwork()
  Debug " Error fatal ===> InitNetwork()"
  End
EndIf

ServerId = CreateNetworkServer(#PB_Any, PortListen)
If  Not ServerId
  Debug " Error fatal ===> CreateNetworkServer()"
  End
EndIf
AddGadgetItem(Editor_0,-1,"Start listen on port : " + Str(PortListen))
CreateThread(@_TCP_Server_Event_LOOp(),0)

Repeat
  WaitWindowEvent()
ForEver
client

Code : Tout sélectionner

EnableExplicit

Structure TCPRdinfo
  PbConnectionid.i
  RecvThreadiD.i
  SendThreadiD.i
  RecvThreadMutex.i
  SendThreadMutex.i
  *PsendData
EndStructure

Global  String_0 ,Window_0,Editor_0

Global TCPInfo.TCPRdinfo\PbConnectionid = #False
Global RecevRate=1024

Global Ipconnect.s = "192.168.1.24"
Global PortConnect = 8888

Global PacketChat.s = "[Packet_Chat]"
Global EndPacket.s = "[End_Packet]" 

Procedure _TCP_Send_Data(*Coi.TCPRdinfo)
  Protected cOurMutex,Send,Sendinc,Sizedata
  Protected *cOurMem
  cOurMutex=*Coi\SendThreadMutex
  *cOurMem=*Coi\PsendData
  LockMutex(cOurMutex)
  Sizedata=MemorySize(*cOurMem)
  Repeat
    If *Coi\PbConnectionid = #False : Break : EndIf
    Send=  SendNetworkData(*Coi\PbConnectionid, *cOurMem+Sendinc,Sizedata)
    If Not Send  : Break : EndIf
    Sendinc+Send
  Until Sendinc=Sizedata
  FreeMemory(*cOurMem)
  UnlockMutex(cOurMutex)
EndProcedure 

Procedure _TCP_Recev_Data(*Coi.TCPRdinfo)
  Protected.s DataString,Selectdata,Datatype,Getdata
  Protected cOurMutex,Recv,Recvinc,ko
  Protected *Memalloc
  cOurMutex=*Coi\RecvThreadMutex
  LockMutex(cOurMutex)
  *Memalloc=AllocateMemory(RecevRate)
  If *Memalloc
    Repeat
      If *Coi\PbConnectionid = #False : Break : EndIf
      Recv=ReceiveNetworkData(*Coi\PbConnectionid, *Memalloc+Recvinc, RecevRate) ;<=== ici mon programme se bloque
      ;If Not Recv  : Break : EndIf
      Recvinc+Recv
      If PeekS(*Memalloc+Recvinc-24,12,#PB_Unicode) = EndPacket
        Break
      Else
        *Memalloc=ReAllocateMemory(*Memalloc,Recvinc+RecevRate)
        If Not *Memalloc  : Break : EndIf
      EndIf
    ForEver
    If Recvinc > 0
      DataString=PeekS(*Memalloc,-1,#PB_Unicode)
      For ko=1 To CountString(DataString, EndPacket)
        Selectdata= StringField(DataString, ko, EndPacket)
        Datatype= Left(Selectdata,13)
        Getdata=Mid(Selectdata, 13+1) 
        
        Select Datatype
          Case PacketChat
            AddGadgetItem(Editor_0,-1,Getdata)
            
        EndSelect
        
      Next
    EndIf
    If *Memalloc : FreeMemory(*Memalloc) : EndIf
  EndIf
  UnlockMutex(cOurMutex)
EndProcedure 

Procedure _TCP_Send_String(*Coi.TCPRdinfo,Pstring.s)
  If *Coi\PbConnectionid
    If Not IsThread(*Coi\SendThreadiD)
      Protected Strlen=StringByteLength(Pstring, #PB_Unicode)
      *Coi\PsendData=AllocateMemory(Strlen+1)
      If *Coi\PsendData
        PokeS(*Coi\PsendData,Pstring,-1,#PB_Unicode)
        *Coi\SendThreadMutex=CreateMutex()
        *Coi\SendThreadiD=CreateThread(@_TCP_Send_Data(),*Coi)
      Else
        ProcedureReturn -3
      EndIf
    Else
      ProcedureReturn -2
    EndIf
  Else
    ProcedureReturn -1
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure _TCP_Clien_Event_LOOp(*coPt)
  Protected Connectevent
  Repeat
    If TCPInfo\PbConnectionid 
      AddGadgetItem(Editor_0,-1,"Connection was successfully established with the server..")
      Repeat
        Delay(20)
        Connectevent = NetworkClientEvent(TCPInfo\PbConnectionid) 
        If Connectevent = #PB_NetworkEvent_None :Delay(20): Continue:EndIf
        Select Connectevent
          Case #PB_NetworkEvent_Data
            If Not IsThread(TCPInfo\RecvThreadiD)
              TCPInfo\RecvThreadMutex=CreateMutex()
              TCPInfo\RecvThreadiD=CreateThread(@_TCP_Recev_Data(),@TCPInfo)
            EndIf
          Case #PB_NetworkEvent_Disconnect
            ClearStructure(@TCPInfo,TCPRdinfo)
            TCPInfo\PbConnectionid = #False
            AddGadgetItem(Editor_0,-1,"Server is shutdown.." + #CRLF$ + "Trying to connect to server..")
            Break 1
        EndSelect
      ForEver
    Else
      TCPInfo\PbConnectionid = OpenNetworkConnection(Ipconnect, PortConnect) 
    EndIf
  ForEver
EndProcedure

Procedure _SendTxt()
  Protected  GetTxt.s = GetGadgetText(String_0)
  If GetTxt = #NUL$ :ProcedureReturn:EndIf
  GetTxt= PacketChat+ GetTxt+EndPacket
  Protected  Sendmsg=_TCP_Send_String(@TCPInfo,GetTxt)
  Select Sendmsg
    Case -3
      Debug "Error ===> AllocateMemory()."
    Case -2
      MessageRequester("","waiting for Server response..")
    Case -1
      MessageRequester("","Client is not connected to server!..")
  EndSelect
EndProcedure

Procedure _Exit()
  End
EndProcedure

Window_0 = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 490,  410, "Client", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
BindEvent(#PB_Event_CloseWindow , @_Exit(),Window_0)
Editor_0 = EditorGadget(#PB_Any, 10, 10, 470, 340,#PB_Editor_ReadOnly)
String_0 = StringGadget(#PB_Any, 20, 370, 320, 25, "")
Define Button_1 = ButtonGadget(#PB_Any, 360, 370, 100, 25, "Send")
BindGadgetEvent(Button_1, @_SendTxt(), #PB_EventType_LeftClick ) 
SetActiveGadget(String_0)

If Not InitNetwork()
  Debug " Error fatal ===> InitNetwork()"
  End
EndIf

AddGadgetItem(Editor_0,-1,"Connection to server was started..")
CreateThread(@_TCP_Clien_Event_LOOp(),0)

Repeat
  WaitWindowEvent()
ForEver

Re: mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 12:30
par falsam
Un truc bizarre, ton client reçoit les données quand ton serveur est down.

Essayes d'envoyer "test" depuis le serveur.
Le client de reçoit rien
Ferme ton serveur et le client reçoit "test"

Re: mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 12:49
par celtic88
oui car quand le serveur est déconnecté le client se débloque de "ReceiveNetworkData"?

Re: mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 12:59
par falsam
J'ai fait quelques chose du meme style que tes deux codes. Je n'ai pas de thread pour la gestion des connections.

Si ça peut t'aider tu peux downloader.

http://s242132022.onlinehome.fr/Downloa ... client.zip

Ton routeur va surement te demander d'autoriser la connexion pour connaitre tes adresses IP WAN + LAN.

Re: mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 13:07
par celtic88
je pense que c'est a cause de "timeout" de "tcp recv" ci non je vais utiliser les api

Re: mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 13:10
par falsam
celtic88 a écrit :je pense que c'est a cause de "timeout" de "tcp recv" ci non je vais utiliser les api
Des API ? Regarde mon code. C'est sans API et ça fonctionne.

Re: mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 13:12
par celtic88
merci @falsam je vais l'étudier

Re: mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 13:18
par falsam
Tu peux même tester une connexion jusqu'à 15:30 :)
IP : 80.13.208.109 Port 6832

Touche Entrée pour envoyer un message.

PS: Merci pour cette connexion Celtic. Trop tard pour les autres mais je peux réitérer ce test.

Re: mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 13:23
par celtic88
mai il faut i avoir une explication sur mon problème si non le signalé comme un bug par ce que a ma connaissance la function "ReceiveNetworkData" ni pas une function bloquante.

Re: mon programme se bloque avec "ReceiveNetworkData" ?

Publié : mer. 30/sept./2015 19:11
par case
je cite la doc de pure basic (ReceiveNetworkData)
Elle doit être appelée uniquement après avoir reçu un événement #PB_NetworkEvent_Data.