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

Public Class cServerClient_RKSV_DE
    Dim clientSocket As Socket
    Dim byteData(1023) As Byte
    Dim doThis As String
    Dim params() As String
    Public status As String = "begin"
    ' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    '     begin()
    ' End Sub

    Public Event FunctionFinished(ByVal sender As Object, ByVal e As FunctionFinishedArgs_RKSV_DE)


    Public Sub begin(ip, doThis_tmp, params)
        doThis = doThis_tmp
        Me.params = params
        Dim timeOut As Integer = 60
        Select Case doThis
            Case "test" : timeOut = 5 ' nach 5 Sekunden wird abgebrochen
            Case "RKSV_DE" : timeOut = 10 ' nach 10 Sekunden wird abgebrochen
        End Select

        'Ein Thread kontrolliert, ob die Funktion nach einer gewissen Zeit noch läuft und beendet diese ggf.
        Dim st As New Thread(AddressOf stopThread)
        st.IsBackground = True
        Dim param_obj(1) As Object
        'Übergabeparameter des 2. Threads
        param_obj(0) = timeOut
        st.Start(param_obj)


        clientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
        Dim ipAddress As IPAddress = IPAddress.Parse(ip)

        ' Dim ipAddress As IPAddress = ipAddress.Parse("192.168.0.90")
        Dim ipEndPoint As IPEndPoint = New IPEndPoint(ipAddress, 8800)
        clientSocket.BeginConnect(ipEndPoint, New AsyncCallback(AddressOf OnConnect), Nothing)
        status = "beginConnect"
        '   endconnect(clientSocket)


    End Sub

    Public Sub waitTillFinished()
        While Not (status = "TaskError" Or status = "TaskSuccess")
            'wait
        End While
        'Return True
    End Sub

    Private Sub OnConnect(ByVal ar As IAsyncResult)
        Try
            clientSocket.EndConnect(ar)
            clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
                                      New AsyncCallback(AddressOf OnRecieve), clientSocket)
        Catch ex As Exception
            '  MsgBox("Verbindung zum Server konnte nicht aufgebaut werden!")
        End Try
    End Sub

    Private Sub OnSend(ByVal ar As IAsyncResult)
        Dim client As Socket = ar.AsyncState
        client.EndSend(ar)
    End Sub
    Private Sub Send(ByVal msg As String, ByVal client As Socket)
        Dim sendBytes As Byte() = Encoding.BigEndianUnicode.GetBytes(msg)
        client.BeginSend(sendBytes, 0, sendBytes.Length, SocketFlags.None, New AsyncCallback(AddressOf OnSend), client)
    End Sub
    Public Function ByteArrayToTextString(ByRef Barr() As Byte) As String
        Dim enc As System.Text.Encoding = Encoding.BigEndianUnicode
        Return enc.GetString(Barr)
    End Function

    Private Sub OnRecieve(ByVal ar As IAsyncResult)
        Try
            Dim client As Socket = ar.AsyncState
            client.EndReceive(ar)
            Dim bytesRec As Byte() = byteData
            Dim message As String = Encoding.BigEndianUnicode.GetString(bytesRec)
            '  MsgBox("FROM SERVER: " & message)
            Dim b(1023) As Byte

            ' MsgBox("SERVER RECIEVE: " & Encoding.BigEndianUnicode.GetString(b))

            byteData = b
            Read(message)
            clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
                                      New AsyncCallback(AddressOf OnRecieve), clientSocket)

        Catch ex As Exception
            '   MsgBox("Verbindung zum Server wurde unterbrochen!")
        End Try
    End Sub

    Delegate Sub _Read(ByVal msg As String)
    Private Sub Read(ByVal msg As String)
        'If frmMain.InvokeRequired Then
        '    frmMain.Invoke(New _Read(AddressOf Read), msg)
        '    Exit Sub
        'End If

        'frmMain.icoVERAGMonitoring.Visible = False

        'if richtige nsachricht
        '  Dim asciis As Byte() = Encoding.BigEndianUnicode.GetBytes(msg)
        '  Dim a As Char = msg(msg.Length - 1)
        ' msg = msg.Replace(a, "")
        ' MsgBox(msg.Length)

        ' MsgBox(msg(msg.Length - 1))
        ' MsgBox(msg(msg.Length - 1))
        '      MsgBox(Asc(msg(msg.Length - 1)))
        ' MsgBox(Asc(msg(msg.Length - 2)))
        msg = msg.Replace(Convert.ToChar(0), "")
        Try

            MsgBox("-" & msg & "-" & vbNewLine & "ConSuccess" & "-" & doThis)
            If msg = "ConSuccess" Then
                status = "ConSuccess"
                Select Case doThis
                    Case "test"
                        Send("test", clientSocket)
                        status = "sendTask"

                    Case "RKSV_DE"
                        MsgBox("RKSV_DE" & paramsToString())
                        Send("RKSV_DE" & paramsToString(), clientSocket)
                        status = "sendTask"
                End Select

                '  MsgBox("!!!!!ConSuccess --> initAufschubkonten")
                '   Send("FSSAtlasStart", clientSocket)
                'Send("test", clientSocket)
                'Send("initAufschubkonten", clientSocket)

            ElseIf msg = "Task successful" Then
                status = "TaskSuccess"
                clientSocket.Disconnect(False)
                clientSocket.Shutdown(SocketShutdown.Both)
                clientSocket.Close()
                'endconnect(clientSocket)'geht ned
                '  MsgBox("Task erfolgreich!", vbSystemModal, doThis)
                RaiseEvent FunctionFinished(Me, New FunctionFinishedArgs_RKSV_DE(FunctionFinishedArgs_RKSV_DE.EventResult.OK, "Task erfolgreich!"))
            ElseIf msg = "Task not found" Then
                MsgBox("SERVERERROR: Der Dienst wurde nicht gefunden!", vbSystemModal, "FSSAtlas")
                status = "TaskError"
                RaiseEvent FunctionFinished(Me, New FunctionFinishedArgs_RKSV_DE(FunctionFinishedArgs_RKSV_DE.EventResult.ERR, "SERVERERROR: Der Dienst wurde nicht gefunden!"))
            ElseIf msg = "Task inactive" Then
                MsgBox("SERVERERROR: Der Dienste ist nicht aktiv!", vbSystemModal, "FSSAtlas")
                status = "TaskError"
                RaiseEvent FunctionFinished(Me, New FunctionFinishedArgs_RKSV_DE(FunctionFinishedArgs_RKSV_DE.EventResult.ERR, "SERVERERROR: Der Dienste ist nicht aktiv!"))
            ElseIf msg = "Task timeout" Then
                MsgBox("SERVERERROR: Der Dienst wurde wegen einer Zeitüberschreitung abgebrochen!", vbSystemModal, "FSSAtlas")
                status = "TaskError"
                RaiseEvent FunctionFinished(Me, New FunctionFinishedArgs_RKSV_DE(FunctionFinishedArgs_RKSV_DE.EventResult.ERR, "SERVERERROR: Der Dienst wurde wegen einer Zeitüberschreitung abgebrochen!"))
            ElseIf msg = "Task error" Then
                MsgBox("SERVERERROR: Server-Fehler!", vbSystemModal, "FSSAtlas")
                status = "TaskError"
                RaiseEvent FunctionFinished(Me, New FunctionFinishedArgs_RKSV_DE(FunctionFinishedArgs_RKSV_DE.EventResult.ERR, "SERVERERROR: Server-Fehler!"))
            Else
                MsgBox("SERVER_NACHRICHT NICHT VERSTANDEN: " & msg, vbSystemModal)
                status = "TaskError"
                RaiseEvent FunctionFinished(Me, New FunctionFinishedArgs_RKSV_DE(FunctionFinishedArgs_RKSV_DE.EventResult.ERR, "SERVER_NACHRICHT NICHT VERSTANDEN: " & msg))

                clientSocket.Shutdown(SocketShutdown.Both)
                clientSocket.Close()
            End If

        Catch ex As Exception
            MsgBox("Verbindungs-Fehler beim Senden", vbSystemModal)
            status = "TaskError"
            RaiseEvent FunctionFinished(Me, New FunctionFinishedArgs_RKSV_DE(FunctionFinishedArgs_RKSV_DE.EventResult.ERR, "Verbindungs-Fehler beim Senden"))
            clientSocket.Close()
        End Try
        ' byteData = Encoding.BigEndianUnicode.GetBytes("")

    End Sub

    Function paramsToString()
        paramsToString = ""
        If params IsNot Nothing Then
            For Each p In params
                paramsToString &= "|||" & p
            Next
        End If
    End Function

    Sub stopThread(param_obj As Object) 'Stoppt einen Hauptthread nach einer gewissen Anzahl von Sekunden; Übergabeparameter: Object { Tread, clientSocket, SekundenToTimeout }
        Thread.Sleep(param_obj(0) * 1000) ' Hier wird soviele Senkunden gewartet, wie in den Übergabeparametern definiert wurde.
        If status = "TaskError" Or status = "TaskSuccess" Then Exit Sub
        status = "TaskError"
        Try
            clientSocket.Disconnect(False)
            clientSocket.Shutdown(SocketShutdown.Both)
            clientSocket.Close()
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

        RaiseEvent FunctionFinished(Me, New FunctionFinishedArgs_RKSV_DE(FunctionFinishedArgs_RKSV_DE.EventResult.ERR, "Task wurde aufgrund eines Timeouts vom Client abgebrochen."))
        MsgBox("ERROR: Task wurde aufgrund eines Timeouts vom Client abgebrochen.") 'Log-Mittelung
    End Sub


End Class

Public Class FunctionFinishedArgs_RKSV_DE
    Inherits EventArgs
    'das was man später unter e sehen kann
    Public Result As EventResult
    'hier - als Beispiel - einfach eine Enum
    Public Enum EventResult
        OK
        ERR
    End Enum
    Public Message As String
    'Zum übergeben der Parameter
    Public Sub New(ByVal r As EventResult, m As String)
        Result = r
        Message = m
    End Sub
End Class