【问题标题】:Tcp Connection only reads one messageTcp Connection 只读取一条消息
【发布时间】:2017-01-02 08:31:06
【问题描述】:

我正在尝试创建一个需要 TcpConnection 的简单游戏。

所以我创建了一个包含 TcpListener 的 Server 类,Client 和 TcpClient 也是如此。但是当我附加我的 Listener Sub 并发送消息时,它只会在第一个被调用:

服务器

Imports System.Net.Sockets

Public Class Server
    Inherits ConnectionPartner

    Private Server As TcpListener
    Private Client As TcpClient
    Private Stream As NetworkStream
    Private Port As Integer

    Public Sub Init(ByVal port As Integer)
        Server = New TcpListener(port)
    End Sub

    Public Sub Open()
        Server.Start()
        Client = Server.AcceptTcpClient()
        Stream = Client.GetStream()
    End Sub

    Public Overrides Sub Write(ByVal Message As String)
        Dim Bytes() As Byte = Encoder.GetBytes(Message)
        Me.Write(Bytes)
    End Sub
    Public Overrides Sub Write(ByVal Message() As Byte)
        If Stream Is Nothing Then Return
        Stream.Write(Message, 0, Message.Length)
    End Sub

    Public Overrides Sub Listen(ByVal Handler As Action(Of String))
        Listen(Sub(ByVal Message() As Byte)
                   Handler(Encoder.GetString(Message))
               End Sub)
    End Sub
    Public Overrides Sub Listen(ByRef Handler As Action(Of Byte()))
        Dim Buffer(Client.ReceiveBufferSize()) As Byte

        While (True)
            Utils.Log("Listening")
            Client.GetStream().Read(Buffer, 0, Buffer.Length)
            Handler(Buffer)
        End While
    End Sub

    Public Sub Close()
        Try
            Client.Close()
        Catch ex As Exception

        End Try
        Try
            Server.Stop()
        Catch ex As Exception

        End Try
    End Sub

End Class

客户

Imports System.Net
Imports System.Net.Sockets

Public Class Client
    Inherits ConnectionPartner

    Private Socket As TcpClient
    Private Stream As NetworkStream
    Private Port As Integer

    Public Sub Init()
        Socket = New TcpClient()
    End Sub

    Public Sub Open(ByVal Ip As IPAddress, ByVal Port As Integer)
        Socket.Connect(Ip, Port)
        Stream = Socket.GetStream()
    End Sub

    Public Overrides Sub Write(ByVal Message As String)
        Dim Bytes() As Byte = Encoder.GetBytes(Message)
        Me.Write(Bytes)
    End Sub
    Public Overrides Sub Write(ByVal Message() As Byte)
        If Stream Is Nothing Then Return
        Stream.Write(Message, 0, Message.Length)
    End Sub

    Public Overrides Sub Listen(ByVal Handler As Action(Of String))
        Listen(Sub(ByVal Message() As Byte)
                   Handler(Encoder.GetString(Message))
               End Sub)
    End Sub
    Public Overrides Sub Listen(ByRef Handler As Action(Of Byte()))
        Dim Buffer(Socket.ReceiveBufferSize()) As Byte

        While (True)
            Utils.Log("Listening")
            Stream.Read(Buffer, 0, Buffer.Length)
            Handler(Buffer)
        End While
    End Sub

    Public Sub Close()
        Try
            Socket.Close()
        Catch ex As Exception

        End Try
    End Sub

End Class

我的测试课

Imports System.Net
Imports System.Threading

