HelpSystem.Net.Sockets.Socket EndConnect() error.

Posts 1–4 of 4 · Page 1 of 1
System.Net.Sockets.Socket EndConnect() error.
Making a basic server/client program using System.Net.Sockets.Socket

I find local ip and bind to a port fine, but when I try to "manually shut down the server" I get an exception. The EndConnect() call-back is called after I call Socket.Close() , which is where I would normally assign the socket returned from .EndConnect(), but because it's been .Closed, it's giving the exception.




Any comments appreciated. Thanks.

 
text code

Public Class GameServer
Private Const LISTEN_PORT As Int32 = 23456
Private Const MAX_PENDING_CONNECTIONS As Int32 = 7

Private _localIp As System.Net.IPAddress
Private _serverSocket As System.Net.Sockets.Socket
Private _clientSocket As System.Net.Sockets.Socket
Private _isRunning As Boolean = False '' Waiting for Incoming connections
Private _outputFunc As GiveOutputDelegate
Public Delegate Sub GiveOutputDelegate(ByVal msg As String, ByVal showTime As Boolean)
Public Sub New(ByVal outputFunction As GiveOutputDelegate)
_outputFunc = outputFunction
''find local ip, else close program!
Dim _ipCollection As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHost Name())
For Each ip As System.Net.IPAddress In _ipCollection.AddressList
If ip.AddressFamily = Net.Sockets.AddressFamily.InterNetwork Then ''take the first ip that's ipV4
_localIp = ip
Exit Sub
End If
Next
''if we fall through the loop, no ipv4 address was found.
MessageBox.Show("Unable to find local IP address. No network connection found. Unable to continue, Shutting down.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
Throw New Exception("System.Net.Dns.GetHostEntry(System.Net. Dns.GetHostName()); [IpHostEntry] returned no ipv4 addresses.") '' Friendly, but it's what it takes to get the user's attention.
End Sub
Public Function StartServer() As Boolean
If _isRunning = False Then '' Don't try to .Start() a server if it's already running.
_isRunning = True
_serverSocket = New System.Net.Sockets.Socket(_localIp.AddressFamily, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
_serverSocket.Bind(New System.Net.IPEndPoint(_localIp, LISTEN_PORT))
If _serverSocket.IsBound Then
_outputFunc("Socket bound to port " & LISTEN_PORT.ToString & " ok.", True)
_serverSocket.Listen(MAX_PENDING_CONNECTIONS)
_serverSocket.BeginAccept(AddressOf SocketConnectedCallback, Nothing)
Return True
Else
MsgBox("GameServer::Start() Unable to bind listening socket on port " & LISTEN_PORT.ToString() & "." & Environment.NewLine _
& "Is that port already being used | Is your firewall blocking it?")
_outputFunc("Socket unable to bind on port " & LISTEN_PORT.ToString & ". Unable to continue.", True)
Return False
End If
Else
''already running
Return True '' misleading
End If
End Function
Public Sub StopServer()
If _isRunning Then
_serverSocket.Close() '' destroys the socket object. Will get a new one on StartServer()
_isRunning = False
End If
End Sub
Private Sub SocketConnectedCallback(ByVal AR As IAsyncResult)
Try
_clientSocket = _serverSocket.EndAccept(AR)
Catch ex As Exception
MsgBox(ex.Message) ''only occurs when shutting down socket. "Can not access a disposed object."
End Try
End Sub
Public ReadOnly Property IsRunning As Boolean
Get
Return _isRunning
End Get
End Property
Public ReadOnly Property LocalIP As System.Net.IPAddress
Get
Return _localIp
End Get
End Property
End Class

@wut12345 Hmm, I looked over the link: as far as I can tell, the object is being disposed and that *is* the problem...

found same issue on stackoverflow: c# - Proper way to stop listening on a Socket - Stack Overflow

one user says:
2) just Close(0) listening socket which will result in false shot to its callback, if you then look into your listening socket you will see that its state is "closed" and "disposed". This is why calling EndAccept would cause exception. You may just ignore it and do not call EndAccept. Listening socket will go down immediately without timeout.

Calling Socket.Close() "..results in false shot to its callback" - I don't understand why I guess. Not sure how to avoid/fix it.

Looking into it now --> from the stackover link:
"
-1: A socket performing an accept (ie. awaiting new connections) is now the same as a socket connected to a client (where one of Disconnect or Shutdown is the right answer). – Richard Oct 16 '12 at 9:52"

ie. When the callback is called normallly, .Connected will be true, and when it's called as a result of Close(), .Connected will be false. ie
Code:
    Private Sub SocketConnectedCallback(ByVal AR As IAsyncResult)

        If _serverSocket.Connected = True Then
            _clientSocket = _serverSocket.EndAccept(AR)
        End If

    End Sub
This avoids the exception, but feels wrong.

Will test soon/update post.

Any comments appreciated.
Posts 1–4 of 4 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?