Announcement

Collapse
No announcement yet.

Client Netzwerkprogrammierung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Client Netzwerkprogrammierung

    Hi an alle.
    Ich habe folgendes Problem!

    Ich soll eine Netztwerkschnittstelle programmieren (CLIENT Anwendung!)
    Gegenstelle(Server) ist eine SPS!

    Ich möchte ständig horchen, ob Daten vom Server kommen! Aber auch jederzeit die Möglichkeit haben selber Daten zum Server zu schicken!

    Auf keinn Fall soll in einem Timer überprüft werden, ob Daten vom Server vorliegen!

    Wie gehe ich am besten vor!?
    Hab schon einiges im Netz gelesen, aber eine anständige Lösung hab ich noch nicht gefunden!



    Folgende umsetztungen würden in Frage kommen(SOCKET-Klasse):
    - über verschiednen Threads!
    --> hab ich ausprobiert...klappt aber leider nicht so ganz

    - event gesteuert!
    --> würde mich sehr interessieren! Kann mir jmd erklären wie man mit Events arbeitet? bzw ein kleines Beispiel zeigen, wie ein Event ausgelöst wird, wenn Daten vom Server kommen und diese dann sofort weiterverarbeiten kann!

    Sorry mit DOT.NET arbeite ich erst seit 3 Wochen!

    Vielen Dank für eure Hilfe

    Gruß

  • #2
    Was für ein Protokoll bzw. welche Schnittstelle verwendet denn eine SPS?

    Seriell? TCP/IP?

    Comment


    • #3
      Das TCP/IP Protokoll!

      Comment


      • #4
        Hat denn keiner nen Ansatz für mich oder nen guten Link, wo ich das lernen kann!?

        Comment


        • #5
          ich kann dir nur soviel sagen. Grundsätzlich gibt es einen TCP Listener in .NET dieser Implementiert ein Asynchrones Interface und überwacht selbst ob Netzwerkpakete auf einem Port ankommen. Aber eines gleich vorweg und das ist das einzige dass ich dir sagen kann. Wenn dein Server nicht selbstständig Pakete losschickt dann kommst du um ein zyklisches Pollen nicht herum.

          Eine weitere Information. Ich hab Elektroniker für Automatisierungstechnik gelernt. Und habe demnach schon viel mit SPS Steuerungen gemacht und weiß folgendes die Visualisierungssoftware WinCCFlex oder auch WinCC oder das alte hhmm mir ist der Name entfallen, arbeiten alle mit Polling aus einem ganz einfachen Grund. Es würde die Zykluszeit einer SPS viel negativer Belasten wenn sie jede Änderung eines Zustandes per Netzwerk senden würde, als wenn ein ClientProgramm in gewissen Abständen nach Signalstellungen fragt. Dadurch kann man nämlich bei Werten die nicht in quasi "Echtzeit" (quasi da es bei einer Standard SPS kein Echtzeit gibt was am Sequenziellen Programmablauf liegt, was aber nicht für alle SPS gilt, ein weiterer Grund ist das Standard Ethernet welches auch nicht Echtzeit fähig ist) benötigt werden das Pollen auf einen größeren Zeitraum beschränken kann und zum Beispiel Zählerstände nur alle 5sek. abfragt.

          Hoffe ich konnte dir ein wenig helfen.
          Unsere Jugend ist unerträglich, unverantwortlich und entsetzlich anzusehen! - Aristoteles

          Comment


          • #6
            Habs folgendermaßen gelöst! (asynchrone Empfangs.-/Senderoutine mit jeweils eigenem Thread)

            FUNKTIONIERT!

            Für Verbesserungsvorschläge bin ich IMMER zu haben!

            P.S. die SPS sendet autark! Wenn Daten im Ringpuffer vorliegen, werden diese versendet!

            Danke :-)

            Code:
            Imports System.Net.Sockets
            Imports System.Net
            Imports System.Threading
            Imports System.Text
            Imports System.Windows.Forms
            
            Public Class Form1
            
            Dim strMessage As String     'Nach empfangener Nachricht steht dies hier als String
                Dim myConnect As Socket      'TCP Socket
                Dim bteRecv(255) As Byte     'Byte Array (Empfangsthread)
                Dim bteSend(255) As Byte     'Byte Array (Sendethread)
                Dim IP_Connected As Boolean  'Vergbindunh hergestellt?
            
                'Delegat für die GUI Elemente, damit ich diese auch aus einem laufendm Thread verwenden kann!
                Delegate Function AddDel(ByVal m_element As TextBox, ByVal m_text As String) As Integer
            
                Private Function SetText(ByVal m_element As TextBox, ByVal m_text As String) As Integer
                    If m_element.InvokeRequired Then
            
                        Dim MyDelegate As New AddDel(AddressOf SetText)
                        m_element.Invoke(MyDelegate, m_element, m_text)
                    Else
                        m_element.Text += m_text
                    End If
                End Function
                Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
                    'Defaultwerte definieren
                    txtAddress.Text = "XXX.XXX.XXX.XXX"
                    txtPort.Text = "XXXXX"
            
                End Sub
            
                Private Sub btnListener_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnListener.Click
                    'Verbindung zum Server herstellen, eigener Thread 
                    Dim myThread As New Thread(New ThreadStart(AddressOf StartListen))
                    myThread.Start()
                End Sub
            
                'Dieser SUB wird nach erfolgreicher Verbindung zum Server gestartet --> EMPFANGSTHREAD
                Private Sub start_recv_thread()
                    Dim myThread As New Thread(New ThreadStart(AddressOf ReceiveStart))
                    myThread.Start()
                End Sub
                'Sendethread starten 
                Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
                    Dim myThread As New Thread(New ThreadStart(AddressOf SendStart))
                    myThread.Start()
                End Sub
            
                'Verbindung herstellen
                Private Sub StartListen()
                    If IP_Connected = False Then
                        Dim intPort As Integer
                        Dim bidEndPoint As IPEndPoint
            
                        intPort = Integer.Parse(txtPort.Text)
                        bidEndPoint = New IPEndPoint(IPAddress.Parse(txtAddress.Text), intPort)
                        myConnect = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            
                        Try
                            Dim myAsyncCallBack As New AsyncCallback(AddressOf ConnectEnd)
                            myConnect.BeginConnect(bidEndPoint, myAsyncCallBack, myConnect)
                            IP_Connected = True
            
                        Catch ex As SocketException
                            Console.WriteLine(ex.Message)
                            IP_Connected = False
                        End Try
                    End If
                End Sub
            
                Private Sub ConnectEnd(ByVal pIAsyncResult As IAsyncResult)
                    'Verbindungsversuch erfolgreich!
                    myConnect.EndConnect(pIAsyncResult)
                    start_recv_thread()
                End Sub
            
                Private Sub ReceiveStart()
                    'Asynchrone Empfangsroutine starten
                    If IP_Connected = True Then
                        Try
            
                            Dim myAsyncCallBack As New AsyncCallback(AddressOf ReceiveData)
                            myConnect.BeginReceive(bteRecv, 0, 50, 0, myAsyncCallBack, myConnect)
            
                        Catch ex As Exception
                            MsgBox(ex.Message)
                        End Try
            
                    End If
            
                End Sub
            
                Private Sub ReceiveData(ByVal pIAsyncResult As IAsyncResult)
                    'Prüfe ob Daten vorliegen
                    If IP_Connected = True Then
                        Try
                            Dim intByte As Integer
                            intByte = myConnect.EndReceive(pIAsyncResult)
                            'intByte größer '0' heißt, Daten wurden empfangen! Danach umwandeln der Bytes in String und den ByteArray Inhalt löschen 
                            If intByte > 0 Then
                                Dim m_arraylenght As Integer
                                Dim i As Integer
                                strMessage = Nothing
                                strMessage += Encoding.ASCII.GetString(bteRecv)
                                m_arraylenght = bteRecv.Length
                                SetText(txtRecv, strMessage)
                                For i = 0 To m_arraylenght - 1
                                    bteRecv(i) = 0
                                Next
                            End If
            
                        Catch ex As Exception
                            'MsgBox(ex.Message)
                        End Try
                        'Asynchrone Empfangsroutine wieder neu anstoßen (so ist gewährleistet, dass wenn Daten vorliegen, diese auch direkt abgeholt werden können)
                        Call ReceiveStart()
                    End If
                End Sub
            
                Private Sub SendStart()
                    'Asynchrone Senderoutine starten
                    If IP_Connected = True Then
                        Try
                            Dim myAsyncCallBack As New AsyncCallback(AddressOf SendData)
                            Dim m_arraylenght As Integer
                            Dim i As Integer
                            'ByteArray Inhalt löschen 
                            For i = 0 To m_arraylenght - 1
                                bteSend(i) = 0
                            Next
                            'Daten versenden
                            bteSend = Encoding.ASCII.GetBytes(txtSend.Text)
                            myConnect.BeginSend(bteSend, 0, bteSend.Length, SocketFlags.DontRoute, myAsyncCallBack, myConnect)
                        Catch
            
                        End Try
                    End If
            
                End Sub
            
                Private Sub SendData(ByVal pIAsyncResult As IAsyncResult)
                    Dim intSend As Integer
                    'Daten erfolgreich versendet
                    intSend = myConnect.EndSend(pIAsyncResult)
                    'SetText(txtRecv, vbCrLf + "Message sent" + intSend.ToString + " bytes ") 'txtRecv.Text += vbCrLf + "Message sent" + intSend.ToString + " bytes "
            
                End Sub
            
                Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
                    'Verbindung beenden/schließen
                    IP_Connected = False
                    myConnect.Close()
                End Sub

            Comment


            • #7
              ist aber ein seperates Modul in der SPS dass das regelt oder, ist ja nicht Standard dass eine SPS so etwas verschickt?!


              P.S. bin mir nicht sicher aber der Code liese sich deutlich verbessern!
              Unsere Jugend ist unerträglich, unverantwortlich und entsetzlich anzusehen! - Aristoteles

              Comment


              • #8
                Mit Sicherheit! Aber ich denke mit meinen knappen 3 Wochen .NET Erfahrungen ist das doch ganz brauchbar...Aber andere bzw. bessere Lösungen schaue ich mir immer wieder gern an!

                Zur SPS: Die Software auf der SPS musste ich auch selber Programmieren..sprich Schnittstelle wie RS232 und Ethernet; Motorsteuerung usw.

                Thx

                Comment


                • #9
                  ok und die hast du dann halt so programmiert dass gewisse Zustandsänderungen verschickt werden?

                  Ja aber schau dir nochmal Beispiele zur Asynchronen Netzwerkverarbeitung an. Denn es ist auch möglich dass du nicht immer wieder deine Empfangsroutine startest. Weil wie du es machst ist es eigentlich au mehr oder minder pollen. Es ist auch möglich dass dich .NET über ein Event informiert dass neue Daten eintreffen.
                  Unsere Jugend ist unerträglich, unverantwortlich und entsetzlich anzusehen! - Aristoteles

                  Comment


                  • #10
                    richtig!

                    ...genau das ist das Problem...ich habs einfach nocht net geblickt, wie das mit den Events funktioniert! woher weiss ich, dass Daten zum Empfagen vorliegen, ohne das ich polle? wo müßte ich das Event auslösen!? wie wird das Programmtechnisch gelöst im Bezug auf das Empagen von Daten per TCP_Client?

                    Wäre dankbar für jede Hilfe!?

                    Comment


                    • #11
                      such dir dazu mal was bei google. Dein Kenntnisstand scheint noch nicht hoch genug. Lies doch noch ein wenig im OpenBook (kostenloses online buch) und dann suchst dir noch tutorials die sich mit netzwerkoperationen beschäftigen dann wirst du sehr schnell sehen wo es noch fehlt und wie du es besser machen kannst
                      Unsere Jugend ist unerträglich, unverantwortlich und entsetzlich anzusehen! - Aristoteles

                      Comment

                      Working...
                      X