Class MainWindow

    Private Server As Server = New Server()
    Private Client As Client = New Client()
    Private C As Connection
    Private Port As Integer = My.Resources.Port

    Private Sub button_client_init_Click(sender As Object, e As RoutedEventArgs) Handles button_client_init.Click
        Client.Init()
    End Sub

    Private Sub button_client_start_Click(sender As Object, e As RoutedEventArgs) Handles button_client_start.Click
        Client.Open(Dns.GetHostEntry("localhost").AddressList(1), Port)
    End Sub

    Private Sub button_client_write_Click(sender As Object, e As RoutedEventArgs) Handles button_client_write.Click
        Client.Write("bar")
    End Sub

    Private Sub button_client_listen_Click(sender As Object, e As RoutedEventArgs) Handles button_client_listen.Click
        Dim T As Thread = New Thread(Sub()
                                         Client.Listen(Sub(ByVal M As String)
                                                           Log("Client:" & M)
                                                       End Sub)
                                     End Sub)
        T.Start()
    End Sub

    Private Sub button_server_init_Click(sender As Object, e As RoutedEventArgs) Handles button_server_init.Click
        Server.Init(Port)
    End Sub

    Private Sub button_server_start_Click(sender As Object, e As RoutedEventArgs) Handles button_server_start.Click
        Dim T As Thread = New Thread(Sub()
                                         Server.Open()
                                     End Sub)
        T.Start()
    End Sub

    Private Sub button_server_write_Click(sender As Object, e As RoutedEventArgs) Handles button_server_write.Click
        Server.Write("foo")
    End Sub

    Private Sub button_server_listen_Click(sender As Object, e As RoutedEventArgs) Handles button_server_listen.Click
        Dim T As Thread = New Thread(Sub()
                                         Server.Listen(Sub(ByVal M As String)
                                                           Log("Server: " & M)
                                                       End Sub)
                                     End Sub)
        T.Start()
    End Sub

End Class

编辑:

我尝试使用 StreamReader/Writers 来完成所有工作。现在我什至没有收到一条消息:

服务器

Imports System.IO
Imports System.Net.Sockets

Public Class Server
    Inherits ConnectionPartner

    Private Server As TcpListener
    Private Client As TcpClient
    Private Reader As StreamReader
    Private Writer As StreamWriter
    Private Port As Integer

    Public Sub Init(ByVal port As Integer)
        Server = New TcpListener(port)
    End Sub

    Public Sub Open()
        Server.Start()
        Client = Server.AcceptTcpClient()
        Dim Stream As NetworkStream = Client.GetStream()
        Reader = New StreamReader(Stream)
        Writer = New StreamWriter(Stream)
    End Sub

    Public Overrides Sub Write(ByVal Message As String)
        Writer.WriteLine(Message)
    End Sub
    Public Overrides Sub Write(ByVal Message() As Byte)
    End Sub

    Public Overrides Sub Listen(ByVal Handler As Action(Of String))
        While True
            Dim Message As String = Reader.ReadLine()
            Handler(Message)
        End While
    End Sub
    Public Overrides Sub Listen(ByRef Handler As Action(Of Byte()))
    End Sub

    Public Sub Close()
        Try
            Client.Close()
        Catch ex As Exception

        End Try
        Try
            Server.Stop()
        Catch ex As Exception

        End Try
    End Sub


End Class

客户

Imports System.IO
Imports System.Net
Imports System.Net.Sockets

Public Class Client
    Inherits ConnectionPartner

    Private Socket As TcpClient
    Private Reader As StreamReader
    Private Writer As StreamWriter
    Private Port As Integer

    Public Sub Init()
        Socket = New TcpClient()
    End Sub

    Public Sub Open(ByVal Ip As IPAddress, ByVal Port As Integer)
        Socket.Connect(Ip, Port)
        Dim Stream As NetworkStream = Socket.GetStream()
        Reader = New StreamReader(Stream)
        Writer = New StreamWriter(Stream)
    End Sub

    Public Overrides Sub Write(ByVal Message As String)
        Writer.WriteLine(Message)
    End Sub
    Public Overrides Sub Write(ByVal Message() As Byte)
    End Sub

    Public Overrides Sub Listen(ByVal Handler As Action(Of String))
        While True
            Dim Message As String = Reader.ReadLine()
            Handler(Message)
        End While
    End Sub
    Public Overrides Sub Listen(ByRef Handler As Action(Of Byte()))
    End Sub

    Public Sub Close()
        Try
            Socket.Close()
        Catch ex As Exception

        End Try
    End Sub


