vb.net flash xmlsocket替换应用程序
题
我正在尝试获取一个vb.net(Express 2010)应用程序连接到套接字服务器(保持连接打开),我该如何处理?现在,它使用Flash XMLSocket进行了工作,我正在尝试使用现有服务器构建一个新客户端。
目前,我只是使用一个简单的窗口显示消息,以及一个发送消息的地方。
它说我已经连接了,但是它没有显示任何消息,并且发送消息似乎没有效果,当我使用相同的IP和端口tlenet到服务器时,我可以看到消息传递给我,所以我知道我可以连接到服务器。这是我的代码:
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
解决方案
只要两个应用都会说TCP/IP,一个都有一个侦听服务器套接字,另一个应用程序知道该服务器套接字的IP和端口号,并且不会被阻止连接到它,那么哪种语言的应用程序都无关紧要写入。拥有TCP/IP之类的协议的目的是,它实际上独立于平台,操作系统,框架,语言或其他任何内容。
至于您的代码,一些事情脱颖而出:
每次发送任何内容时,您都可以创建一个附加到网络流的新流动者。如果作者关闭并在大多数IDISPOSABLE所做的最终确定上处置自己,它将关闭基础流(在TCPCLIENT的流中,将关闭连接)。如果您要使用作者发送数据,请将数据作为实例变量并重复使用,而不是每次创建新数据。
从阅读有关XMLSocket协议的信息,似乎已发送和接收的字符串应为无效。也就是说,您的循环在里面
BuildString
将数据分解成字符串时应该寻找0而不是10,并且Send
应该附加一个nul字符(Chr(0)
)而不是vbCr
到它发送的每个字符串。您确实应该使用编码将字节转换为字符。假设有任何数据要发送,您的现有代码(如上所述时)至少应向您显示一些数据。但是,由于假设1个字节== 1个字符,您可能会发现损坏的数据被损坏了 - 自Unicode击中它以来很少是这种情况。 :)我建议您使用流读器而不是直接从流中读取 - 流读器使用幕后编码(默认情况下的UTF-8 One,IIRC),并且会处理大多数血腥详细信息,因此您不必担心要阅读多少个字节来获得字符。但是,流读器没有内置的内容来进行异步读取。为了使用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
(顺便说一句,评论开始有趣,因此语法强调的行为不那么愚蠢。)