Supposons que vous obtenez un flux réseau, vous pouvez faire quelque chose comme le code ci-dessous.
Le sous-registre Main()
obtient un flux réseau et le lit jusqu'à la fin. Il a passé les octets à la classe PlayBuffer
qui ajoute les octets à la fin d'un MemoryStream. Lorsque vous utilisez la méthode Read()
sur le PlayBuffer
, il lit dès le début et conserve un pointeur vers l'endroit où vous avez lu. Le verrouillage est là pour que vous puissiez écrire et lire dans le flux à partir de threads séparés. Je n'ai pas fourni de code qui utilise Read(). C'est juste pour donner une idée. Si vous obtenez des octets continus, vous pouvez alors allouer un grand buffer et une fois à la fin, vous recommencez à écrire au début (buffer circulaire).
[Modifier - le code modifié pour écrire et lire en même temps]
Je n'ai pas complètement testé le code, mais la classe PlayBuffer hérite d'un cours d'eau et doit être capable de lire et écrire en même temps, tant qu'un thread écrit et que l'autre lit juste.
Friend Class PlayProgram
Public Sub Main()
Dim playBuffer As New PlayBuffer
Dim readData As New Thread(Function
Using client As TcpClient = New TcpClient("somehostname", 80)
Using networkStream As NetworkStream = client.GetStream
Dim readBytes As Integer
Dim buffer As Byte() = New Byte(&H1000 - 1) {}
Do While (readBytes = networkStream.Read(buffer, 0, buffer.Length) > 0)
playBuffer.Write(buffer, 0, readBytes)
playBuffer.Flush
Loop
End Using
End Using
End Function)
readData.Start
New SoundPlayer(playBuffer).Play
readData.Join
End Sub
End Class
Friend Class PlayBuffer
Inherits Stream
Public Sub AppendToBuffer(ByVal buffer As Byte(), ByVal bytesRead As Integer)
SyncLock PlayBuffer._lock
Me._buffer.Position = Me._buffer.Length
Me._buffer.Write(buffer, 0, bytesRead)
End SyncLock
End Sub
Public Overrides Sub Flush()
SyncLock PlayBuffer._lock
Me._buffer.Flush
End SyncLock
End Sub
Public Overrides Function Read(ByVal internalBuffer As Byte(), ByVal offset As Integer, ByVal count As Integer) As Integer
SyncLock PlayBuffer._lock
Me._buffer.Position = Me._readPosition
Dim bytesRead As Integer = Me._buffer.Read(internalBuffer, 0, internalBuffer.Length)
Me._readPosition = (Me._readPosition + bytesRead)
Return bytesRead
End SyncLock
End Function
Public Overrides Function Seek(ByVal offset As Long, ByVal origin As SeekOrigin) As Long
Throw New NotImplementedException
End Function
Public Overrides Sub SetLength(ByVal value As Long)
Throw New NotImplementedException
End Sub
Public Overrides Sub Write(ByVal buffer As Byte(), ByVal offset As Integer, ByVal count As Integer)
SyncLock PlayBuffer._lock
Me._buffer.Position = Me._buffer.Length
Me._buffer.Write(buffer, offset, count)
End SyncLock
End Sub
Public Overrides ReadOnly Property CanRead As Boolean
Get
Return True
End Get
End Property
Public Overrides ReadOnly Property CanSeek As Boolean
Get
Throw New NotImplementedException
End Get
End Property
Public Overrides ReadOnly Property CanWrite As Boolean
Get
Return True
End Get
End Property
Public Overrides ReadOnly Property Length As Long
Get
Return Me._buffer.Length
End Get
End Property
Public Overrides Property Position As Long
Get
Return Me._readPosition
End Get
Set(ByVal value As Long)
Throw New NotImplementedException
End Set
End Property
Private ReadOnly _buffer As MemoryStream = New MemoryStream
Private Shared ReadOnly _lock As Object = New Object
Private _readPosition As Long
End Class
Pourriez-vous poster le code qui reçoit les données? S'il arrive dans un flux, lisez-le dans un MemoryStream. Aussi, lisez-vous continuellement ou juste une chanson à la fois? –