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:
Expand|Select|Wrap|Line Numbers
- 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
Expand|Select|Wrap|Line Numbers
- 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