Hello!

I'm just going to repost my question here from stackoverflow.

I am currently developing a file sharing application using asynchronous communication in VB.Net. I successfully coded a simple connection between the client and the server. But, I am currently having a bad time doing the disconnection sub routine for both the client and the server. I'm currently stuck in this problem for a couple of days already and have decided to seek help here because I can't find any good ways to do the disconnection thing.

Here's my code:

Server Application

Private Sub FileSharingInitialize()

    ServerSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

    Dim EndPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 7777)

    ServerSocket.Bind(EndPoint)

    ServerSocket.Listen(0)

End Sub


Private Sub FileSharingOnAccept(ByVal AsyncResult As IAsyncResult)

    ClientSocket = ServerSocket.EndAccept(AsyncResult)

    FileSharingAddClient(ClientSocket)

    ClientSocket.BeginReceive(ByteData, 0, ByteData.Length, SocketFlags.None, New AsyncCallback(AddressOf FileSharingOnReceive), ClientSocket)

End Sub


Delegate Sub _FileSharingAddClient(ByVal Client As Socket)


Private Sub FileSharingAddClient(ByVal Client As Socket)

    If InvokeRequired Then

        Invoke(New _FileSharingAddClient(AddressOf FileSharingAddClient), Client)

        Exit Sub

    End If

    lvConnectedClients.Items.Add("")

    lvConnectedClients.Items(lvConnectedClients.Items.Count - 1).SubItems.Add(Client.LocalEndPoint.ToString)

End Sub


Private Sub FileSharingOnReceive(ByVal AsyncResult As IAsyncResult)

    Dim Client As Socket = CType(AsyncResult.AsyncState, Socket)

    Client.EndReceive(AsyncResult)

    Dim ByteReceived As Byte() = ByteData

    Dim LogMessage As String = System.Text.Encoding.ASCII.GetString(ByteReceived)

    ReadLogMessage(LogMessage)

End Sub


Delegate Sub _ReadLogMessage(ByVal LogMessage As String)


Private Sub ReadLogMessage(ByVal LogMessage As String)

    If InvokeRequired Then

        Invoke(New _ReadLogMessage(AddressOf ReadLogMessage), LogMessage)

        Exit Sub

    End If

    DisplayLogMessage(LogMessage)

End Sub


Private Sub DisplayLogMessage(ByVal Log As String)

    Dim TimeStamp As String = "[" & DateAndTime.Now.ToString("hh:mm:ss tt dddd, dd MMMM yyyy") & "]: "

    Dim LogMessage As String = ""

    If txtLog.Text > "" Then

        LogMessage = Chr(10) & Chr(13)

    End If

    LogMessage &= TimeStamp

    LogMessage &= Log

    txtLog.SelectionStart = Len(txtLog.Text)

    txtLog.SelectedText = LogMessage

End Sub


Private Sub frmMain_Load(sender As Object, e As System.EventArgs) Handles Me.Load

    FileSharingInitialize()

End Sub


Private Sub btnStart_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles btnStart.MouseClick

    ServerSocket.BeginAccept(New AsyncCallback(AddressOf FileSharingOnAccept), Nothing)

    DisplayLogMessage("Server started." & Environment.NewLine)

End Sub

On the server part, when I press the stop button, I want to disconnect all the clients from the server. I have tried this code in my start button but it doesn't work. I'm receiving an error that says the socket is not connected. I'm thinking that maybe I am disconnecting the wrong socket since I have also a socket named ClientSocket in the server application. Or maybe, I should do it with a loop to disconnect the clients? What do you think?

Private Sub btnStop_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles btnStop.MouseClick

    ServerSocket.Shutdown(SocketShutdown.Both)

    ServerSocket.Close()

    ServerSocket = Nothing

End Sub

Client Application

Private Sub btnConnect_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles btnConnect.MouseClick

    ClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

    Dim Address As IPAddress = IPAddress.Parse(frmNetworkSettings.txtServerIPAddress.Text)

    Dim Endpoint As IPEndPoint = New IPEndPoint(Address, CInt(frmNetworkSettings.txtFileSharingPort.Text))

    ClientSocket.BeginConnect(Endpoint, New AsyncCallback(AddressOf FileSharingOnConnect), Nothing)

    SendLogMessage(Username & " is connected." & Environment.NewLine, ClientSocket)

End Sub


Private Sub FileSharingOnConnect(ByVal AsyncResult As IAsyncResult)

    ClientSocket.EndConnect(AsyncResult)

End Sub


Private Sub SendLogMessage(ByVal LogMessage As String, ByVal Client As Socket)

    Dim SendByteData As Byte() = System.Text.Encoding.ASCII.GetBytes(LogMessage)

    Client.BeginSend(SendByteData, 0, SendByteData.Length, SocketFlags.None, New AsyncCallback(AddressOf OnSendLogMessage), Client)

End Sub


Private Sub OnSendLogMessage(ByVal AsyncResult As IAsyncResult)

    Dim Client As Socket = CType(AsyncResult.AsyncState, Socket)

    Client.EndSend(AsyncResult)

End Sub

The problem on the client part is the same on the server. The code to disconnect the client from the server doesn't work. It doesn't send any logs to the server after I press the disconnect button, even when I reconnect afterwards. It seems that the socket has been disposed? If so, how can I prevent it from doing that and reuse the socket when I try to reconnect? Another thing, is that when I press the connect button without starting the server and afterwards start the server, a log is sent to the server that the client connected. It seems that the problem is on the listen method of the server. I don't want that to happen, I just want an exception or something that will alert the user that the client is not connected to the server and do not send a log message to the server afterwards the client connects. I don't really know, but do you think that if I set the backlog of the listen method to zero will prevent that from happening?

Thanks in advance!

If I remember correcly, the thing about TCP connections is that they are only actually connected during a data transfer between the client and the server. And not while idle.

So my suggestion would be that you should check to see if there is a connection before trying to disconnect.
At least in order to avoid any embarrassing error messages. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.