Is someone able to replicate my problem (network)?

Everything else that doesn't fall into one of the other PB categories.
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Is someone able to replicate my problem (network)?

Post by Kukulkan »

Hi,

I create a small server (cancel with ESC). Please compile as console-app.

Code: Select all

; Server

InitNetwork()

OpenConsole()

PrintN("Server started!")

ServerID.l = CreateNetworkServer(1, 6002, #PB_Network_TCP)

While Quit.b = #False
  
  ; ####### check network data #######
  SEvent.l = NetworkServerEvent()
  CID.l = 0
  If SEvent.l <> 0
    CID.l = EventClient()
  EndIf
  
  Select SEvent.l
  
    Case #PB_NetworkEvent_Connect ; ####### new client #######
      ; PrintN("Connect " + Str(CID.l))
      
    Case #PB_NetworkEvent_Data
      ; PrintN("Data " + Str(CID.l))
      *NetworkBuffer.l  = AllocateMemory(8192)  ; 8 KB Puffer for Server
      ReceivedContent.s = ""
      length.l = ReceiveNetworkData(CID.l, *NetworkBuffer.l, 8192)
      If length.l > 0
        ReceivedContent.s = PeekS(*NetworkBuffer.l, length.l)
      EndIf
      FreeMemory(*NetworkBuffer.l)
      
      If ReceivedContent.s <> ""
        ; calculate something
        PrintN("Did some job. " + FormatDate("%yyyy/%mm/%dd %hh:%ii:%ss", Date()))
        For x.l = 1 To 50000
          e.l = Random(1000)
        Next
        SendNetworkString(CID.l, "Result is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc")
        CloseNetworkConnection(CID.l)
      EndIf
      
    Case #PB_NetworkEvent_Disconnect
      
  EndSelect
  
  If Inkey() = Chr(27): Quit.b = #True: EndIf
  
  Delay(1)
  
Wend

CloseNetworkServer(1)

PrintN(" ")
PrintN("FINISHED SERVER")

End
Additional, there is a small client application needed. This one creates a connection, sends something, waits for the result, validates the result and closes the connection. And this in a endless loop.

This is the small client (cancel with ESC). Please compile as console-app.

Code: Select all

; Client

lngTimeoutSeconds.l = 5

InitNetwork()

OpenConsole()

PrintN("Client started!")

While Quit.b = #False
  
  Conn.l = OpenNetworkConnection("127.0.0.1", 6002)
  
  If Conn.l <> 0
    ; send request
    SendNetworkString(Conn.l, "Hey, do some job...")
  
    StartTime.l = ElapsedMilliseconds() + (lngTimeoutSeconds.l * 1000)
    Result.s = ""
    
    Repeat
      *NetworkBuffer.l = AllocateMemory(8192)  ; 8 KB Puffer for Server
      length.l = ReceiveNetworkData(Conn.l, *NetworkBuffer.l, 8192)
      If length.l > 0
        Result.s = Result.s + PeekS(*NetworkBuffer.l, length.l)
      EndIf
      FreeMemory(*NetworkBuffer.l)
    Until Len(Result.s) > 2 Or ElapsedMilliseconds() > StartTime.l Or Quit.b = #True
    
    If ElapsedMilliseconds() > StartTime.l
      PrintN("TIMEOUT!")
    EndIf
    
    CloseNetworkConnection(Conn.l)
    
    If Result.s <> "Result is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc"
      PrintN("FAILED!")
    EndIf
  Else
    ; no connection possible!
    PrintN("no connection possible!")
  EndIf
  
  Delay(1)
  
  If Inkey() = Chr(27): Quit.b = #True: EndIf
  
Wend

PrintN(" ")
PrintN("FINISHED CLIENT")

CloseConsole()

End
At the beginning, everything works fine. After a while, the client responses "no connection possible!". This is getting more and more bad. It does not help to restart the client. I need to restart the server to fix this.

What is my misstake? Is there an error in the code? I do not manage to pass my performance-tests because of this error.

After a while, sometimes, the server does not accept connections. Is there something wrong? Did I miss something? Something to cleanup?

Kukulkan
PMV
Enthusiast
Enthusiast
Posts: 727
Joined: Sat Feb 24, 2007 3:15 pm
Location: Germany

Re: Is someone able to replicate my problem (network)?

Post by PMV »

I have disabled all compiler options and let it running for hours
... one client, one server ... no problem.
Windows 7 Professional x64, PureBasic v4.51 x86.

MFG PMV
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Is someone able to replicate my problem (network)?

Post by Kukulkan »

Thank you PMV,

but with a completely fresh and restarted system, the error comes after 30 or 40 seconds and getting more worse each start. In compiled form, the error occures sometimes directly after a few seconds (PureBasic 4.51 / 32 bit)

It is a 32bit Windows XP (SP3) system with no additional firewalls or exotic settings. No networking tweaks or any other things. The virus-scanner has been disabled.

Kukulkan
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Is someone able to replicate my problem (network)?

Post by Kukulkan »

I replicated the problem again on another system. Now, the compiled versions have been started on a Windows XP SP2 using Atom Chipset (Netbook). The same result. After about 30 to 50 seconds, the first problems start...

[UPDATE]The problem does not occur on a System with Windows 7!!! Is it a problem on XP systems?[/UPDATE]

Is this possible????

Kukulkan
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Is someone able to replicate my problem (network)?

Post by TerryHough »

I tested on a Windows XP Pro system. It ran without problem for over 10 minutes in 3 separated tests.

However, I don't think it is a XP problem.

The server could use some tweaking for speed, but is basically OK. You are wasting time allocating and freeing memory and emptying the ReceivedContent string. You should let the client break the connection after it receives the data instead of having the server break the connection immediately after sending the data. Here is my quick cleanup:

Code: Select all

; Server

*NetworkBuffer.l  = AllocateMemory(8192)  ; 8 KB Buffer for Server

InitNetwork()

OpenConsole()

ServerID.l = CreateNetworkServer(1, 6002, #PB_Network_TCP)
PrintN("Server started!")

While Quit.b = #False
  
  ; ####### check network data #######
  SEvent.l = NetworkServerEvent()
  CID.l = EventClient()
  
  Select SEvent.l
      
    Case #PB_NetworkEvent_Connect ; ####### new client #######
      ; PrintN("Connect " + Str(CID.l))
      
    Case #PB_NetworkEvent_Data
      length.l = ReceiveNetworkData(CID.l, *NetworkBuffer.l, 8192)
      If length.l > 0
        ReceivedContent.s = PeekS(*NetworkBuffer.l, length.l)
        
        If ReceivedContent.s <> ""
          ; calculate something
          PrintN("Did some job. " + FormatDate("%yyyy/%mm/%dd %hh:%ii:%ss", Date()))
          For x.l = 1 To 50000
            e.l = Random(1000)
          Next
          SendNetworkString(CID.l, "Result is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc")
        EndIf
      EndIf
      
    Case #PB_NetworkEvent_Disconnect
      ;PrintN("A client disconnected")
      
  EndSelect
  
  If Inkey() = Chr(27): Quit.b = #True: EndIf
  
  Delay(1)
Wend

CloseNetworkServer(1)

PrintN(" ")
PrintN("FINISHED SERVER")

End
The client code needs work. As soon as you connect and send data to the server, you are banging the server to receive data without checking to see if data is available. Not too visible when both run on the same machine, but across a network you would get some real problems and delays.

Recode the client to work based on NetworkClientEvents (similar to your server code) and it would be much improved. Be sure to have the client break the connection after receiving the expected data.
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Is someone able to replicate my problem (network)?

Post by Kukulkan »

Hi TerryHough,

thank you very much for your help and the good tips. The problem is, that, in the final product, the calling clients are not only PureBasic applications. There are PHP and Perl-Applications doing calls, too. And I fear, that PHP may try to re-use a connection and does not close the channel. But the server application is meant to do one job each connection (it is a very special cryptographic job). I thought, the closing by the server is more relieable...

Btw, I now have four different XP installations that all are showing the same error... WTF :shock:

Kukulkan
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Is someone able to replicate my problem (network)?

Post by TerryHough »

I still haven't been able to duplicate your problem with your code here on XP Pro.

I believe the problem is caused by your client code not being based on events.

Try the following to see if it resolves the problem:

Code: Select all

; Client

lngTimeoutSeconds.l = 5
*NetworkBuffer.l = AllocateMemory(8192)  ; 8 KB Buffer for Server

InitNetwork()

OpenConsole()

PrintN("Client started!")

While Quit.b = #False
  
  Conn.l = OpenNetworkConnection("127.0.0.1", 6002)
  
  If Conn.l <> 0
    ; send request
    SendNetworkString(Conn.l, "Hey, do some job...")
    
    StopTime.l = ElapsedMilliseconds() + (lngTimeoutSeconds.l * 1000)
    
    Repeat
      SendChk = NetworkClientEvent(Conn)
      
      Select SendChk
          
        Case #PB_NetworkEvent_Data ; Raw data has been received
          length.l = ReceiveNetworkData(Conn.l, *NetworkBuffer.l, 8192)
          If length.l > 0
            Result.s = PeekS(*NetworkBuffer.l, length.l)
            If Result.s <> "Result is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc"
              PrintN("FAILED!")
            Else 
              PrintN("Results received")
            EndIf
            Break 
          EndIf
          
        Case 0 ; Nothing has happened
          
        Case #PB_NetworkEvent_File ; A file has been received - Not used here
          
      EndSelect
      If ElapsedMilliseconds() > StopTime.l  ; limit to 5 seconds (lngTimeoutSeconds.l)
        PrintN("TIMEOUT!")
        Break 
      EndIf
    ForEver 
    
    CloseNetworkConnection(Conn.l)
    
  Else
    ; no connection possible!
    PrintN("no connection possible!")
  EndIf
  
  If Inkey() = Chr(27): Quit.b = #True: EndIf
  
Wend

PrintN(" ")
PrintN("FINISHED CLIENT")

CloseConsole()

End
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Is someone able to replicate my problem (network)?

Post by Kukulkan »

Hi TerryHough,

thank you for your version. I try'd this and the result is quite the same. The limit is reached after about 30 to 40 seconds. Then the client(s) start to print "TIMEOUT" and "no connection" messages.

Currently, I was pointed to this page http://smallvoid.com/article/winnt-tcpip-max-limit.html on the german forum. I will try, if one of this values may help. Especially those parameters seem to be interesting for this problem:

[HKEY_LOCAL_MACHINE \System \CurrentControlSet \services \Tcpip \Parameters] TcpTimedWaitDelay
[HKEY_LOCAL_MACHINE \SYSTEM \CurrentControlSet \Services \Tcpip \Parameters] EnableConnectionRateLimiting
[HKEY_LOCAL_MACHINE \System \CurrentControlSet \services \Tcpip \Parameters] TcpTimedWaitDelay

I will try to change those values and report the result here...

Kukulkan
Post Reply