I am creating a small server client program that is meant for up to 70 connections from 70 different computers on a network.
Everything in the program functions correctly except when testing operations with a server crash, the clients go into a disconnected state and wait for the server to come back up.
Once the server is up the clients attept to connect. 75% of the time all clients connect and there connect message is accepted and parsed without a problem then they are added to a clients hash table, the other 25% the server still connects all clients but thier connect message is not accepted or parsed so they are not added to the client hash table, maybe missine one or two, the clients sent the connect string but its as if the server never got the message. I have no clue how to remedy this. Here is some sample code hopefully enough to explain the process. Thanks to all I'm losing my mind on this.
Server:
Client:
Hopefully this is enough to help understand. I appreciate everything anyone can help me with.
Everything in the program functions correctly except when testing operations with a server crash, the clients go into a disconnected state and wait for the server to come back up.
Once the server is up the clients attept to connect. 75% of the time all clients connect and there connect message is accepted and parsed without a problem then they are added to a clients hash table, the other 25% the server still connects all clients but thier connect message is not accepted or parsed so they are not added to the client hash table, maybe missine one or two, the clients sent the connect string but its as if the server never got the message. I have no clue how to remedy this. Here is some sample code hopefully enough to explain the process. Thanks to all I'm losing my mind on this.
Server:
Code:
Private listener As TcpListener
Private listenerthread As Threading.Thread
Public Shared statusdict As New Hashtable
Public Shared clients As New Hashtable
Private Sub AdminForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'**********************************************************************
'SOCKET CONNECTION SECTION
listenerthread = New Threading.Thread(AddressOf DoListen)
listenerthread.Start()
Updatestatus("Listener Started")
'**********************************************************************
End Sub
Private Sub DoListen()
Try
' Listen for new connections.
listener = New TcpListener(System.Net.IPAddress.Any, config.PortNumber)
listener.Start()
Do
' Create a new user connection using TcpClient returned by
Dim client As New UserConnection(listener.AcceptTcpClient)
' Create an event handler to allow the UserConnection to communicate with the window.
AddHandler client.LineReceived, AddressOf OnLineReceived
Updatestatus("New connection found: waiting for log-in")
Loop Until False
Catch ex As Exception
'error handling
End Try
End Sub
Private Sub ConnectUser(ByVal workstation As String, ByVal sender As UserConnection)
Try
If Not clients.Contains(workstation) Then
sender.WS = workstation
'
'adds connected ws to hashtable
clients.Add(workstation, sender)
'sends connected to client
ReplyToSender("CONNECTED|" sender)
End If
Catch ex As Exception
'MsgBox(Environment.StackTrace.ToString)
End Try
End Sub
Private Sub OnLineReceived(ByVal sender As UserConnection, ByVal data As String)
Dim dataArray() As String
Dim clientcount As Integer = clients.Count
' Message parts are divided by "|" Break the string into an array accordingly.
dataArray = data.Split(Chr(124))
' dataArray(0) is the command.
Try
Select Case dataArray(0)
Case "CONNECT"
'when connect is sent from client, the ws is the dataarray(1)
Try
Updatestatus(dataArray(1) & " has connected.")
ConnectUser(dataArray(1), sender)
Catch ex As Exception
'some error processing
End Try
Case "RECSTATUS"
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'creates and updates a separete hashtable for display of ws status
Try
If Not statusdict.ContainsKey(sender.WS) Then
statusdict.Add(sender.WS, dataArray(3))
Else
statusdict.Item(sender.WS) = dataArray(3)
End If
Catch ex As Exception
MsgBox(ex)
WriteError.WriteErrorFile(Me.Name.ToString, ex.ToString(), True, True, True, True)
End Try
End Select
Catch ex As Exception
' WriteError.WriteErrorFile(Me.Name.ToString, ex.ToString(), True, True, True, True)
End Try
End select
End sub
Private Sub Updatestatus(ByVal statusmessage As String)
lstStatus.Items.Add(statusmessage)
'lstStatus.SelectedIndex = lstStatus.Items.Count - 1
End Sub
Public Shared Sub ReplyToSender(ByVal strmessage As String, ByVal sender As UserConnection)
Try
sender.SendData(strmessage)
Catch ex As Exception
'MsgBox("1 " & Environment.StackTrace.ToString)
End Try
End Sub
Code:
Dim currentstatus As String = ""
Dim oldstatus As String = ""
Dim conncount As Integer = 0
Const READ_BUFFER_SIZE As Integer = 255
Private client As TcpClient
Private readbuffer(READ_BUFFER_SIZE) As Byte
Private Sub clientform_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
MakeConnection(Nothing)
End Sub
Public Sub MakeConnection(ByVal callingfunc As String)
Try
If callingfunc <> "MarkAsDisconnected" Then
Me.Show()
End If
Do
Try
client = New TcpClient()
client.Connect("localhost", 6000)
Me.Enabled = True
Label1.BackColor = Color.Green
Catch e As Exception
Label1.BackColor = Color.Red
End Try
Loop Until client.Connected = True
' Start an asynchronous read invoking DoRead to avoid lagging the user
' interface.
client.GetStream.BeginRead(readbuffer, 0, READ_BUFFER_SIZE, AddressOf DoRead, Nothing)
' If callingfunc <> "MarkAsDisconnected" Then 'attempt to make it recheck for connection and reconnect
SendCMD("CONNECT|" & System.Environment.MachineName)
Catch e As Exception
Me.Dispose()
End Try
End Sub
Private Sub DoRead(ByVal ar As IAsyncResult)
Dim BytesRead As Integer
Dim strMessage As String
Try
' Finish asynchronous read into readBuffer and return number of bytes read.
BytesRead = client.GetStream.EndRead(ar)
If BytesRead < 1 Then
' If no bytes were read server has close. Disable input window.
MarkAsDisconnected()
Exit Sub
End If
' Convert the byte array the message was saved into, minus two for the
' Chr(13) and Chr(10)
strMessage = Encoding.ASCII.GetString(readbuffer, 0, BytesRead - 2)
ProcessCommands(strMessage)
' Start a new asynchronous read into readBuffer.
client.GetStream.BeginRead(readbuffer, 0, READ_BUFFER_SIZE, AddressOf DoRead, Nothing)
Catch e As Exception
MarkAsDisconnected()
End Try
End Sub
Private Sub MarkAsDisconnected()
conncount = 1
oldstatus = currentstatus
MakeConnection("MarkAsDisconnected")
End Sub
Private Sub SendCMD(ByVal data As String)
Dim writer As New IO.StreamWriter(client.GetStream)
writer.Write(data & vbCr)
writer.Flush()
End Sub
Private Sub ProcessCommands(ByVal strMessage As String)
Dim dataArray() As String
' Message parts are divided by "|" Break the string into an array accordingly.
dataArray = strMessage.Split(Chr(124))
If dataArray(0) = "CONNECTED" Or dataArray(0) = "LOCKED" Or _
dataArray(0) = "LOGGEDIN" Or dataArray(0) = "LOGGEDOUT" Then
currentstatus = dataArray(0)
End If
Select Case dataArray(0)
Case "CONNECTED"
Label1.BackColor = Color.Green
If conncount = 0 Then
'sends status connected, but dont want to log on recon
SendCMD("RECSTATUS|CONNECTED|" & System.Environment.MachineName.ToString)
ElseIf conncount = 1 Then
currentstatus = oldstatus
SendCMD("RECSTATUS|" & currentstatus & "|" & System.Environment.MachineName.ToString)
conncount = 0
End If
Case Else
MsgBox("no message")
End Select
End Sub