jjzjj

vb.net - TCP客户端到服务器通信

coder 2023-09-20 原文

我只需要在windows窗体vb.net上寻找一个简单的tcpclient/listner示例。我是一个新手,微软tcpclient/listner类的例子不是我想要的。我只想让tcpclient发送一条消息,让tcplistener获取该消息并将消息发送回“我收到了您的消息”?
一点帮助就好了。我有一些代码,但只是将消息发送到服务器,而不是从服务器返回到客户端。
任何帮助都将不胜感激。

最佳答案

TCP通信被称为基于流的,这意味着它不处理任何数据包。因此,接收到的消息可以是部分的,也可以集中在一起。
例如,您可以发送:
Hello!
How are you?
但你可能会收到:
Hello!How are you?
或:
Hello!How ar
e you?
(或类似的东西)
要解决这个问题,您必须应用称为“长度前缀”的东西。长度前缀(或长度前缀)是指在发送消息之前,将消息的长度(字符数)放在消息的开头。然后,端点可以读取该消息,然后根据其长度读取每个消息,因此,部分消息或聚合在一起的消息不会有问题。
这并不是最简单的事情,但是我已经创建了两个类来为您完成这一切。请参阅下面的示例,了解如何将它们用于简单的基于消息的通信。
链接到源:http://www.mydoomsite.com/sourcecodes/ExtendedTcpClient.zip
链接到C源:http://www.mydoomsite.com/sourcecodes/ExtendedTcpClient%20CSharp.zip
示例用法
请注意,在这些示例中,Client不是指客户端,而是指TCPClient。
服务器端
首先为ExtendedTcpClient声明一个新变量,并确保
在声明中包含WithEvents

Dim WithEvents Client As ExtendedTcpClient

然后需要一个TcpListener和一个Timer来检查传入连接。
Dim Listener As New TcpListener("0.0.0.0", 5555) 'Listen for any connection on port 5555.
Dim WithEvents Tmr As New System.Windows.Forms.Timer

然后您需要订阅计时器的Tick事件。
Private Sub Tmr_Tick(sender As System.Object, e As System.EventArgs) Handles Tmr.Tick

End Sub

在这里,您可以通过Listener.Pending()方法检查传入连接。当您要接受连接时,首先声明一个新的
ExtendedTcpClient的实例。该类要求
表单作为其所有者,在此应用程序中,Me是当前表单。
然后将ExtendedTcpClient.SetNewClient()方法用于
Listener.AcceptTcpClient()作为应用
TcpClient来自听众。将此代码放入Tmr_Tick子命令中:
If Listener.Pending() = True Then
    Client = New ExtendedTcpClient(Me)
    Client.SetNewClient(Listener.AcceptTcpClient())
End If

现在客户机和服务器相互连接。
现在您需要订阅
客户。创建一个子类,这样:
Private Sub Client_PacketReceived(sender As Object, e As ExtendedTcpClient.PacketReceivedEventArgs) Handles Client.PacketReceived

End Sub

所有接收到的数据都以字节数组的形式显示。
PacketReceived子菜单中,您可以将接收到的数据包作为文本输出到PacketReceived子菜单中。只需检查数据包头是否TextBox,然后
您可以转换接收到的数据包内容(它是
字节,通过PlainText访问字符串并将其放入
e.Packet.Contents
If e.Packet.Header = TcpMessagePacket.PacketHeader.PlainText Then
    TextBox1.AppendText("Message recieved: " & System.Text.Encoding.Default.GetString(e.Packet.Contents) & Environment.NewLine)
End If

TextBox将字节数组转换为普通文本。
System.Text.Encoding.Default.GetString()sub中,您还可以使它向客户机发送“message received”。
Dim ResponsePacket As New TcpMessagePacket(System.Text.Encoding.Default.GetBytes("Message received."), TcpMessagePacket.PacketHeader.PlainText)
ResponsePacket.Send(Client.Client) 'Get the ExtendedTcpClient's underlying TcpClient.

最后,当关闭表单时,只需要断开客户机。
Private Sub ServerWindow_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    If Client IsNot Nothing Then Client.Disconnect()
End Sub

这就是服务器端。
客户端
对于客户端,您将与服务器端做几乎相同的工作,尽管您不需要PacketReceivedTcpListener
Dim WithEvents Client As New ExtendedTcpClient(Me) 'The current form as its owner.

通过您提供给侦听器的IP和端口连接到服务器。
Client.Connect("127.0.0.1", 5555) 'Connects to localhost (your computer) at port 5555.

现在,如果要将文本发送到服务器,您需要执行以下操作(例如,按钮):
Dim MessagePacket As New TcpMessagePacket(System.Text.Encoding.Default.GetBytes(TextBox2.Text), TcpMessagePacket.PacketHeader.PlainText)
MessagePacket.Send(Client.Client)

Timer包含要发送的文本。
最后,您还需要在此处订阅TextBox2事件,以检查服务器的响应。在那里,您可以像服务器一样接收文本。
Private Sub Client_PacketReceived(sender As Object, e As ExtendedTcpClient.PacketReceivedEventArgs) Handles Client.PacketReceived
    If e.Packet.Header = TcpMessagePacket.PacketHeader.PlainText Then
        TextBox1.AppendText(System.Text.Encoding.Default.GetString(e.Packet.Contents) & Environment.NewLine) 'Prints for example "Message received." from the server.
    End If
End Sub

现在一切都应该正常了!
链接到完整的示例项目(仅客户端到服务器):http://www.mydoomsite.com/sourcecodes/TCP%20Messaging%20System.zip
链接到C示例:http://www.mydoomsite.com/sourcecodes/CSharp%20TCP%20Messaging%20System.zip
如果要向类中添加更多的头(头指示包的类型),只需打开PacketReceived并在TcpMessagePacket.vb枚举中添加更多值(位于名为PacketHeader的区域中)。
希望这有帮助!
示例项目的屏幕截图
(单击图像可获得更高的分辨率)

关于vb.net - TCP客户端到服务器通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35233852/

有关vb.net - TCP客户端到服务器通信的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  5. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  6. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  7. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  8. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  9. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  10. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

随机推荐