Cannot close socket connection in vb.net

Hi, using VB.net/VS2005/.net2.   Created server using TCP listener, Asyncronous connection from client.  Client connects and disconnects from server correctly.  However, if client losses connection, server does not close connection automatically.  Using the code below doesnt close the connection.   Looking for a way to either close the connection or the thread automatically, or perhaps by time (nothing heard after so many seconds or something) and how to access and control that particular connection by code
If bytesRead < 1 Then 
_client.Close()
other stuff
Exit Sub
Else
Do stuff with the  bytes
End If

Open in new window

LVL 2
PNRTAsked:
Who is Participating?
 
spandexandyCommented:
If you are like me, getting these Sockets running felt like a painful hurdle to get past so that I could actually get into the interesting part of the application I was writing. I wasn't really interested in optimizing the sockets side of things. So I am perhaps a bit embarrassed to submit the module that I have attached. Nevertheless, I hope that it will get you further along.

Here is a rough explanation of how I did it:

1.  I created a class called clsUser which stored all the information about my sockets and what they were busy doing. (See code snippet below). Have a Collection of clsUsers to store them all.

2.  I created a module called mConnections which contained it's own class called AsynchronousSocketListener. I had noticed that when listening for incoming connections, the whole application "froze" while waiting. To avoid this (I needed my application to continue executing it's own code while listening for new connections in the background), the AsynchronousSocketListener uses a BackgroundWorker to handle the listening behind-the-scenes.

3.  When a new incoming connection is detected, create a new "clsUser" object and set it's MySocket to be the socket of the AsynchronousSocketListener. No need to store IP addresses or anything like that, I just let the Socket manage the connection.

4.  When I am done with the connection, call the Disconnect method of the clsUser object.

I hope this helps you get past the annoying (to me) Sockets aspect of your application and onto the more meat and potatos of what you're trying to accomplish!

Cheers.
Imports System.Threading
Imports System.ComponentModel
Imports System.Net.Sockets
Imports System.Text
 
Public Class clsUser
 
    Public MySocket As System.Net.Sockets.Socket
    Public Name As String
    Public Idle As Integer
    Public CollectionKey As String
 
    Public Status As Integer
 
    Public InputBuffer As StringBuilder
    Public InputBufferBytes() As Byte
 
    Public Sub Disconnect()
 
        'Switch off the socket
        Try
            MySocket.Disconnect(True)
        Catch ex As Exception
        End Try
 
        Try
            MySocket.Shutdown(SocketShutdown.Both)
        Catch ex As Exception
        End Try
 
        Try
            MySocket.Close()
        Catch ex As Exception
        End Try
 
        Try
            MySocket = Nothing
        Catch ex As Exception
        End Try
        
    End Sub
 
End Class

Open in new window

mConnectionsDOTvb.txt
0
 
spandexandyCommented:
Hi

In my application, I used a variable "idle" for each socket. Whenever data came from that socket, I reset idle to zero, and a timer popped every second to increment the idle counter. When idle reached 10 minutes (or whatever), I had it trigger the following code which seemed to do the job.
       
Cheers


        'Switch off the socket
        Try
            MySocket.Disconnect(True)
        Catch ex As Exception
        End Try
 
        Try
            MySocket.Shutdown(SocketShutdown.Both)
        Catch ex As Exception
        End Try
 
        Try
            MySocket.Close()
        Catch ex As Exception
        End Try
 
        Try
            MySocket = Nothing
        Catch ex As Exception
        End Try

Open in new window

0
 
PNRTAuthor Commented:
Thanks for this.   However, my problem seems to be refering back to a particular connection to close it, when I have say 50 connections open and three or four that have dropped.  If I cant get it to close automatically, then I would like to be able to at least address and control a particular connection
0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

 
spandexandyCommented:
You will have an array or a user-defined class with references to each of your 50 sockets, right? I assume that you would loop through your 50 connections to find the ones which have dropped, or which have gone idle and you want to drop. Use the code above to kill the socket connection.

(Perhaps I am not understanding?)

Cheers.
0
 
PNRTAuthor Commented:
Thanks Andy, yes you're understanding correctly, a hashtable in fact.  I'm just trying to get my head around the timer aspect.  I'll give it a try and get back as soon as.
0
 
PNRTAuthor Commented:
Just incidently, any idea why the code is not closing the connection once there are no further bytes to be read?
0
 
spandexandyCommented:
The socket is waiting for the client to send more bytes. There are different situations where you may want to use a socket.

I used these sockets to write a telnet application whereby users would type commands and have them executed by the server. In that situation I wanted the connection to remain open, accepting commands whenever the user typed them, until the user typed the "quit" command or they had fallen idle for 5 minutes.

In other situations, you may have an automated client (1) connect, (2) send X bytes, and then (3) be done. I am guessing that perhaps this is the type of application you are writing. In your case you could execute the code I provided to then close the connection after receiving whatever the client has sent.

Cheers.
0
 
PNRTAuthor Commented:
Thanks yes, Im writing a server that will stay connected and send automated replies back to the client.

I think I've now done a complete 360 and got back where I started.  Still cant address the particular socket that needs closing.    

When a new connection occurs, I create three hashtables holding various data. One holds the IP/Port number.  This is the hashtable IPPorts. If ObjEntry is the loop, I have this.
 
Dim oldIP As Net.Sockets.TcpClient
oldIP = Client .IPPorts(objEntry.Key)
To close or disconnect the oldIP

I then get  -

"Option Strict On disallows implicit conversions from 'Object' to 'System.Net.Sockets.TcpClient'.    

Intellisanse then suggests  the following (obviously to change the type)

oldIP = CType(Client.IPPorts(objEntry.Key), Net.Sockets.TcpClient)

This compiles OK but then throws up the exception -  'System.InvalidCastException: Unable to cast object of type system.string to System.Net,Sockets.TcpClient.

I've also tried an array but with the saem results

I dont seem to be able to ge the conversion between string and System.Net.Sockets.TcpClient.
So Im back where I started, not being able to address a particular socket in order to close/disconnect it
as I mentioned in the first question.

Any ideas?

0
 
PNRTAuthor Commented:
Thanks for the reply Andy,not exactly what I was after as I would have to rewrite the method I have, but gives me the idea.  I'll ask a seperate question regarding the type conversion
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.