
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'
'
'  Example taken from http://msdn.microsoft.com/en-us/library/6y0e13d3.aspx
'
'    Synchronous Server Socket Example

'  The following example program creates a server that receives connection requests from clients. The 
' server is built with a synchronous socket, so execution of the server application is suspended 
' while it waits for a connection from a client. 
'
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading



Module modIF_Api2_Server
    Dim evntParseComplete As New ManualResetEvent(False)
    Dim booltimeOut As Boolean = False
    Dim boolAPIActivity2 As Boolean = True


    Public Sub subCheckForAPITimeout2()
        Try
            If classAPI2Server.Connected And Not boolAPIActivity2 Then
                booltimeOut = True
                frmDebug.subWriteLogs(" $$$$$$$$######################################## API 2 TIMEOUT  ")
            End If
            boolAPIActivity2 = False
        Catch ex As Exception
            frmDebug.subWriteLogs(" EXCEPTION in subCheckForAPITimeout2 :  " & ex.ToString)
        End Try
    End Sub


    Public WithEvents classNewAPI2Server As New classAPI2Server
    Delegate Sub DelegateParseAndRespond(ByVal strAPIMessage As String)
    Sub subAPIParseAndRespond(ByVal strAPIMessage As String) Handles classNewAPI2Server.evntAPICommandReceived
        '  Parse the received data and respond
        Try
            If frmGotABotTop.InvokeRequired And Not boolShutDown Then
                Dim newDelegate As New DelegateParseAndRespond(AddressOf subAPIParseAndRespond)
                frmGotABotTop.Invoke(newDelegate, New Object() {strAPIMessage})
            Else
                frmDebug.subWriteLogs(vbCrLf & ftnElapsedTimeS() & ":  " & booltimeOut & " \\\\\\\\\\\\\\\\\\\\  API 2 Received Message: " & strAPIMessage)
                If booltimeOut Then
                    strAPIMessage = "API_Timeout" & vbCr
                ElseIf classAPI2Server.Connected Then
                    Dim strNessageReceived As String = strAPIMessage
                    If CBool(InStr(strNessageReceived, "Connection: close")) Or CBool(InStr(strNessageReceived, "POST")) Then
                        strAPIMessage = "OK"
                        classAPI2Server.Connected = False
                        booltimeOut = True
                        evntParseComplete.Set()
                        Dim threadAPI2 As New Thread(AddressOf ftnAPICommands)
                        threadAPI2.Start(strNessageReceived)
                        'strAPIMessage = ftnAPICommands(strNessageReceived)
                    Else
                        strAPIMessage = ftnAPICommands(strNessageReceived)
                        evntParseComplete.Set()
                    End If
                End If
            End If
        Catch ex As Exception
            frmDebug.subWriteLogs(" EXCEPTION in subAPIParseAndRespond2" & ex.ToString)
        End Try
    End Sub




    Class classAPI2Server
        ' This server waits for a connection and then uses  sychronous operations to
        ' accept the connection, get data from the connected client, 
        ' perform the API function.
        Shared Event evntAPICommandReceived(ByVal strAPIMessage As String)
        Public Shared Connected As Boolean = False

        Public Shared Sub subMain()
            Dim handler As Socket
            Try
                ' strAPIMessage buffer for incoming strAPIMessage.
                Dim bytes() As Byte = New [Byte](1024) {}
                Dim strAPIMessage As String = ""
                Dim ipAddress As IPAddress = ipAddress.Loopback    ' 
                Dim localEndPoint As New IPEndPoint(ipAddress.Any, 9400) ' Create a TCP/IP socket.
                Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
                listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, True)
                listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True)
                listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, False)
                listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, True)
                listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000)

                listener.Bind(localEndPoint)
                While Not boolShutDown
                    If boolDebugAPI Then frmDebug.subWriteLogs(ftnElapsedTimeS() & " subMain 2  start connection")
                    booltimeOut = False

                    listener.Listen(1)
                    handler = listener.Accept() ' Start listening for connections.
                    classAPI2Server.Connected = handler.Connected
                    If boolDebugAPI And classAPI2Server.Connected Then frmDebug.subWriteLogs(ftnElapsedTimeS() & " subMain 2  listening")

                    strAPIMessage = ""
                    While Not boolShutDown And Not booltimeOut And handler.Connected 'loop and wait for incomming strAPIMessage
                        Thread.Sleep(50)
                        bytes = New Byte(1024) {}
                        Dim bytesRec As Integer = 0 ' handler.Receive(bytes)
                        If (handler.Poll(100000, SelectMode.SelectRead)) Then _
                              bytesRec = handler.Receive(bytes, bytes.Length, 0) ' numbytes =count of bytes returned
                        If bytesRec > 0 Then strAPIMessage += Encoding.ASCII.GetString(bytes, 0, bytesRec)
                        If strAPIMessage.IndexOf(vbCrLf) > -1 Then ' we've received a line of data
                            evntParseComplete.Reset()
                            RaiseEvent evntAPICommandReceived(strAPIMessage)  ' Process the command
                            If boolDebugAPI Then frmDebug.subWriteLogs(ftnElapsedTimeS() & " subMain 2  received")
                            Dim timeOut As DateTime = Now().AddMilliseconds(1500)
                            evntParseComplete.WaitOne(1500)
                            If (Now() >= timeOut) Then
                                booltimeOut = True
                                classAPI2Server.Connected = False
                                If boolDebugAPI Then frmDebug.subWriteLogs(ftnElapsedTimeS() & " subMain 2  timeout")
                            ElseIf classAPI2Server.Connected And handler.Connected Then
                                If boolDebugAPI Then frmDebug.subWriteLogs(ftnElapsedTimeS() & " subMain 2  send")
                                Dim msg As Byte() = Encoding.ASCII.GetBytes(strAPIMessage)
                                handler.Send(msg)
                            End If
                            strAPIMessage = ""
                        End If
                    End While
                    If handler.Connected Then handler.Disconnect(Not boolShutDown)
                    Thread.Sleep(200)
                    classAPI2Server.Connected = handler.Connected
                    If boolDebugAPI Then frmDebug.subWriteLogs(ftnElapsedTimeS() & " subMain 2  end connection")
                End While
            Catch ex As Exception
                frmDebug.subWriteLogs(" EXCEPTION in subMainn " & ex.ToString)
            End Try
        End Sub


    End Class 'classAPI2Server






End Module
