none
TcpClient Anwendung auf einem PC in VB simulieren RRS feed

  • Frage

  • Hallo Forum,

    ich versuche seit einigen Tagen in VB mit System.Net.Sockets (TcpClient, TcpListener, Pending, NetworkStream, ...) eine kleine Anwendung zusammen zu Stoppeln,  die es mir erlaubt eine Client/Server-Verbindung zu simulieren. Das heist, a) alls Server auf Horchposition gehen und dann als Client eine Verbindung aufbauen und Text senden/empfangen. Das muß doch prinzipiell gehen.

    Im folgenden Code-Beispiel bekomme ich (in der unterstrichenen Zeile) eine Fehlermeldung "Der Vorgang ist für nicht verbundene Sockets unzulässig." Versuche ich jedoch ein client.Connect davor, spricht er von "Sockets bereits verbunden". Jetzt weiß ich nicht mehr weiter, ich hoffe ihr könnt mir helfen,

    lg heinz

     

    Imports System.Net
    Imports System.Net.Sockets
    
    Module Module1
    
      Sub Main()
        Try
          ' Set the TcpListener on port 13000.
          Dim port As Int32 = 13000
          'Dim server As New TcpListener(IPAddress.Any, port)
          Dim server As New TcpListener(IPAddress.Parse("10.0.0.1"), port)
          ' Start listening for client requests.
          server.Start()
          ' Use the Pending method to poll the underlying socket instance for client connection requests.
          Dim s As Int16 = 0
    
          While s = 0
            If server.Pending() Then Exit While
            '  Hier wird der anrufende Client simuliert
            Connect("10.0.0.1", "Text vom Client")
          End While
          ' Buffer for reading data
          Dim bytes(1024) As [Byte]
          Dim data As [String] = Nothing
    
          ' Enter the listening loop.
          While True
            Console.Write("Waiting for a connection... ")
    
            ' Perform a blocking call to accept requests.
            ' You could also user server.AcceptSocket() here.
            Dim client As TcpClient = server.AcceptTcpClient()
            Console.WriteLine("Connected!")
    
            data = Nothing
    
            ' Get a stream object for reading and writing
            Dim stream As NetworkStream = client.GetStream()
    
            Dim i As Int32
    
            ' Loop to receive all the data sent by the client.
            i = stream.Read(bytes, 0, bytes.Length)
            While (i <> 0)
              ' Translate data bytes to a ASCII string.
              data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)
              Console.WriteLine([String].Format("Received: {0}", data))
    
              ' Process the data sent by the client.
              data = data.ToUpper()
    
              Dim msg As [Byte]() = System.Text.Encoding.ASCII.GetBytes(data)
    
              ' Send back a response.
              stream.Write(msg, 0, msg.Length)
              Console.WriteLine([String].Format("Sent: {0}", data))
    
              i = stream.Read(bytes, 0, bytes.Length)
    
            End While
    
            ' Shutdown and end connection
            client.Close()
          End While
        Catch e As SocketException
          Console.WriteLine("SocketException: {0}", e)
        End Try
    
        Console.WriteLine(ControlChars.Cr + "Hit enter to continue...")
        Console.Read()
    
      End Sub
    
      '------------------------------------------------------------------------
      Private Sub Connect(ByVal server As [String], ByVal message As [String])
        Try
          ' Create a TcpClient.
          ' Note, for this client to work you need to have a TcpServer 
          ' connected to the same address as specified by the server, port
          ' combination.
          Dim port As Int32 = 13000
          Dim tclient As New TcpClient(server, port)
          'client.Connect(server, port)      'doppelter Connect
          ' Translate the passed message into ASCII and store it as a Byte array.
          Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(message)
    
          ' Get a client stream for reading and writing.
          ' Stream stream = client.GetStream();
          Dim stream As NetworkStream = tclient.GetStream()
    
          ' Send the message to the connected TcpServer. 
          stream.Write(data, 0, data.Length)
    
          Console.WriteLine("Sent: {0}", message)
    
          ' Receive the TcpServer.response.
          ' Buffer to store the response bytes.
          ''data = New [Byte](256) {}
    
          ' String to store the response ASCII representation.
          ''Dim responseData As [String] = [String].Empty
    
          ' Read the first batch of the TcpServer response bytes.
          ''Dim bytes As Int32 = stream.Read(data, 0, data.Length)
          ''responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)
          ''Console.WriteLine("Received: {0}", responseData)
    
          ' Close everything.
          ''stream.Close()
          ''client.Close()
        Catch e As ArgumentNullException
          Console.WriteLine("ArgumentNullException: {0}", e)
        Catch e As SocketException
          Console.WriteLine("SocketException: {0}", e)
        End Try
    
        ''Console.WriteLine(ControlChars.Cr + " Press Enter to continue...")
        ''Console.Read()
      End Sub 'Connect
    
      '------------------------------------------------------------------------
      Public Sub PendingTeil(ByVal ipNr As String, ByVal portNumber As Long)
    
        Try
    
          'Dim ipAddress As IPAddress = Dns.Resolve("localhost").AddressList(0)  'ursprünglicher Code
          Dim ipAddress As IPAddress = Dns.GetHostEntry("localhost").AddressList(0)
          Dim tcpListener As New TcpListener(ipAddress, portNumber)
          tcpListener.Start()
    
          ' Use the Pending method to poll the underlying socket instance for client connection requests.
          If Not tcpListener.Pending() Then
    
            Console.WriteLine("Sorry, no connection requests have arrived")
    
          Else
    
            'Accept the pending client connection and return a TcpClient object initialized for communication.
            Dim tcpClient As TcpClient = tcpListener.AcceptTcpClient()
            ' Using the RemoteEndPoint property.
            Console.Write("I am listening for connections on ")
            Console.WriteLine(ipAddress.Parse(CType(tcpListener.LocalEndpoint, IPEndPoint).Address.ToString()))
            Console.Write("on port number ")
            Console.Write(CType(tcpListener.LocalEndpoint, IPEndPoint).Port.ToString())
          End If
        Catch
        End Try
    
      End Sub
    End Module
    
    Samstag, 19. Februar 2011 12:05

