Telnet is simply a type of application protocol that runs on networks. All telnets use a network, but not all networks use telnet. Telnet at its most basic, utilizes control characters (ASCII 0-31 and/or ASCII 127-255) to add color, line control, page control, blinking and other attributes to terminal sessions. You can turn on a telnet client in Windows (Control Panel, Programs and Features, Turn Windows Features on or off).
What I did was that I wrote a generic TCP Network Reader and Writer procedures. I did the same for UDP. I then pass data to and from these procedures. I put these procedures in a PBI file, then I can include them as needed. For instance: Note that these are Windows ONLY procedures.
Code: Select all
; ------------------------------------------------------------
; Program name: network_procs.pbi
; Written by: Rich Algeni, Jr.
; Date written: 02/17/2011
;
; Purpose: to include network procedures into PB programs
;
; (c) Copyright 2015, Orion Tek Solutions, All rights reserved.
; ------------------------------------------------------------
; **********************************************************************************
; initialization of networking variables
; **********************************************************************************
Procedure.i InitializeNetwork()
Protected result.i
; add this program name and version to the list of includes the main program is running
AddElement(programList())
programList() = "network_procs.pbi"
AddElement(progVersions())
progVersions() = "2.0.02b"
; define the structure we will use for connect and send
Structure connectSendData
csdHost.s
csdPort.i
csdText.s
csdLeng.i
EndStructure
; make sure we can initialize the network
result = InitNetwork()
Global hostName.s = Hostname()
ProcedureReturn result
EndProcedure
; **********************************************************************************
; this procedure set the TCP receive buffer size, and keepalive
; **********************************************************************************
Procedure.i SetTCPBufferSize(connectNumber.i, bufferSize.i)
Protected result.l = 0; winsock utlizes a 32 bit integer only!
Protected keepAlive.i = 1
Protected socketHandle.i = 0
socketHandle = ConnectionID(connectNumber)
result = setsockopt_(socketHandle, #SOL_SOCKET, #SO_RCVBUF, @bufferSize, SizeOf(bufferSize))
result = setsockopt_(socketHandle, #SOL_SOCKET, #SO_KEEPALIVE, @keepAlive, SizeOf(keepAlive))
ProcedureReturn result
EndProcedure
; **********************************************************************************
; process to open a client socket connection, and set the receive buffer size
; **********************************************************************************
ProcedureDLL.i OpenClientSocket(*socketNumber, *serverName, serverPortNumber.i, setBufferRecvSize.i, networkMode.i, openTimeout.i, *bindToIP, bindToPort.i)
Protected result.i
Protected logText.s
Protected socketNumber.i
Protected bindToIP.s = PeekS(*bindToIP)
Protected serverName.s = PeekS(*serverName)
; attempt to open the socket here, then poke in the result
socketNumber = OpenNetworkConnection(serverName, serverPortNumber, networkMode, openTimeout, bindToIP, bindToPort.i)
PokeI(*socketNumber, socketNumber)
; if the socket opened successfully, set the socket number, then the receive buffer size
If socketNumber > 0
If networkMode = #PB_Network_TCP
result = SetTCPBufferSize(socketNumber, setBufferRecvSize)
If result <> 0
logText = "OpenClientSocket() > SetTCPBufferSize() returned " + Str(result)
WriteToLog(@logText)
EndIf
EndIf
Else
logText = "OpenClientSocket() > Unable to open socket to " + serverName + " on port " + serverPortNumber
WriteToLog(@logText)
EndIf
; this procedure returns the socket number if the socket is open, the socket number is also Poked into *socketNumber
ProcedureReturn socketNumber
EndProcedure
; **********************************************************************************
; this procedure writes binary data to a network connection
; **********************************************************************************
Procedure.i NetworkWrite(connectNumber.i, *memoryLoc, lenSendText.i, *netSource, debugThis.i)
Protected totalSent.i = 0
Protected errNumber.i = 0
Protected errorText.s = ""
Protected lenToSend.i
Protected result.i
Protected length.i
If lenSendText < 1 Or *memoryLoc < 1; just in case
ProcedureReturn -999
EndIf
; try to send the data, loop until all done, or error encountered
While lenSendText > 0
If lenSendText > maxSendSize; make sure our packet size is not too large
lenToSend = maxSendSize
Else
lenToSend = lenSendText
EndIf
result = SendNetworkData(connectNumber, *memoryLoc + totalSent, lenToSend)
; if we've received an error, set the condition to get out of the loop
If result < 0
totalSent = result
lenSendText = 0
errNumber = WSAGetLastError_()
Else
totalSent = totalSent + result
lenSendText = lenSendText - result
If lenSendText
Delay(packetDelay)
EndIf
EndIf
Wend
; send the data we have transmitted to the debugger listing, or if needed the error
If debugThis
DebugString(*memoryLoc, totalSent, *netSource, #debugOut, errNumber, @errorText)
EndIf
ProcedureReturn totalSent
EndProcedure
; **********************************************************************************
; this procedure reads binary data from a network connection in one read attempt
; **********************************************************************************
Procedure.i NetworkRead(connectNumber.i, *memoryLoc, memLength.i, *netSource, debugThis.i, socketTimeout.i, maxReadTrys.i)
Protected socketHandle.i = 0
Protected attemptCount.i = 0
Protected amountRead.i = 0
Protected errNumber.i = 0
Protected length.i = 0
Protected result.l = 0; winsock utlizes a 32 bit integer only!
socketHandle = ConnectionID(connectNumber)
; loop until we have received data, or our timeout has been exceeded
Repeat
result = ioctlsocket_(socketHandle, #FIONREAD, @length)
; get out of the loop if ShutDownNow is true
If ShutDownNow
debugThis = #False
Break
EndIf
; if we encountered a socket error, we need to exit the loop
If result <> 0
errNumber = WSAGetLastError_()
amountRead = -1
Break
EndIf
; if nothing has been received, increment the attempt counter and sleep, else get out of the loop
If length = 0
attemptCount = attemptCount + 1
If attemptCount > maxReadTrys
Break
Else
Delay(socketTimeout)
EndIf
; else get the data in the network receive buffer
Else
amountRead = ReceiveNetworkData(connectNumber, *memoryLoc, memLength)
Break
EndIf
ForEver
; send the data we have read to the debugger listing, if needed
If debugThis
DebugString(*memoryLoc, amountRead, *netSource, #debugIn, errNumber, 0)
EndIf
; now return the amount we have received, if anything
ProcedureReturn amountRead
EndProcedure
; **********************************************************************************
; this procedure reads predefined fixed amount of binary data from a network connection
; **********************************************************************************
Procedure.i NetworkReadFixed(connectNumber.i, *memoryLoc, memLength.i, *netSource, debugThis.i, socketTimeout.i, maxReadTrys.i)
Protected socketHandle.i = 0
Protected attemptCount.i = 0
Protected amountRead.i = 0
Protected errNumber.i = 0
Protected length.i = 0
Protected result.l = 0; winsock utlizes a 32 bit integer only!
socketHandle = ConnectionID(connectNumber)
; loop until we have received the predetermined amount of data, or our timeout has been exceeded
Repeat
result = ioctlsocket_(socketHandle, #FIONREAD, @length)
; get out of the loop if ShutDownNow is true
If ShutDownNow
debugThis = #False
Break
EndIf
; if we encountered a socket error, we need to exit the loop
If result <> 0
errNumber = WSAGetLastError_()
amountRead = -1
Break
EndIf
; if nothing has been received, increment the attempt counter and sleep, else get out of the loop
If length = 0
attemptCount = attemptCount + 1
If attemptCount > maxReadTrys
Break
Else
Delay(socketTimeout)
EndIf
; else get the data in the network receive buffer
Else
result = ReceiveNetworkData(connectNumber, *memoryLoc + amountRead, memLength)
If result > 0
amountRead = amountRead + result
memLength = memLength - result
EndIf
If memLength <= 0
Break
EndIf
EndIf
ForEver
; send the data we have read to the debugger listing, if needed
If debugThis
DebugString(*memoryLoc, amountRead, *netSource, #debugIn, errNumber, 0)
EndIf
; now return the amount we have received, if anything
ProcedureReturn amountRead
EndProcedure
; **********************************************************************************
; this procedure writes binary data to a UDP network connection, never debug UDP writes
; **********************************************************************************
Procedure.i NetworkUDPWrite(connectNumber.i, *memoryLoc, lenSendText.i)
Protected lenToSend.i
If lenSendText < 1 Or *memoryLoc < 1; just in case
lenToSend = -999
Else
; we only send 2048 bytes total, and never received an error with UDP
If lenSendText > 2048
lenToSend = 2048
Else
lenToSend = lenSendText
EndIf
SendNetworkData(connectNumber, *memoryLoc, lenToSend)
EndIf
ProcedureReturn lenToSend
EndProcedure
; **********************************************************************************
; this procedure reads binary data from a UDP network connection, never debug UDP
; **********************************************************************************
Procedure.i NetworkUDPRead(connectNumber.i, *memoryLoc, memLength.i)
Protected result.i
; in theory, there are no socket errors with UDP
result = ReceiveNetworkData(connectNumber, *memoryLoc, memLength)
; now return the aounnt we have received, if anything
ProcedureReturn result
EndProcedure
Use as needed. As some of the work I do is for government entities, they require a copyright notice in all code I use. If you have any questions, just let me know.