VB.net flash XMLSocket替换应用程序
我正在尝试让一个VB.net(express 2010)应用程序连接到一个套接字服务器(保持连接打开),我该如何做?现在它使用FlashXMLSocket工作,我正在尝试使用现有服务器构建一个没有flash的新客户机 目前,我只是使用一个简单的窗口显示消息,以及一个发送消息的地方 它说我已连接,但不显示任何消息,发送的消息似乎没有任何效果。当我使用相同的IP和端口远程登录到服务器时,我可以看到收到的消息,因此我知道我可以连接到服务器。这是我的密码:VB.net flash XMLSocket替换应用程序,vb.net,sockets,xmlsocket,Vb.net,Sockets,Xmlsocket,我正在尝试让一个VB.net(express 2010)应用程序连接到一个套接字服务器(保持连接打开),我该如何做?现在它使用FlashXMLSocket工作,我正在尝试使用现有服务器构建一个没有flash的新客户机 目前,我只是使用一个简单的窗口显示消息,以及一个发送消息的地方 它说我已连接,但不显示任何消息,发送的消息似乎没有任何效果。当我使用相同的IP和端口远程登录到服务器时,我可以看到收到的消息,因此我知道我可以连接到服务器。这是我的密码: Imports System.Text Imp
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结尾。也就是说,在将数据分解为字符串时,
中的循环应该查找0而不是10,并且BuildString
应该在它发送的每个字符串后面附加nul字符(Send
),而不是Chr(0)
)vbCr
- 您确实应该使用编码将字节转换为字符。您现有的代码(如上所述修复时)至少应该向您显示一些数据,假设有任何数据要发送。但是,由于假设1字节==1字符,您可能会发现数据已损坏——这是因为Unicode非常流行,所以很少出现这种情况。:)我建议您使用StreamReader,而不是直接从流中读取——StreamReader在幕后使用编码(默认情况下为UTF-8,IIRC),并将处理大部分血淋淋的细节,因此您不需要担心读取多少字节才能获得一个字符。但是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的余弦,它将能够做到这一点(客户端,而不是服务器端),一旦我能得到数据,我就可以自己解析它。它很有效!非常感谢你!我会