Page 1 of 1
TCP Sockets - IRC
Posted: Sun Jun 25, 2023 10:04 pm
by Jestr
I have been using the language for a little bit now and have been getting the hang of it however, I have noticed continuity issues across older versions specifically with seldom touched-on topics/protocols such as IRC. IRC is relatively simple in its design using simple TCP sockets with modern servers supporting connections without TLS.
I ask today whether there are any good resources to learn low-level networking using PureBasic? IRC WebSockets Telnet SNMP and so on?
Re: TCP Sockets - IRC
Posted: Sun Jun 25, 2023 10:06 pm
by jassing
Jestr wrote: Sun Jun 25, 2023 10:04 pm
I have been using the language for a little bit now and have been getting the hang of it however, I have noticed continuity issues across older versions specifically with seldom touched-on topics/protocols such as IRC. IRC is relatively simple in its design using simple TCP sockets with modern servers supporting connections without TLS.
I ask today whether there are any good resources to learn low-level networking using PureBasic? IRC WebSockets Telnet SNMP and so on?
Using PB for these things is easy. It's following the relevant RFC that you need to focus on. Follow those and you should be good. It's all "send this" and "receive that" and know how to respond in a timely fashion.
maybe this will get you started?
irc
http://forums.purebasic.com/english/vie ... =13&t=5539
telnet
viewtopic.php?t=33819&sid=1a52eae426805 ... e46be4264a
snmp
http://forums.purebasic.com/english/vie ... hp?t=77943
Re: TCP Sockets - IRC
Posted: Sun Jun 25, 2023 10:11 pm
by Jestr
Yeah with IRC it's very straightforward with a lot of it falling on the user at the client with commands like /join and back in the day before auto-login with /login . I'm looking for anyone that has implemented similar protocols to act as a good base to learn from. Like I said I have been having trouble finding good resources that are up to date enough to match the newer syntax. I'm looking for examples OpenNetworkConnection and SenNetworkData/String's usage.
Re: TCP Sockets - IRC
Posted: Thu Jun 29, 2023 9:40 pm
by RichAlgeni
Here are a couple of simple programs that communicate with each other. Take a look, try them out, then feel free to ask any questions. Run the test_server process first, and enter the port number you wish to use. Then run the test_client process, and do the same.
Code: Select all
; test_server.pb
EnableExplicit
Procedure ProcessRequest(connectNumber.i)
Protected result.l
Protected length.i
Protected *memoryLocation
Protected memLength.i = 32767
Protected lastRecv.i = Date()
Protected doNotExit.i = #True
Protected socketHandle.i = ConnectionID(connectNumber)
PrintN("Client " + Str(connectNumber) + " connected")
*memoryLocation = AllocateMemory(memLength)
; loop until we have received data, or our timeout has been exceeded
While doNotExit
result = ioctlsocket_(socketHandle, #FIONREAD, @length)
If result = 0 And length > 0
Debug "result = " + Str(result) + ", length received Data = " + Str(length)
result = ReceiveNetworkData(connectNumber.i, *memoryLocation, memLength.i)
Select result
Case 1 To 32767
PrintN("Client " + Str(connectNumber) + " received " + PeekS(*memoryLocation, result))
Case 0
Default
PrintN("Client " + Str(connectNumber) + " received socket error:" + Str(result) + ", " + Str(WSAGetLastError_()))
doNotExit = #False
EndSelect
If Date() - lastRecv > 5
doNotExit = #False
EndIf
ElseIf result = 0 And length = 0
Delay(100)
Else
PrintN("Client " + Str(connectNumber) + " received socket error:" + Str(result) + ", " + Str(WSAGetLastError_()))
doNotExit = #False
EndIf
Wend
FreeMemory(*memoryLocation)
EndProcedure
Define NSEvent.i
Define keyPressed.s
Define portNumber.i
Define portString.s
Define thisClient.i
Define serverNumber.i
Define socketHandle.i
OpenConsole("Network Server Tester, Build:" + #PB_Editor_BuildCount)
PrintN("")
Print("Enter the server port number you wish to spawn: ")
portString = Input()
If portString = ""
CloseConsole()
End
EndIf
portNumber = Val(portString)
If portNumber < 1 Or portNumber > 65535
PrintN("Invalid port number entered: " + portString)
Input()
CloseConsole()
End
EndIf
serverNumber = CreateNetworkServer(#PB_Any, portNumber)
If serverNumber < 1
PrintN("Unable to spawn a server to port " + Str(portNumber))
Input()
End
EndIf
PrintN("Started Network Server on port " + Str(portNumber))
Repeat
NSEvent = NetworkServerEvent() ; if we receive data, it will be indicated here
Select NSEvent
Case #PB_NetworkEvent_Connect ; a socket has connected
Case #PB_NetworkEvent_Data ; raw data has been received
thisClient = EventClient() ; get the event client identifier
socketHandle = ConnectionID(thisClient)
PrintN("Received client connection from: " + IPString(GetClientIP(thisClient)))
ProcessRequest(thisClient) ; procedure to process incoming data
Break
Case #PB_NetworkEvent_Disconnect; a socket disconnected
Default ; no server event occurred
Delay(100) ; sleep so we don't hammer the processor
EndSelect
keyPressed = Inkey()
ForEver
PrintN("Exiting loop, will close the socket")
closesocket_(socketHandle)
PrintN("Returned from closing the socket, will attempt to close the server")
CloseNetworkServer(serverNumber)
PrintN("Returned from closing the server, will now end the progam")
CloseConsole()
Input()
End
; IDE Options = PureBasic 6.02 LTS (Windows - x64)
; ExecutableFormat = Console
; CursorPosition = 40
; FirstLine = 30
; Executable = test_server.exe
; DisableDebugger
; HideErrorLog
; CurrentDirectory = D:\dev\PureBasic\temp\
; CompileSourceDirectory
; EnableCompileCount = 1
; EnableBuildCount = 1
; EnableExeConstant
Code: Select all
; test_client.pb
EnableExplicit
Define length.i
Define result.i
Define errNumber.i
Define lenSendText.i
Define serverName.s
Define stringText.s
Define portNumber.i
Define portString.s
Define connectNumber.i
Define socketHandle.i
Define memLength.i = 10000
Define *memoryLocation = AllocateMemory(memLength + 1)
OpenConsole("Network Client Tester, Build:" + #PB_Editor_BuildCount)
PrintN("")
Print("Enter the IP Address or name of the server, or press <enter> for local host: ")
serverName = Input()
If serverName = ""
serverName = "localhost"
EndIf
Print("Enter the port number to connect to: ")
portString = Input()
If portString = ""
CloseConsole()
End
EndIf
portNumber = Val(portString)
If portNumber < 1 Or portNumber > 65535
PrintN("Invalid port number entered: " + portString)
Input()
CloseConsole()
End
EndIf
PrintN("Attempting to connect to Network Server at " + serverName + " on port " + Str(portNumber))
connectNumber = OpenNetworkConnection(serverName, portNumber)
If connectNumber < 1
errNumber = WSAGetLastError_()
PrintN("Unable to connect to localhost, port " + Str(portNumber))
PrintN("Winsock error = " + Str(errNumber))
Else
socketHandle = ConnectionID(connectNumber)
Repeat
result = ioctlsocket_(socketHandle, #FIONREAD, @length)
Debug "result = " + Str(result) + ", length received Data = " + Str(length)
If result = 0 And length > 0
result = ReceiveNetworkData(connectNumber, *memoryLocation, memLength)
If result > 0
PrintN("Received: " + PeekS(*memoryLocation, result))
ElseIf result < 0
PrintN("Received error " + Str(result) + ", " + WSAGetLastError_())
Break
EndIf
ElseIf result <> 0
PrintN("Received error " + Str(result) + ", " + WSAGetLastError_())
Break
EndIf
stringText = Input()
lenSendText = StringByteLength(stringText)
If lenSendText
stringText + #CRLF$
lenSendText + 2
result = SendNetworkData(connectNumber, @stringText, lenSendText)
If result <> lenSendText
PrintN("Received error " + Str(result) + ", " + WSAGetLastError_())
Break
EndIf
EndIf
Debug "lenSendText = " + Str(lenSendText)
ForEver
CloseNetworkConnection(connectNumber)
PrintN("Network sending complete, Press <enter> to exit")
EndIf
Input()
CloseConsole()
End
; IDE Options = PureBasic 6.02 LTS (Windows - x64)
; ExecutableFormat = Console
; CursorPosition = 69
; FirstLine = 18
; Executable = test_client.exe
; DisableDebugger
; HideErrorLog
; CurrentDirectory = \
; CompileSourceDirectory
; EnableCompileCount = 1
; EnableBuildCount = 1
; EnableExeConstant