Thanks to Mike S. for the help.
Below are two files, Thread.pb, and EchoServer.pb. They have been modified to run in Console Mode (Used jaPBe to edit, can compile but not debug, yet

). Also, the server will read and write lines now instead of bytes. And the server should not answer connection requests if it is maxed out now

Theoreticly (sp?) preventing the server from responding to DOS attacks by criminals. Also keeps the thread count down, hehe...
Events.pb and Common.pb is no longer needed. It also shaves off about 10k
EchoServer.pb
Code: Select all
;
; Catalyst SocketTools 4.5 Build 4520
; Copyright 1995-2006, Catalyst Development Corporation
; All rights reserved
;
; This example demonstrates how to create a simple server
; which echoes back any data that is sent to it.
;
EnableExplicit
; A global count of the number of active client sessions
Global g_nClientCount.l = 0
Global MAXCLIENTS.l = 100
; Include SocketTools header files
IncludeFile "cstools4.pbi"
IncludeFile "cserror4.pbi"
IncludeFile "cstkey4.pbi"
IncludeFile "thread.pb"
Define.l Event, WindowID, GadgetID, EventType
Define.l hServer = #INVALID_SOCKET
Define.l nResult, nIndex
Define.l nLocalAddress, nLocalPort, hSocket = #INVALID_SOCKET, hThread
Define.s{64} strAddress
Define.s{128} strError
Define.s KeyPressed
Dim nAddressList.l(32)
OpenConsole()
ConsoleTitle("Echo Server")
; Initialize the SocketTools API
If Not InetInitialize(#CSTOOLS4_LICENSE_KEY, #Null)
PrintN("Error: Unable to initialize SocketTools library")
Input()
End
EndIf
If hServer = #INVALID_SOCKET
strAddress = "000.000.000.000" ; <- Change This!
nLocalAddress = InetGetAddress(strAddress)
nLocalPort = 0000 ; <- Change This!
; Start listening for connections on that address and port
hServer = InetListen(nLocalAddress, nLocalPort)
If hServer = #INVALID_SOCKET
InetGetErrorString(InetGetLastError(), @strError, 128)
PrintN("ERROR: " + strError)
EndIf
PrintN("Listening for client connections on address " + strAddress + " port " + Str(nLocalPort))
EndIf
PrintN("Press ESC to quit ...")
Repeat ; Start of the event loop
KeyPressed = Inkey()
If g_nClientCount < MAXCLIENTS ; Only accept connections IF we are not @ our max!
hSocket = InetAccept(hServer, 1)
If hSocket <> #INVALID_SOCKET
hThread = CreateThread(@ClientThread(), hSocket)
If hThread = 0
PrintN("ERROR: Unable to create thread to accept client connection")
EndIf
EndIf
EndIf
Delay(1)
Until KeyPressed = Chr(27) ; Wait until escape is pressed
; If socket handle is valid, stop listening for connections
If hServer <> #INVALID_SOCKET
InetDisconnect(hServer)
hServer = #INVALID_SOCKET
EndIf
; Uninitialize the SocketTools library
InetUninitialize()
CloseConsole()
End
Thread.pb
Code: Select all
;
; Catalyst SocketTools 4.5 Build 4520
; Copyright 1995-2006, Catalyst Development Corporation
; All rights reserved
;
#BUFSIZE = 1024
#TIMEOUT = 10
Import "kernel32.lib"
GetCurrentThreadId.l()
InterlockedDecrement.l(*lpAddend.l)
InterlockedIncrement.l(*lpAddend.l)
EndImport
Procedure ClientThread(hClient.l)
Define.l nThreadId = 0
Define.l nPeerAddress, nPeerPort
Define.l nBytesRead, nBytesWritten
Define.l nError = 0
Define.s{128} strError
Define.s{64} strAddress;
Define.s{#BUFSIZE} strBuffer
; Get the current thread ID and increment the client count
; so we can track the number of clients that have connected
; to our server
nThreadId = GetCurrentThreadId()
; Attach socket to thread!
InetAttachThread(hClient, 0)
; Lock!
InterlockedIncrement(@g_nClientCount)
If hClient <> #INVALID_SOCKET
; If the connection has been accepted, get the address of the
; client who has connected to us
InetGetPeerAddress(hClient, @nPeerAddress, @nPeerPort)
InetFormatAddress(nPeerAddress, @strAddress, 64);
; Check to make sure that there aren't more clients running
; than the maximum specified by the user
If g_nClientCount > MAXCLIENTS
PrintN("ERROR: Too many active clients, rejecting connection from " + strAddress)
InetDisconnect(hClient)
InterlockedDecrement(@g_nClientCount)
ProcedureReturn
EndIf
; Update the ListView gadget
PrintN("Thread 0x" + Hex(nThreadId) + " accepting connection from " + strAddress)
Else
nError = InetGetLastError()
EndIf
; Read any data that has been sent by the client and write
; that data back to them.
While nError = 0
; Initialize nBytesRead to the maximum number of characters
; that can be stored in the string buffer
nBytesRead = #BUFSIZE
; Read a line of data, buffered up to the carriage-return/newline
If InetReadLine(hClient, @strBuffer, @nBytesRead)
; Some data has been read from the client, send it back
; exactly as we have read it
nBytesWritten = nBytesRead
If Not InetWriteLine(hClient, strBuffer, @nBytesWritten)
nError = InetGetLastError()
EndIf
Else
; An error has occurred. If the error indicates that the
; connection was closed by the client, then simply exit
; the loop. If the error is a timeout, then just go back
; to waiting for more data from the client. Otherwise
; report the error and terminate the connection.
nError = InetGetLastError()
If nError = #ST_ERROR_CONNECTION_CLOSED
nError = 0
Break
ElseIf nError = #ST_ERROR_OPERATION_TIMEOUT
nError = 0
EndIf
EndIf
Wend
If nError = 0
; No error has occurred, the client has closed its connection
PrintN("Thread 0x" + Hex(nThreadId) + " closing connection to client from " + strAddress)
Else
; An error has occurred, report it to the user
InetGetErrorString(nError, @strError, 128)
PrintN("ERROR: Thread 0x" + Hex(nThreadId) + " error " + Hex(nError) + ": " + strError)
EndIf
; Disconnect the client socket and decrement the count of
; active client sessions
InetDisconnect(hClient)
InterlockedDecrement(@g_nClientCount)
EndProcedure