VB.net flash XMLSocket替换应用程序

VB.net flash XMLSocket替换应用程序,vb.net,sockets,xmlsocket,Vb.net,Sockets,Xmlsocket,我正在尝试让一个VB.net(express 2010)应用程序连接到一个套接字服务器(保持连接打开),我该如何做?现在它使用FlashXMLSocket工作,我正在尝试使用现有服务器构建一个没有flash的新客户机 目前,我只是使用一个简单的窗口显示消息,以及一个发送消息的地方 它说我已连接,但不显示任何消息,发送的消息似乎没有任何效果。当我使用相同的IP和端口远程登录到服务器时,我可以看到收到的消息,因此我知道我可以连接到服务器。这是我的密码: Imports System.Text Imp

我正在尝试让一个VB.net(express 2010)应用程序连接到一个套接字服务器(保持连接打开),我该如何做?现在它使用FlashXMLSocket工作,我正在尝试使用现有服务器构建一个没有flash的新客户机

目前,我只是使用一个简单的窗口显示消息,以及一个发送消息的地方

它说我已连接,但不显示任何消息,发送的消息似乎没有任何效果。当我使用相同的IP和端口远程登录到服务器时,我可以看到收到的消息,因此我知道我可以连接到服务器。这是我的密码:

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
导入系统文本
导入System.Net.Sockets
公开课表格1
继承System.Windows.Forms.Form
公共委托子显示调用程序(ByVal t作为字符串)
专用mobjClient作为TcpClient
专用数据(1024)作为字节
作为新StringBuilder()的专用mobjText
私有子表单1_Load(ByVal发送方作为System.Object,ByVal e作为System.EventArgs)处理MyBase.Load
mobjClient=newtcpclient(“example.com”,7777)
DisplayText(“连接到主机”和“example.com”)
mobjClient.GetStream.BeginRead(marData,0,1024,地址为DoRead,Nothing)
端接头
私有子BTN发送\单击(ByVal发送方作为System.Object,ByVal e作为System.EventArgs)处理BTN发送。单击
发送(txtSend.Text)
txtSend.Text=“”
端接头
专用子发送(ByVal t作为字符串)
Dim w作为新IO.StreamWriter(mobjClient.GetStream)
w、 写入(t&vbCr)
w、 刷新()
显示文本(vbNewLine和“Sent”和t)
端接头
私有子数据段(由VAL ar作为IAsyncResult)
Dim intCount为整数
尝试
intCount=mobjClient.GetStream.EndRead(ar)
如果intCount小于1,则
MarkAsDisconnected()
出口接头
如果结束
构建字符串(marData、0、intCount)
mobjClient.GetStream.BeginRead(marData,0,1024,地址为DoRead,Nothing)
捕获e作为例外
MarkAsDisconnected()
结束尝试
端接头
私有子构建字符串(ByVal Bytes()作为字节,ByVal offset作为整数,ByVal count作为整数)
Dim intIndex为整数
对于intIndex=偏移到偏移+计数-1
如果字节(intIndex)=10,则
mobjText.Append(vbLf)
Dim params()作为对象={mobjText.ToString}
调用(新的DisplayInvoker(AddressOf Me.DisplayText),参数)
mobjText=新的StringBuilder()
其他的
mobjText.Append(ChrW(字节(intIndex)))
如果结束
下一个
端接头
私有子标记asdisconnected()
txtSend.ReadOnly=True
btnSend.Enabled=False
显示文本(vbNewLine和“disconnected”)
端接头
私有子显示文本(ByVal t作为字符串)
txtDisplay.AppendText(t)
端接头
末级

只要两个应用程序都使用TCP/IP,其中一个有一个侦听服务器套接字,另一个知道该服务器套接字的IP和端口号,并且没有被阻止连接到该套接字,那么这两个应用程序使用哪种语言编写都无关紧要。拥有像TCP/IP这样的协议的意义在于它实际上独立于平台、操作系统、框架、语言或其他任何东西

至于您的代码,有几点很突出:

  • 每次发送任何内容时,您都会创建一个连接到网络流的新StreamWriter。如果编写器在完成时关闭并处理自己(大多数IDisposables都会这样做),它将关闭底层流(对于TcpClient的流,底层流将关闭连接)。如果要使用writer发送数据,请保留一个作为实例变量并重用它,而不是每次都创建一个新的实例变量

  • 通过阅读XmlSocket协议,似乎发送和接收的字符串应该以null结尾。也就是说,在将数据分解为字符串时,
    BuildString
    中的循环应该查找0而不是10,并且
    Send
    应该在它发送的每个字符串后面附加nul字符(
    Chr(0)
    ),而不是
    vbCr

  • 您确实应该使用编码将字节转换为字符。您现有的代码(如上所述修复时)至少应该向您显示一些数据,假设有任何数据要发送。但是,由于假设1字节==1字符,您可能会发现数据已损坏——这是因为Unicode非常流行,所以很少出现这种情况。:)我建议您使用StreamReader,而不是直接从流中读取——StreamReader在幕后使用编码(默认情况下为UTF-8,IIRC),并将处理大部分血淋淋的细节,因此您不需要担心读取多少字节才能获得一个字符。但是StreamReader没有内置用于异步读取的功能。为了使用StreamReader,您必须稍微更改您的内容,并为其生成一个线程

您可以直接使用解码器,这与StreamReader的功能非常相似。可以这样使用它:

''// 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

(顺便说一句,注释开头很有趣,因此语法突出显示的行为就不那么愚蠢了。)

挑剔:客户端通常连接到服务器,而不是相反。例外是一些协议,如FTP,允许服务器打开辅助套接字进行数据传输。XmlSocket部分似乎特别相关,因为它定义了所使用的协议,但远程服务器的语言/平台并不重要。不过,这确实增加了一个论点的分量,即您应该使用UTF-8之类的编码来解码字符串,而不仅仅是假设每个字节都是一个字符(这种情况很少再出现)。是的,我理解这一部分,我需要的是visual basic.net的余弦,它将能够做到这一点(客户端,而不是服务器端),一旦我能得到数据,我就可以自己解析它。它很有效!非常感谢你!我会