M
Michael D. Ober
Chris,
I have replaced the listening/accept code with the following:
Private ConnectionCounter As Long = 0
Private tcpServer As TcpListener
Public Sub CreateListener()
Dim ServerAddress As IPAddress =
Dns.GetHostEntry(My.Computer.Name).AddressList(0)
Dim LocalHost As New IPEndPoint(ServerAddress,
OSInterface.iniWrapper.ReadInt("Dialer", "Port", "Wakefield.ini"))
tcpServer = New TcpListener(LocalHost)
tcpServer.Start()
WriteLog("Ready for IP Connections")
tcpServer.BeginAcceptSocket(AddressOf AcceptRequest, tcpServer)
Debug.Print("Waiting for a connection")
End Sub
Private Sub AcceptRequest(ByVal ar As System.IAsyncResult)
Dim sock As Socket = Nothing
Dim ClientEndPoint As New IPEndPoint(0, 0)
Dim ClientName As String = ""
Dim MsgIn As String = ""
Dim BytesIn(1024) As Byte
Dim i As Integer
Try
Debug.Print("Incoming Connection")
Dim Listener As TcpListener = CType(ar.AsyncState, TcpListener)
sock = Listener.EndAcceptSocket(ar)
' Start listening for the next connection
tcpServer.BeginAcceptSocket(AddressOf AcceptRequest, tcpServer)
ClientEndPoint = CType(sock.RemoteEndPoint, IPEndPoint)
ClientName = ClientEndPoint.Address.ToString
ClientName = Dns.GetHostEntry(ClientName).HostName
ClientName &= ":" & ClientEndPoint.Port.ToString
Interlocked.Increment(ConnectionCounter)
UpdateCaption("Client Connection", ClientName)
' If the socket remains unused for 5 minutes, error out and release
server resources
If Not ClientName.Contains("Lily_Tomlin") Then sock.ReceiveTimeout =
5 * 60 * 1000
WriteLog(ClientName & ": Socket Timeout is set to " &
sock.ReceiveTimeout.ToString("#,##0") & " milliseconds")
I left the do loop in as this provides the state information for bookeeping
(ClientName) and de-blocking the TCP stream (MsgIn). This change eliminates
the need to have CreateListener started in a seperate thread and also the
need for the AutoResetEvent object. I understand your comments (I think)
about using the BeginRead/ReadComplete callback methods, but the number of
clients I have connected at any given time is less than 100, so scaleability
isn't an issue. I need to keep a small amount of state information around
between socket reads and the do loop allows me to do that easily, since each
callback to the AcceptRequest starts a new thread with its own stack and
thread local data.
Mike.
I have replaced the listening/accept code with the following:
Private ConnectionCounter As Long = 0
Private tcpServer As TcpListener
Public Sub CreateListener()
Dim ServerAddress As IPAddress =
Dns.GetHostEntry(My.Computer.Name).AddressList(0)
Dim LocalHost As New IPEndPoint(ServerAddress,
OSInterface.iniWrapper.ReadInt("Dialer", "Port", "Wakefield.ini"))
tcpServer = New TcpListener(LocalHost)
tcpServer.Start()
WriteLog("Ready for IP Connections")
tcpServer.BeginAcceptSocket(AddressOf AcceptRequest, tcpServer)
Debug.Print("Waiting for a connection")
End Sub
Private Sub AcceptRequest(ByVal ar As System.IAsyncResult)
Dim sock As Socket = Nothing
Dim ClientEndPoint As New IPEndPoint(0, 0)
Dim ClientName As String = ""
Dim MsgIn As String = ""
Dim BytesIn(1024) As Byte
Dim i As Integer
Try
Debug.Print("Incoming Connection")
Dim Listener As TcpListener = CType(ar.AsyncState, TcpListener)
sock = Listener.EndAcceptSocket(ar)
' Start listening for the next connection
tcpServer.BeginAcceptSocket(AddressOf AcceptRequest, tcpServer)
ClientEndPoint = CType(sock.RemoteEndPoint, IPEndPoint)
ClientName = ClientEndPoint.Address.ToString
ClientName = Dns.GetHostEntry(ClientName).HostName
ClientName &= ":" & ClientEndPoint.Port.ToString
Interlocked.Increment(ConnectionCounter)
UpdateCaption("Client Connection", ClientName)
' If the socket remains unused for 5 minutes, error out and release
server resources
If Not ClientName.Contains("Lily_Tomlin") Then sock.ReceiveTimeout =
5 * 60 * 1000
WriteLog(ClientName & ": Socket Timeout is set to " &
sock.ReceiveTimeout.ToString("#,##0") & " milliseconds")
I left the do loop in as this provides the state information for bookeeping
(ClientName) and de-blocking the TCP stream (MsgIn). This change eliminates
the need to have CreateListener started in a seperate thread and also the
need for the AutoResetEvent object. I understand your comments (I think)
about using the BeginRead/ReadComplete callback methods, but the number of
clients I have connected at any given time is less than 100, so scaleability
isn't an issue. I need to keep a small amount of state information around
between socket reads and the do loop allows me to do that easily, since each
callback to the AcceptRequest starts a new thread with its own stack and
thread local data.
Mike.