End Class

解决方案:

忘记刷新消息。

服务器

Imports System.IO
Imports System.Net
Imports System.Net.Sockets

Public Class Server
    Inherits ConnectionPartner

    Private Server As TcpListener
    Private Client As TcpClient
    Private Reader As StreamReader
    Private Writer As StreamWriter
    Private Port As Integer

    Public Sub Init(ByVal Ip As IPAddress, ByVal Port As Integer)
        Server = New TcpListener(Ip, Port)
    End Sub

    Public Sub Open()
        Server.Start()
        Client = Server.AcceptTcpClient()
        Dim Stream As NetworkStream = Client.GetStream()
        Reader = New StreamReader(Stream)
        Writer = New StreamWriter(Stream)
        Writer.AutoFlush = True
    End Sub

    Public Overrides Sub Start(ByVal Ip As IPAddress, ByVal Port As Integer)
        Me.Init(Ip, Port)
        Me.Open()
    End Sub

    Public Overrides Sub Write(ByVal Message As String)
        Writer.WriteLine(Message)
    End Sub

    Public Overrides Sub Listen(ByVal Handler As Action(Of String))
        While True
            Dim Message As String = Reader.ReadLine()
            Handler(Message)
        End While
    End Sub

    Public Overrides Sub Close()
        Try
            Client.Close()
        Catch ex As Exception

        End Try
        Try
            Server.Stop()
        Catch ex As Exception

        End Try
    End Sub


End Class

客户

Imports System.IO
Imports System.Net
Imports System.Net.Sockets

Public Class Client
    Inherits ConnectionPartner

    Private Socket As TcpClient
    Private Reader As StreamReader
    Private Writer As StreamWriter
    Private Port As Integer

    Public Sub Init()
        Socket = New TcpClient()
    End Sub

    Public Sub Open(ByVal Ip As IPAddress, ByVal Port As Integer)
        Socket.Connect(Ip, Port)
        Dim Stream As NetworkStream = Socket.GetStream()
        Reader = New StreamReader(Stream)
        Writer = New StreamWriter(Stream)
        Writer.AutoFlush = True
    End Sub

    Public Overrides Sub Start(ByVal Ip As IPAddress, ByVal Port As Integer)
        Me.Init()
        Me.Open(Ip, Port)
    End Sub

    Public Overrides Sub Write(ByVal Message As String)
        Writer.WriteLine(Message)
    End Sub

    Public Overrides Sub Listen(ByVal Handler As Action(Of String))
        While True
            Dim Message As String = Reader.ReadLine()
            Handler(Message)
        End While
    End Sub

    Public Overrides Sub Close()
        Try
            Socket.Close()
        Catch ex As Exception

        End Try
    End Sub


End Class

【问题讨论】:

标签: vb.net tcp stream tcpclient tcplistener


【解决方案1】:

TCP 根本不提供消息。它提供了无边界的字节流。当您Read 时,您可以取回低至 1 的任意字节数。您的代码需要假设任意分块。在这里,您假设每次都获得一个完整的缓冲区。

您可以使用BinaryReader.ReadBytes 读取确切的字节数。 StreamReader/Writer 使基于文本的协议变得更加容易。

ReceiveBufferSize 不是传入的字节数。它的值是没有意义的,别看它。

【讨论】:

  • 尝试了哪个 StreamReader/Writer - 仍然无法正常工作(参见编辑)
  • 该代码要好得多,并且基本上可以工作。发布用于调用这些方法的代码。理想情况下,它是独立的可执行代码。此外,将 VS 设置为在所有异常上中断。
  • 我仍然使用相同的测试类(这是我的问题)
  • 我没看到。那么你点击了什么,会发生什么?
  • 服务器初始化-客户端初始化-服务器打开-客户端打开-服务器监听-客户端监听-服务器写入-服务器客户端;我的听众只打印所有消息,但没有打印任何内容
猜你喜欢
  • 2023-03-16
  • 2013-01-28
  • 2015-05-12
  • 2016-04-15
  • 2017-12-20
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多