Page 1 of 1

Waiting for Network Server Events

Posted: Sun May 21, 2006 2:35 am
by lee__48
Hi all. I'm writing a server type program. It all works okay, but the program makes the CPU usage go up to 100% and everything else runs slowly. I assume it has something to do with the NetworkServerEvent() on the loop, is there a way around this?

The code is below if it helps!
Lee

Code: Select all


IncludeFile "sqlite3.pb" ; Procedures to interface with SQLite3

OpenConsole()

If SQLite3_InitLib("sqlite3.dll") = #False
  PrintN("Couldn't initialize SQLite3 library.")
Else
  PrintN("SQLite3 library initialized.")

  ; Obtain a handle to the database
 Global dbHandle = SQLite3_OpenDatabase("d:\music.db")
  If dbHandle = 0
    PrintN("Couldn't connect to database.")
  Else
    PrintN("Connected to database.")
  EndIf
EndIf

CloseConsole()

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

cmd.s ; String used for SQLite commands
Define.s_RecordSet RS

Port = 54321
Buffer = AllocateMemory(1000)

If CreateNetworkServer(0, Port)
  Debug "Server created (Port "+Str(Port)+")."
  
  Repeat
    SEvent = NetworkServerEvent()
 
    If SEvent
      ClientID = EventClient()
  
      Select SEvent
      
        Case 1
          Debug "A new client has connected ! "+Str(ClientID)
          
        Case 2
          Debug "Client "+Str(ClientID)+" has send a packet !"
          ReceiveNetworkData(ClientID, Buffer, 1000)
          Command$ = PeekS(Buffer)
          Debug "Packet Reads: "+Command$
          Delay(1000)
          
          If Left(Command$, 3) = "GET"

            firstDot = -1
            For i = 1 To Len(Command$)
              If Mid(Command$, i, 1) = "."
                If firstDot = -1
                  firstDot=i
                EndIf
              EndIf
            Next i
  
            Command$ = Left(Command$, firstDot-1)
            Command$ = Mid(Command$, 5, Len(Command$)-4)
  
            SearchField$ = "SELECT path FROM tracks WHERE trackID='"+Command$+"'"
 
            ; Get number of rows
            If SQLite3_GetTable(SearchField$, dbHandle, @RS)
              If RS\Rows < 1
                Debug "SQLite3 Error:"+SQLite3_GetLastMessage() : End
              EndIf
  
              rows = RS\Rows                   
              SQLite3_GetTable(SearchField$, dbHandle, @RS)

              If rows = 1
                SQLite3_GetRowCol(1, 0, @RS): FileName$ = (RS\sValue)
                Debug "Requested: "+FileName$
              EndIf  
            EndIf
            
          ElseIf Left(Command$, 5) = "LIST."
              CopyFile("D:\music.db", GetTemporaryDirectory()+"temp.txt")
              FileName$=GetTemporaryDirectory()+"temp.txt"
              Debug "TempFile created."
              Debug "Database requested. "+FileName$
          EndIf
         
          Delay(1000)
          Debug "Sending requested file"
          SendNetworkFile(ClientID, FileName$)
          Debug "Requested file sent"

          If Left(Command$, 5) = "LIST."
            DeleteFile(GetTemporaryDirectory()+"temp.txt")
            Debug "Temporary file deleted."
          EndIf
          
        Case 4
          Debug "Client "+Str(ClientID)+" has closed the connection."
          ;Quit = 1
    
      EndSelect
    EndIf
    
  Until Quit = 1 
  
  Debug "Server shut down!"
  
  CloseNetworkServer(0)
Else
  Debug "Can't create the server."
EndIf

End

Posted: Sun May 21, 2006 2:45 am
by Matt
try adding a Delay(20) (you can change 20 around to what you please [it is in milliseconds]) before Until Quit = 1

Posted: Sun May 21, 2006 3:23 am
by Joakim Christiansen

Code: Select all

If SEvent
  ;do events
Else
  delay(2)
EndIf
:P

Posted: Sun May 21, 2006 9:26 am
by Tranquil
Or you can bind Network event messages to a window using WSAsyncSelect_() API command. Not that hard to use.

Posted: Sun May 21, 2006 11:54 am
by lee__48
Who'd have thought a 2ms delay would make it all better!!

@Tranquil: I assume you mean WSAAsyncSelect_() as WSAsyncSelect didn't come up with anything in Google! Do you have a small example? MSDN references are very confusing.

Lee

Posted: Sun May 21, 2006 3:31 pm
by Tranquil
#WM_NetWorkEvent = #WM_User +1

#FD_ALL = #FD_READ|#FD_WRITE|#FD_OOB|#FD_ACCEPT|#FD_CONNECT|#FD_CLOSE
WSAAsyncSelect_(l_socket, h_window, #WM_NetworkEvent, #FD_ALL)

l_socket is the socket you want to listen on (returned by ConnectionID()) and h_window is the window handle returned by WindowID().

If all goes right you will now receive #WM_NetWorkEvent as a Window-Message if there are datas in your network or any incoming connection on a server socket. One socket can only be assigned once. That means, you can not use WSAAsyncSelect_() twice on one socket.