【问题标题】:Using streams through TcpClient and TcpServer通过 TcpClient 和 TcpServer 使用流
【发布时间】:2017-08-20 00:31:59
【问题描述】:

我尝试将数据从服务器 (TcpListener) 发送到客户端 (TcpClient)。我使用 Windows 窗体应用程序和下一个代码:

Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Runtime.InteropServices

Public Class Form1

Private Server As TcpListener = Nothing
Private ServerThread As Thread = Nothing
Dim tcpclnt As TcpClient
Dim stream As NetworkStream

Public Shared bytes(1024) As Byte
Public Shared data As String = Nothing


Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Shown
    Server = New TcpListener(IPAddress.Any, 40000)
    ServerThread = New Thread(AddressOf ConnectionListener)
    ServerThread.IsBackground = True
    ServerThread.Start()
    TextBox1.Text = "Server started!"

End Sub

Private Sub ConnectionListener()
    Try
        Server.Start()


        While True
            Dim myClient As TcpClient = Server.AcceptTcpClient()
            Dim T As New Thread(AddressOf SomeClientActions)
            T.Start(myClient)
            Invoke(Sub() TextBox1.Text = TextBox1.Text + Environment.NewLine + "Client connected")


            ' HERE IM TRYING TO READ DATA FROM STREAM
            stream = myClient.GetStream()
            Dim i As Int32
            i = stream.Read(bytes, 0, bytes.Length)

            While True
                ' Translate data bytes to a ASCII string.
                data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)
                Invoke(Sub() TextBox3.Text = "Received: {0}" + data)

                ' Process the data sent by the client.
                data = data.ToUpper()
                Dim msg As Byte() = System.Text.Encoding.ASCII.GetBytes(data)

                ' Send back a response.
                stream.Write(msg, 0, msg.Length)
                Invoke(Sub() TextBox3.Text = "Sent: {0}" + data)

                i = stream.Read(bytes, 0, bytes.Length)

           End While


            myClient.Close()
        End While

    Catch ex As Exception
        MessageBox.Show("Unable to Accept Connections", "Server Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Try
    Application.ExitThread()

End Sub

Private Sub SomeClientActions(ByVal client As Object)
    ' ... do something with "client" in here ...
    ' MAYBE SOME CODE HERE?..
End Sub


Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    Server.Stop()
End Sub


Private Sub ButtonClientConnection_Click(sender As Object, e As EventArgs) Handles Button2.Click
    tcpclnt = New TcpClient()
    tcpclnt.Connect("127.0.0.115", 40000)
End Sub

Private Sub ButtonSendData_Click(sender As Object, e As EventArgs) Handles Button3.Click
    ' HERE IM TRYING TO WRITE DATA TO STREAM FROM TEXTBOX
    Dim msg As New System.IO.StringReader(TextBox2.Text)
    Dim msgstr As String = msg.ReadToEnd
    Dim msgbyte() As Byte = Encoding.UTF8.GetBytes(msgstr)
    stream.Write(msgbyte, 0, msgbyte.Length)
End Sub


End Class

我正在尝试做的事情:我创建服务器,然后在 textbox1 中按下按钮 ButtonClientConnection' and create and connect client (TcpClient). That works - I get stringsServer startedandClient connected`。

现在我想做:在 textbox2 中放入一些文本,按下按钮 ButtonSendData 并通过流将这些数据从客户端传输到服务器,并将这些数据写入另一个文本框(textbox3)。 我的尝试在代码中,但没有任何反应 - 正如我在调试器中看到的那样,我在流中写入了一些数据,但无法读取它,因为我用于从流中读取数据的代码在客户端连接时仅执行 1 次。

如何永久读取数据?并按ButtonSendData 将其正确写入流式传输? 我做了一些解决方法,看起来它卡在了线上:

i = stream.Read(bytes, 0, bytes.Length)

代码停在这里,不能在这个线程中进一步。

【问题讨论】:

  • NetworkStread.Read() 阻塞调用线程,直到有东西要接收,所以当你发送数据时应该继续执行。
  • @VisualVincent 啊哈!所以我只是错误地发送数据?你能看看我的ButtonSendData_Click 函数吗?也许我在另一个线程中做?

标签: .net vb.net tcp stream streaming


【解决方案1】:

您通过错误的流发送数据。 stream 是服务器的流,但您没有 tcpclnt 的流。

试试这个:

Dim clientstream As NetworkStream

Private Sub ButtonClientConnection_Click(sender As Object, e As EventArgs) Handles Button2.Click
    tcpclnt = New TcpClient()
    tcpclnt.Connect("127.0.0.115", 40000)
    clientstream = tcpclnt.GetStream()
End Sub

Private Sub ButtonSendData_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Dim msgbyte() As Byte = Encoding.UTF8.GetBytes(TextBox2.Text)
    clientstream.Write(msgbyte, 0, msgbyte.Length)
End Sub

如您所见,我还删除了StringReader,因为它完全没有必要。您创建它只是为了再次将其读回字符串,您可以直接从 TextBox2.Text 获取字节。

【讨论】:

  • Visual Vincent,再次感谢您这么快的回复!我删除了ButtonSendData_Click 中的多余行。我在 Sub ConnectionListener 中评论流定义,但它仍然停留在 i = clientstream.Read(bytes, 0, bytes.Length) 行。请你再看一遍好吗!我在我的问题中添加了代码中的所有编辑。
  • @Mikhail_Sam :Nonono,除了我在回答中显示的内容之外,您不应该更改任何其他内容。您需要两个不同的流:客户端和服务器。
  • @Mikhail_Sam :如果 server 从 client 流 接收,那么您将永远不要获取您从 客户端流 发送的数据。客户端发送到服务器流,反之亦然。 -- 你应该把它分成两个应用程序(或至少两个表单),这样你就不会轻易混淆它们。
  • @Mikhail_Sam :这里有一个关于如何划分的小例子:imgur.com/KCnQ6m3
  • 我明白了!现在它可以工作了,我可以发送和收集数据了!最后一个问题:我无法理解如何只显示一次接收到的数据:我将文本放入 textbox2,按 SendData,它会写入clientstream。然后stream 被激活(我们返回到 ConnectionListener 函数),它从stream 读取数据并且......然后呢?现在在我的循环中,它将此文本放在 TextBox3 中(是的,这是我想要的),但它是无限循环。怎么说他总是阅读stream,如果它不为空,则将数据放入TextBox3?或者最好再问一个关于这个的问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多