Frage

Ich versuche zu bekommen eine VB.net (express 2010) App auf einen Socket-Server (wobei die Verbindung offen) zu verbinden, wie würde ich über diese gehen? Im Moment funktioniert mit Flash xmlsocket, ich versuche, einen neuen Client ohne Blitz zu bauen, den bestehenden Server.

Zur Zeit bin ich nur ein einfaches Fenster mit Anzeige von Nachrichten, und einen Ort, um Nachrichten zu senden.

Er sagt, ich bin verbunden, aber es zeigt keine Nachrichten und gesendeten Nachrichten scheinen keine Wirkung zu haben, wenn ich Telnet auf dem Server die gleiche IP und Port verwenden, kann ich Nachrichten in mir kommen sehen, damit ich weiß, ich kann mit dem Server verbinden. Hier ist mein Code:

Imports System.Text
Imports System.Net.Sockets


Public Class Form1
    Inherits System.Windows.Forms.Form

    Public Delegate Sub DisplayInvoker(ByVal t As String)

    Private mobjClient As TcpClient
    Private marData(1024) As Byte
    Private mobjText As New StringBuilder()

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        mobjClient = New TcpClient("example.com", 7777)
        DisplayText("Connected to host " & "example.com")

        mobjClient.GetStream.BeginRead(marData, 0, 1024, AddressOf DoRead, Nothing)
    End Sub

    Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
        Send(txtSend.Text)
        txtSend.Text = ""
    End Sub

    Private Sub Send(ByVal t As String)
        Dim w As New IO.StreamWriter(mobjClient.GetStream)
        w.Write(t & vbCr)
        w.Flush()
        DisplayText(vbNewLine & "Sent " & t)
    End Sub

    Private Sub DoRead(ByVal ar As IAsyncResult)
        Dim intCount As Integer
        Try
            intCount = mobjClient.GetStream.EndRead(ar)
            If intCount < 1 Then
                MarkAsDisconnected()
                Exit Sub
            End If

            BuildString(marData, 0, intCount)

            mobjClient.GetStream.BeginRead(marData, 0, 1024, AddressOf DoRead, Nothing)
        Catch e As Exception
            MarkAsDisconnected()
        End Try
    End Sub

    Private Sub BuildString(ByVal Bytes() As Byte, ByVal offset As Integer, ByVal count As Integer)
        Dim intIndex As Integer

        For intIndex = offset To offset + count - 1
            If Bytes(intIndex) = 10 Then
                mobjText.Append(vbLf)

                Dim params() As Object = {mobjText.ToString}
                Me.Invoke(New DisplayInvoker(AddressOf Me.DisplayText), params)

                mobjText = New StringBuilder()
            Else
                mobjText.Append(ChrW(Bytes(intIndex)))
            End If
        Next
    End Sub

    Private Sub MarkAsDisconnected()
        txtSend.ReadOnly = True
        btnSend.Enabled = False
        DisplayText(vbNewLine & "Dissconnected")
    End Sub

    Private Sub DisplayText(ByVal t As String)
        txtDisplay.AppendText(t)
    End Sub
End Class
War es hilfreich?

Lösung

Solange beide Anwendungen TCP / IP sprechen, hat man einen Abhör Server-Socket und der andere kennt die IP und die Portnummer des Server-Socket und eine Verbindung zu ihm nicht blockiert, es spielt keine Rolle, welche Sprache entweder app ist geschrieben in. der Punkt ein Protokoll wie TCP / IP zu haben, ist, dass es effektiv unabhängig von Plattform, Betriebssystem, Rahmen, die Sprache oder so gut wie nichts anderes.

Wie für Ihren Code, ein paar Dinge fallen auf:

  • Sie sind eine neue Stream Erstellen mit dem Netzwerk-Stream angebracht jedes Mal, wenn Sie etwas schicken. Wenn die Schriftsteller schließt und verfügt selbst über Finalisierung, die die meisten IDisposables tun, würde es den zugrunde liegenden Stream schließen (was im Falle des TcpClient Stream, wird die Verbindung schließen). Wenn Sie vorhaben, einen Schriftsteller zu verwenden, um Daten zu senden, halten ein als Instanzvariable und wiederverwenden, anstatt einen neuen jedes Mal zu schaffen.

  • Aus der Lektüre über das XMLSocket-Protokoll, so scheint es, die Saiten gesendet und empfangen werden sollten nullterminierte sein. Das heißt, sollten Sie Ihre Schleife in BuildString für 0 suchen, anstatt 10, wenn die Daten in Strings Zerschlagung und Send sollte ein NUL-Zeichen (Chr(0)) eher als ein vbCr zu jeder Zeichenfolge sendet sie werden angehängt wird.

  • Sie sollten wirklich eine Codierung zu konvertieren verwenden Bytes Zeichen. Ihr vorhandener Code (wenn festgelegt wie oben) sollte zumindest zeigen Ihnen einige Daten, vorausgesetzt, es irgendeine gesendet werden. Sie können die Daten beschädigt gut finden, wenn auch aufgrund der Annahme, dass 1 Byte == 1 char - was selten der Fall ist, da Unicode traf es groß. :) Ich würde vorschlagen, dass Sie einen Stream verwenden, anstatt direkt aus dem Stream zu lesen - die Stream verwendet eine Codierung hinter den Kulissen (die UTF-8 eine standardmäßig IIRC), und die meisten der blutigen Details handhaben, so dass Sie nicht brauchen, um Sorgen darüber, wie viele Bytes zu lesen Zeichen zu erhalten. Aber StreamReaders haben nicht das Zeug in ihnen gebaut tun async liest. Sie müßten Ihre Sachen ein bisschen ändern, und Laichen einen Thread für sie, um einen Stream zu verwenden.

Sie könnten einen Decoder verwenden, um direkt, was ziemlich viel ist, was ein Stream tut. Verwenden Sie es so etwas wie folgt aus:

''// This is important!  Keep the Decoder and reuse it when you read this socket.
''// If you don't, a char split across two reads will break.
Private _decoder As Decoder = UTF8Encoding.GetDecoder()


Private Sub BuildString(bytes() As Byte, offset As Integer, byteCount As Integer)

    ''// Here's where the magic happens.  The decoder converts bytes into chars.
    ''// But it remembers the final byte(s), and doesn't convert them,
    ''// until they form a complete char.
    Dim chars(bytes.Length) As Char
    Dim charCount as Integer = _decoder.GetChars(bytes, offset, byteCount, chars, 0)

    For i as Integer = 0 to charCount - 1
        if chars(i) = chr(0) then           ''// The fix for bullet #2
            mObjText.Append(vbLf)

            Dim params() As Object = {mobjText.ToString}
            Me.Invoke(New DisplayInvoker(AddressOf Me.DisplayText), params)

            ''// You don't have to make a new StringBuilder, BTW -- just clear it.
            mObjText.Length = 0
        else
            mObjText.Append(chars(i))
        end if
    Next
End Sub

(BTW, werden die Kommentare gestartet lustig, so dass die Syntax-Hervorhebung wirkt weniger dumm.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top