Antworten

  • Jetzt werde ich mich über die Analyse des Codes machen.

    Herzlichen Dank für deine Hilfe - aber ich denke ich werde dein Wissen noch einige Male benötigen,

    lg heinz


    Hallo Heinz, super das freut mich.

    Der Code funktioniert übrigens auch über das Internet Dazu musst Du nur die öffentlichen IP Adressen der beiden Router eingeben und eine entsprechende Port Weiterleitung in den Routern haben.

    Ach bitte mache eine NEUE Frage auf. Sonst wird das für die anderen, die ein Problem lösen müssen, zu unübersichtlich.

    schöne Grüße Ellen

     


    Ich benutze/ I'm using VB2008 & VB2010
    • Als Antwort markiert Heinz999 Montag, 21. Februar 2011 12:50
    Montag, 21. Februar 2011 12:06

Alle Antworten

  • Hallo Heinz,

    Dein Code geht. Ich habe folgende Änderungen vorgenommen:

      Try
       ' Set the TcpListener on port 13000.
       Dim port As Int32 = 13000
       Dim server As New TcpListener(IPAddress.Any, port)
       'Dim server As New TcpListener(IPAddress.Parse("10.0.0.1"), port)
       ' Start listening for client requests.
       server.Start()
    

    und diese hier:

    While s = 0
        If server.Pending() Then Exit While
        ' Hier wird der anrufende Client simuliert
        Connect("127.0.0.1", "Text vom Client")
       End While
    

    Dein Fehler ist: Man kann nicht auf ein und demselben IP Endpunkt zwei sockets verbinden

    Probier das mal so.

    schöne Grüße Ellen


    Ich benutze/ I'm using VB2008 & VB2010
    • Bearbeitet Ellen Ramcke Samstag, 19. Februar 2011 20:37 screenshot
    Samstag, 19. Februar 2011 16:33
  • Hallo Heinz,

    meine Änderungen Deines Codes sind erst einmal die Lösung der Fehlermeldung oben. Ich habe mir Deinen Code noch einmal genau angesehen und ich muss sagen, der ist noch weit entfernt von einer lauffähigen Lösung.

    Ich habe im Juli letzen Jahres hier ein unversielles TCP Chat Programm gepostet. Das folgende Programm ist eine Weiterentwicklung davon  Dieses möchte ich Dir zur Verfügung stellen. Die Benutzung ist ohne copyright.

    http://cid-c2d662ab4dd70d18.office.live.com/self.aspx/.Documents/TCP%5E_Chat.zip

    Das interesante an diesem Projekt ist die class TCPChat. Diese verwende ich jetzt in vielen Forms Anwendungen zur  TCP Kommunikation. Diese stellt einen asynchronen server bereit und arbeitet gleichzeitig als client

    Viel Spaß und schöne Grüße Ellen

     


    Ich benutze/ I'm using VB2008 & VB2010
    Samstag, 19. Februar 2011 20:25
  • Hallo Ellen,

    danke für die rasche Antwort. Leider ändern deine Änderungen bei mir das Ergebnis nicht.

    Prinzipiell geht es mir um das Verstehen und das Zusammenspiel der einzelnen Funktionen. Wenn ich deine Aussage "Man kann nicht auf ein und demselben IP Endpunkt zwei sockets verbinden" wörtlich nehme, ist eigentlich mein Vorhaben nicht möglich (was dein Testergebnis ja widerlegt). Die zweite Änderung auf "127.0.0.1" verstehe ich nicht ganz. Kannst du das etwas näher erläutern?

    Ich habe mir dein "TCPChat" herunter geladen und werde nun versuchen anhand der Code-Verfolgung schlauer zu werden.

    Nochmals Danke und schöne Grüße Heinz

    Sonntag, 20. Februar 2011 09:43
  • Die zweite Änderung auf "127.0.0.1" verstehe ich nicht ganz. Kannst du das etwas näher erläutern?

    Hallo Heinz,

    nehmen wir mal an Dein Netzwerkadapter hat die IP Adresse 192.168.2.1.

    Dann kann man einen TCPlistener verbinden mit 192.168.2.1:13000 auf port 13000. (Das nennt man Endpunkt)  eine zweite Instanz auf demselben Rechner kann diesen Endpunkt nicht mehr verwenden. Das gilt für einen Client sowie einen server. Die Fehlermeldung:  "Sockets bereits verbunden" ist ja eindeutig.

    Was aber geht ist folgendes:

    Einen listenener auf 0.0.0.0:13000 legen und einen client auf 192.168.2.1:13000. Dann unterhalten sich client und listener über den port 13000.

    Die IP Adresse 127.0.0.1 hat eine Sonderfunktion. Diese Adresse ist das loop back device eines host. Lese bitte Seite 26 Einführung in TCP/IP

     

    Ich stell Dir noch einen link ein. Einführung in TCP/IP. Muss ich noch suchen.

    schöne Grüße Ellen

    Hier die links. Hab ich alles mühevoll durchgearbeitet. An diesen Grundlagen kommt man nicht vorbei, trotz komfortabler NET Klassen

    Einstiegsseite wiki:

    http://de.wikipedia.org/wiki/TCP/IP-Referenzmodell#TCP.2FIP-Referenzmodell

    und hier das pdf Dokument runterladen

    http://www.rvs.uni-bielefeld.de/~heiko/tcpip/

     

     


    Ich benutze/ I'm using VB2008 & VB2010
    • Bearbeitet Ellen Ramcke Sonntag, 20. Februar 2011 11:38 Nachtrag
    Sonntag, 20. Februar 2011 11:07
  • Hallo Hellen,

    danke für die Links. Ich bezog bisher mein Basiswissen aus "Internet intern" von Tischler/Jennrich, welches allerdings schon etwas älter ist. Im Prinzip ist mir die Sache verständlich, der Teufel liegt im Detail und in der Umsetzung.

    Aber nun ein anderes Problem:

    Ich habe nun TCPChat benutzt und die Fehlermeldung "sendData: Es konnte keine Verbindung hergestellt werden, da der Zielcomputer die Verbindung verweigert" bekommen. Ich habe nun versucht in der Windows-Firewall (ich fahre XP-Home) das Port 5000 zuzulassen, als Name habe ich "TCPChat" eingegeben - kein Erfolg.

    Meine Frage dazu: Wie kann ich der Anwendung den Zugriff ermöglichen? Spielt der Router (Internet Gateway) hier auch eine Rolle und muß ich auch dort die Anwendung freigeben?

    lg Heinz

     

    Sonntag, 20. Februar 2011 13:22
  • Hallo Heinz,

    setze mal das Häckchen unten in der Firewall. Ich benutze auch XP Home. Es ist die Firewall, welche den Zugriff sperrt.

     

    Gruß Ellen


    Ich benutze/ I'm using VB2008 & VB2010
    Sonntag, 20. Februar 2011 13:43
  • Hallo Ellen,

    ich habe diese beiden Eintragungen nicht in meiner Firewall?

    Auch wenn ich die Firewall ausschalte bekomme ich die gleiche Meldung?

    lg heinz

    ich hoffe ich bin nicht zu lästig

     

     

    Sonntag, 20. Februar 2011 14:16
  • http://cid-c2d662ab4dd70d18.office.live.com/self.aspx/.Documents/ctsupport-Ellen-MD96500-port5500.zip

    Hallo Heinz,

    ich habe hier PC Ferndiagnose. Ich möchte mir das mal ansehen. Pack das Programm aus und starte es. Doppelklicken auf "Hier doppelklicken" und ich bin in Deinem Computer drin. Eibverstanden?

    Gruß Ellen

     


    Ich benutze/ I'm using VB2008 & VB2010
    Sonntag, 20. Februar 2011 14:50
  • Hallo Ellen,

    ja, geht Ok. Gib mir bitte Bescheid wann ich das tun sollen,

    lg heinz

    Montag, 21. Februar 2011 07:21
  • Hallo Ellen,

    TCPChat funktioniert nun. Mein Fehler war, dass ich es nicht installiert hatte sondern nur mit dem Debugger ausgeführt hatte.

    Nach der Installation hat mich die Firewall gefragt ob ich es weiter blockieren will. Nachdem ich dies verneint habe, habe ich es auch in der Firewall eingetragen gefunden.

    Jetzt werde ich mich über die Analyse des Codes machen.

    Herzlichen Dank für deine Hilfe - aber ich denke ich werde dein Wissen noch einige Male benötigen,

    lg heinz

    Montag, 21. Februar 2011 08:57
  • Jetzt werde ich mich über die Analyse des Codes machen.

    Herzlichen Dank für deine Hilfe - aber ich denke ich werde dein Wissen noch einige Male benötigen,

    lg heinz


    Hallo Heinz, super das freut mich.

    Der Code funktioniert übrigens auch über das Internet Dazu musst Du nur die öffentlichen IP Adressen der beiden Router eingeben und eine entsprechende Port Weiterleitung in den Routern haben.

    Ach bitte mache eine NEUE Frage auf. Sonst wird das für die anderen, die ein Problem lösen müssen, zu unübersichtlich.

    schöne Grüße Ellen

     


    Ich benutze/ I'm using VB2008 & VB2010
    • Als Antwort markiert Heinz999 Montag, 21. Februar 2011 12:50
    Montag, 21. Februar 2011 12:06