How can I detect that my client disconnected?

Lioth

New member
Joined
Sep 1, 2009
Messages
2
Programming Experience
1-3
Hi, I'm a beginning .NET programmer and learning the system.net.sockets class atm. The program works fine (start server, each client can join, and broadcast to everyone), but I don't seem to find how to detect that my client is disconnected. Here is my code:

THE SERVER CONSOLE
VB.NET:
Imports System.Net
Imports System.Net.Sockets
Imports System.Text

Module Server

    Private vServerSocket As New TcpListener(IPAddress.Any, 13713)
    Private vClientSocket As TcpClient
    Private vClientList As New Hashtable
    Private vClient As Client
    Private vItem As DictionaryEntry
    Private vNetworkStream As NetworkStream
    Private vBytesFrom(13713) As Byte
    Private vDataFrom As String

    Public Sub Main()
        StartServer()
    End Sub

    Private Sub StartServer()
        vServerSocket.Start()
        Message("Server Started")
        Do
            ConnectClient()
        Loop
    End Sub

    Private Sub ConnectClient()
        vClientSocket = vServerSocket.AcceptTcpClient
        vNetworkStream = vClientSocket.GetStream
        vNetworkStream.Read(vBytesFrom, 0, CInt(vClientSocket.ReceiveBufferSize))
        vDataFrom = Encoding.ASCII.GetString(vBytesFrom)
        vDataFrom = vDataFrom.Substring(0, vDataFrom.IndexOf("~"))
        vClientList(vDataFrom) = vClientSocket
        Message(vDataFrom & " joined")
        Broadcast(vDataFrom & " joined", vDataFrom, False)
        vClient = New Client
        vClient.StartClient(vClientSocket, vDataFrom, vClientList)
    End Sub

    Public Sub Broadcast(ByVal vMessage As String, ByVal vUser As String, ByVal vFlag As Boolean)
        For Each vItem In vClientList
            Dim tSocket As TcpClient
            tSocket = CType(vItem.Value, TcpClient)
            Dim tStream As NetworkStream = tSocket.GetStream
            Dim tBytes As Byte()
            If vFlag = True Then
                tBytes = Encoding.ASCII.GetBytes(vUser & " says: " & vMessage)
            Else
                tBytes = Encoding.ASCII.GetBytes(vMessage)
            End If
            tStream.Write(tBytes, 0, tBytes.Length)
            tStream.Flush()
        Next
    End Sub

    Public Sub Message(ByVal vMessage As String)
        Console.WriteLine(vMessage)
    End Sub

End Module

THE CLIENT CLASS (SERVER)
VB.NET:
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading

Public Class Client

    Private vClientSocket As TcpClient
    Private vClientList As Hashtable
    Private vNetworkStream As NetworkStream
    Private vBytesFrom(13713) As Byte
    Private vNr As String
    Private vDataFrom As String

    Public Sub StartClient(ByVal tClientSocket As TcpClient, ByVal tNr As String, ByVal tClientList As Hashtable)
        Me.vClientSocket = tClientSocket
        Me.vNr = tNr
        Me.vClientList = tClientList
        Dim vThread As Thread = New Thread(AddressOf Communicate)
        vThread.Start()
    End Sub

    Private Sub Communicate()
        Do
            Try
                vNetworkStream = vClientSocket.GetStream
                vNetworkStream.Read(vBytesFrom, 0, CInt(vClientSocket.ReceiveBufferSize))
                vDataFrom = Encoding.ASCII.GetString(vBytesFrom)
                vDataFrom = vDataFrom.Substring(0, vDataFrom.IndexOf("~"))
                Server.Message("From client " & vNr & ": " & vDataFrom)
                Server.Broadcast(vDataFrom, vNr, True)
            Catch ex As Exception
                Server.Message(ex.ToString)
            End Try
        Loop
        Server.Message("Out of loop")
    End Sub

End Class

THE CLIENT CODE (form has textboxuser, textboxmessage, listboxmessages, buttonconnection, buttonsend)
VB.NET:
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading

Public Class Client

    Private vClientSocket As New TcpClient
    Private vNetworkstream As NetworkStream
    Private vData As String
    Private vBytesTo As Byte()
    Private vBytesFrom(13713) As Byte
    Private vThread As Thread
    Private vBufferSize As Integer


    Private Sub ButtonConnection_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonConnection.Click
        If ButtonConnection.Text = "Connect" Then
            vClientSocket.Connect("127.0.0.1", 13713)
            Message("Connected to server")
            vNetworkstream = vClientSocket.GetStream
            vBytesTo = Encoding.ASCII.GetBytes(TextBoxUser.Text & "~")
            vNetworkstream.Write(vBytesTo, 0, vBytesTo.Length)
            vNetworkstream.Flush()
            vThread = New Thread(AddressOf GetMessage)
            vThread.Start()
            ButtonConnection.Text = "Disconnect"
        Else
            vThread.Abort()
            ButtonConnection.Text = "Connect"
        End If
    End Sub

    Private Sub Message(ByVal vMessage As String)
        ListBoxMessages.Items.Add(vMessage)
    End Sub

    Private Sub GetMessage()
        Do
            vNetworkstream = vClientSocket.GetStream
            vBufferSize = vClientSocket.ReceiveBufferSize
            vNetworkstream.Read(vBytesFrom, 0, vBufferSize)
            vData = Encoding.ASCII.GetString(vBytesFrom)
            Message(vData)
        Loop
    End Sub

    Private Sub ButtonSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSend.Click
        vBytesTo = Encoding.ASCII.GetBytes(TextBoxMessage.Text & "~")
        vNetworkstream.Write(vBytesTo, 0, vBytesTo.Length)
        vNetworkstream.Flush()
    End Sub

End Class

I thought I would get an exception in the Communicate Sub of the Client class (server), but I don't... Also, I used vThread.abort to disconnect the client, but I'm not sure that this actually finishes the connection on the client side. If it does, is it enought to put vThread.abort in the server side to stop the connection (and if it does, where do I put it)

A lot of questions, I know, but I'm stuck on this one.

Thanks in advance for the help,

Lioth
 
Last edited:
I had the same problem with some of the things I'm trying to do ... I have a couple of suggestion, but I'm not an expert at this by any means.

First I close the connection after every transmission, then if I have a message to send I try and reconnect if I can't I know that client is gone. I'm sure there are better ways but it works for what I'm trying to do, secound and this might not be a problem for you is what happens if you end up sending more data then your recieve buffer size. from what I see it looks like you will end up losing that transmission, its easy enough to test, just fill the text box with 65000 chars and see what happens.
 
Back
Top