Hello!
I'm trying to implement a TCP Sockets Server for use on my LAN.
I had written the shared code inside the Main Sub and it was working.
I tried to move the shared code inside a new code module. Since moving the code to another module, I can't connect to the socket server. Init sub is called from Main.
The sockets created are derived from a Class module.
What am I doing wrong?
Note that I need every socket running at its own thread!
Thank you in advance!
The shared module code:
The Class code:
I'm trying to implement a TCP Sockets Server for use on my LAN.
I had written the shared code inside the Main Sub and it was working.
I tried to move the shared code inside a new code module. Since moving the code to another module, I can't connect to the socket server. Init sub is called from Main.
The sockets created are derived from a Class module.
What am I doing wrong?
Note that I need every socket running at its own thread!
Thank you in advance!
The shared module code:
B4X:
Sub Process_Globals
'Global statistics.
Private intActiveClients As Int
Private intMessages As Int
Private intBytes As Int
Public srvListener As ServerSocket
Public IsListening As Boolean
Dim intPort As Int
Private lstClients As List
End Sub
Private Sub srvListener_NewConnection(Successful As Boolean, NewSocket As Socket)
Dim intClient As Int
Dim RMC As RMClient
Dim FoundAvailable As Boolean
Dim intActualClient As Int
Dim NewClient As RMClient
If Successful Then
'Socket1 = NewSocket
For intClient = 0 To lstClients.Size - 1
RMC = lstClients.Get(intClient)
If Not(RMC.InUse) Then
FoundAvailable = True
'Hack needed here to emulate action of
'an "Exit For" statement:
intActualClient = intClient
intClient = lstClients.Size - 1
End If
Next
If Not(FoundAvailable) Then
intActualClient = intClient
NewClient.Initialize(Me, "Client", intActualClient)
lstClients.Add(NewClient)
RMC = NewClient
End If
RMC.NewConnection(NewSocket)
intActiveClients = intActiveClients + 1
Log("Client " & intActualClient & " connected")
Else
Log("Connection attempt failed: " & LastException.Message)
End If
srvListener.Listen
End Sub
Public Sub RMClient_Input(strMsg As String)
Dim intClient As Int
Dim Client As RMClient
intMessages = intMessages + 1
For intClient = 0 To lstClients.Size - 1
Client = lstClients.Get(intClient)
If Client.InUse Then
Client.Write(strMsg & Chr(0x0d))
End If
Next
End Sub
Private Sub RMClient_Bytes(ReceivedByteCount As Int)
intBytes = intBytes + ReceivedByteCount
Log(intBytes)
End Sub
Public Sub Init
intPort = 61999
srvListener.Initialize(intPort, "srvListener")
srvListener.Listen
Log("Listening on port " & intPort)
lstClients.Initialize
IsListening = True
End Sub
Private Sub StopServer
Dim intClient As Int
Dim Client As RMClient
For intClient = 0 To lstClients.Size - 1
Client = lstClients.Get(intClient)
If Client.InUse Then
Client.Close
End If
Next
srvListener.Close
IsListening = False
End Sub
The Class code:
B4X:
Private Sub Class_Globals
'PseudoConsts:
Private DELIMITER As String = Chr(0x0d) 'CR.
Private ENCODING As String = "WINDOWS-1253"
Private INPUT_STREAM_FALLBACK As Int = 18000
Private INPUT_STREAM_MAX As Int = 22000 'This can be ineffective if not
'greater than underlying socket
'buffer length (normally 8192
'bytes).
Private mParent As Object
Private mEventName As String
Private mIndex As Int
Private mInput As String
Private mInUse As Boolean
Private mLastError As String
Public mClientType As Int ' 1 = Statuses, 2 = WorkStations, 3 = AnswerStatuses
Private mClientBase As String ' CD_BASE
Private sckClient As Socket
Private astmClient As AsyncStreams
Private sbAssemStm As StringBuilder 'Assembled input stream buffer.
Private Strings As JStringFunctions
End Sub
Public Sub Initialize(Parent As Object, EventName As String, Index As Int)
mParent = Parent
mEventName = EventName
mIndex = Index
Strings.Initialize
End Sub
Public Sub getIndex() As Int
Return mIndex
End Sub
Public Sub getInput() As String 'Valid during Input event.
Return mInput
End Sub
Public Sub getInUse() As Boolean
Return mInUse
End Sub
Public Sub getLastError() As String
Return mLastError
End Sub
Public Sub Close()
astmClient.Close
sckClient.Close
sckClient = Null
CallSub2(mParent, mEventName & "_Terminated", Me)
mInUse = False
End Sub
Public Sub NewConnection(NewSocket As Socket)
mLastError = ""
sckClient = NewSocket
sbAssemStm.Initialize
astmClient.Initialize(sckClient.InputStream, sckClient.OutputStream, "astmClient")
mInUse = True
End Sub
Public Sub Write(Output As String)
Dim mCMesg As String
Dim mCBase As String
Try
'Log(Output)
'Log(mClientType)
Select Case mClientType
Case 1
astmClient.Write(Output.GetBytes(ENCODING))
'astmClient.Write(DELIMITER.GetBytes(ENCODING))
End Select
Catch
Log("Error Client Write!")
End Try
End Sub
Private Sub astmClient_Error()
mLastError = LastException.Message
CallSub2(mParent, mEventName & "_Error", Me)
Log(mLastError)
Close
End Sub
Private Sub astmClient_NewData(Buffer() As Byte)
Dim Frag As String
Dim Msgs As String
Dim Pos As Int
Dim DelimPos As Int
Dim RmID As String
Dim RmMesg As String
CallSub2(mParent, mEventName & "_Bytes", Buffer.Length)
Frag = BytesToString(Buffer, 0, Buffer.Length, ENCODING)
If sbAssemStm.Length > INPUT_STREAM_MAX Then
sbAssemStm.Remove(INPUT_STREAM_FALLBACK, sbAssemStm.Length)
End If
sbAssemStm.Append(Frag)
If Frag.Contains(DELIMITER) Then
Msgs = sbAssemStm.ToString
Pos = 0
Do Until DelimPos < 0
DelimPos = Msgs.IndexOf2(DELIMITER, Pos)
If DelimPos >= 0 Then
mInput = Msgs.SubString2(Pos, DelimPos)
RmID = Strings.SplitGetWord(mInput, ",", 1)
RmMesg = Strings.SplitGetWord(mInput, ",", 2)
Log(mInput)
PushShared.SendWebClientMessage(RmMesg, RmID)
mInput = ""
Pos = DelimPos + 1
End If
Loop
'Delete the processed messages from the assembled input stream,
'reinsert any leftover characters.
sbAssemStm.Initialize
sbAssemStm.Append(Msgs.SubString(Pos))
End If
End Sub
Private Sub astmClient_Terminated()
Close
End Sub