"Flush()" Serialized object over a Networkstream using the BinaryFormatter

Please support our VB.NET advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Jan 2008
Posts: 10
Reputation: Ossehaas is an unknown quantity at this point 
Solved Threads: 0
Ossehaas's Avatar
Ossehaas Ossehaas is offline Offline
Newbie Poster

"Flush()" Serialized object over a Networkstream using the BinaryFormatter

 
0
  #1
Feb 22nd, 2009
Hello all,

I'm having a problem with sending a serialized object over a NetworkStream. I'm using the BinaryFormatter and the object is serialized and deserialized fine writing to a file.

If I use a streamwriter to send text it works fine after the Flush()

    nStream = _tcpClient.GetStream()
    Dim sw As StreamWriter = New StreamWriter(nStream)
    sw.Write("Text to sent")
    sw.Flush()

Now when I use the BinaryFormatter the object is serialized to the NetworkStream but the server never gets it

  1. nStream = _tcpClient.GetStream()
  2. Dim bf As New BinaryFormatter()
  3. bf.Serialize(nStream, MyObject)

It look like it's waiting for a flush or something.

I hope someone can help me
Last edited by Ossehaas; Feb 22nd, 2009 at 12:22 pm.
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 63
Reputation: 4advanced is an unknown quantity at this point 
Solved Threads: 10
4advanced 4advanced is offline Offline
Junior Poster in Training

Re: "Flush()" Serialized object over a Networkstream using the BinaryFormatter

 
0
  #2
Feb 23rd, 2009
Ossehaas,

Check the StreamingContext class for additional info.... I think it will help ya out....

According MSDN:

  1. Imports System
  2. Imports System.Text
  3. Imports System.Runtime.Serialization.Formatters.Binary
  4. Imports System.Runtime.Serialization
  5. Imports System.IO
  6. Imports System.Security.Permissions
  7.  
  8.  
  9. Class Program
  10.  
  11. Shared Sub Main(ByVal args() As String)
  12. Try
  13. SerializeAndDeserialize()
  14. Catch exc As System.Exception
  15. Console.WriteLine(exc.Message)
  16. Finally
  17. Console.WriteLine("Press <Enter> to exit....")
  18. Console.ReadLine()
  19. End Try
  20.  
  21. End Sub
  22.  
  23. Shared Sub SerializeAndDeserialize()
  24. Dim myObject As Object = DateTime.Now
  25. ' Create a StreamingContext that includes a
  26. ' a DateTime.
  27. Dim sc As New StreamingContext(StreamingContextStates.CrossProcess, myObject)
  28. Dim bf As New BinaryFormatter(Nothing, sc)
  29. Dim ms As New MemoryStream(New Byte(2047) {})
  30. bf.Serialize(ms, New [MyClass]())
  31. ms.Seek(0, SeekOrigin.Begin)
  32. Dim f As [MyClass] = CType(bf.Deserialize(ms), [MyClass])
  33. Console.WriteLine(vbTab + " MinValue: {0} " + vbLf + vbTab + " MaxValue: {1}", f.MinValue, f.MaxValue)
  34. Console.WriteLine("StreamingContext.State: {0}", sc.State)
  35.  
  36. Dim myDateTime As DateTime = CType(sc.Context, DateTime)
  37. Console.WriteLine("StreamingContext.Context: {0}", myDateTime.ToLongTimeString())
  38.  
  39. End Sub
  40. End Class
  41.  
  42. <Serializable(), SecurityPermission(SecurityAction.Demand, SerializationFormatter := True)> _
  43. Class [MyClass]
  44. Implements ISerializable
  45. Private minValue_value As Integer
  46. Private maxValue_value As Integer
  47.  
  48. Public Sub New()
  49. minValue_value = Integer.MinValue
  50. maxValue_value = Integer.MaxValue
  51. End Sub
  52.  
  53. Public Property MinValue() As Integer
  54. Get
  55. Return minValue_value
  56. End Get
  57. Set
  58. minValue_value = value
  59. End Set
  60. End Property
  61.  
  62. Public Property MaxValue() As Integer
  63. Get
  64. Return maxValue_value
  65. End Get
  66. Set
  67. maxValue_value = value
  68. End Set
  69. End Property
  70.  
  71. Sub GetObjectData(ByVal si As SerializationInfo, ByVal context As StreamingContext) Implements ISerializable.GetObjectData
  72. si.AddValue("minValue", minValue_value)
  73. si.AddValue("maxValue", maxValue_value)
  74.  
  75. End Sub
  76.  
  77. Protected Sub New(ByVal si As SerializationInfo, ByVal context As StreamingContext)
  78. minValue_value = Fix(si.GetValue("minValue", GetType(Integer)))
  79. maxValue_value = Fix(si.GetValue("maxValue", GetType(Integer)))
  80. End Sub
  81. End Class
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 10
Reputation: Ossehaas is an unknown quantity at this point 
Solved Threads: 0
Ossehaas's Avatar
Ossehaas Ossehaas is offline Offline
Newbie Poster

Re: "Flush()" Serialized object over a Networkstream using the BinaryFormatter

 
0
  #3
Feb 25th, 2009
Thanxs for the reply, Im not sure how too use the code you posted, I think it's for testing the Serialization process, but the object is Serialized and deserialized fine when I'm writing it to a file. I have a working example but I have to translate it from C# to VB. I will post it when I'm done.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 10
Reputation: Ossehaas is an unknown quantity at this point 
Solved Threads: 0
Ossehaas's Avatar
Ossehaas Ossehaas is offline Offline
Newbie Poster

Serialized object over a Networkstream using the BinaryFormatter

 
0
  #4
Feb 25th, 2009
Ok, here goes the code, it works and it's also Generic.

First build a class library and add the following classes

  1. Namespace Library
  2. <Serializable()> _
  3. Public Class UserLogin
  4. Private _name As String
  5. Private _password As String
  6.  
  7. Public Sub New(ByVal UserName As String, ByVal Password As String)
  8. _name = UserName
  9. _password = Password
  10. End Sub
  11.  
  12. Public ReadOnly Property UserName() As String
  13. Get
  14. Return _name
  15. End Get
  16. End Property
  17.  
  18. Public ReadOnly Property Password() As String
  19. Get
  20. Return _password
  21. End Get
  22. End Property
  23. End Class
  24.  
  25. Public Delegate Sub DataReceivedDelegate(ByVal sender As Object, ByVal args As DataReceivedEventArgs)
  26.  
  27.  
  28. Public Class DataReceivedEventArgs
  29. Inherits EventArgs
  30.  
  31. Private _data As Object
  32. Public Property Data() As Object
  33. Get
  34. Return _data
  35. End Get
  36. Set(ByVal value As Object)
  37. _data = value
  38. End Set
  39. End Property
  40.  
  41. Public Sub New()
  42.  
  43. End Sub
  44.  
  45. Public Sub New(ByVal Data As Object)
  46. _data = Data
  47. End Sub
  48. End Class
  49.  
  50. Public Class SimpleServer(Of T)
  51. Private _ip As IPAddress
  52. Public ReadOnly Property IP() As IPAddress
  53. Get
  54. Return _ip
  55. End Get
  56. End Property
  57. Private _listener As TcpListener
  58.  
  59. Private _data As IEnumerable(Of T)
  60. Public Property Data() As IEnumerable(Of T)
  61. Get
  62. Return _data
  63. End Get
  64. Set(ByVal value As IEnumerable(Of T))
  65. _data = value
  66. End Set
  67. End Property
  68.  
  69. Private _port As Integer
  70. Public ReadOnly Property Port() As Integer
  71. Get
  72. Return _port
  73. End Get
  74. End Property
  75.  
  76. Public Sub New(ByVal port As Integer, ByVal ip As IPAddress)
  77. _ip = ip
  78. _port = port
  79. _listener = New TcpListener(ip, port)
  80. End Sub
  81.  
  82. Public Sub SendData()
  83. Try
  84. While True
  85. Using client As TcpClient = _listener.AcceptTcpClient()
  86. Using netStream As NetworkStream = client.GetStream()
  87. While True
  88. Using memStream As MemoryStream = New MemoryStream()
  89. For Each item As T In Data
  90. Dim formatter As New BinaryFormatter()
  91. formatter.Serialize(memStream, item)
  92. Dim data() As Byte = memStream.GetBuffer()
  93. Dim length() As Byte = BitConverter.GetBytes(data.Length)
  94. netStream.Write(length, 0, length.Length)
  95. netStream.Write(data, 0, data.Length)
  96. memStream.Position = 0
  97. Next
  98.  
  99. Exit While
  100. End Using
  101. End While
  102. End Using
  103. Exit While
  104. End Using
  105. End While
  106. Catch ex As Exception
  107. Console.WriteLine(ex.Message)
  108. Finally
  109. _listener.Stop()
  110. End Try
  111. End Sub
  112.  
  113. Public Sub Listen()
  114. _listener.Start()
  115. SendData()
  116. End Sub
  117. End Class
  118.  
  119. Public Class SimpleClient(Of T)
  120. Private _port As Integer
  121. Public ReadOnly Property Part() As Integer
  122. Get
  123. Return _port
  124. End Get
  125. End Property
  126.  
  127. Private _ip As IPAddress
  128. Public ReadOnly Property IP() As IPAddress
  129. Get
  130. Return _ip
  131. End Get
  132. End Property
  133.  
  134. Private _serverPort As Integer
  135. Public ReadOnly Property ServerPort() As Integer
  136. Get
  137. Return _serverPort
  138. End Get
  139. End Property
  140.  
  141. Private _serverIP As IPAddress
  142. Public ReadOnly Property ServerIP() As IPAddress
  143. Get
  144. Return _serverIP
  145. End Get
  146. End Property
  147. Private _dataReceivedEvent As DataReceivedDelegate
  148. Public Sub PassDelegate(ByVal del As DataReceivedDelegate)
  149. _dataReceivedEvent = del
  150. End Sub
  151.  
  152. Public Sub New(ByVal port As Integer, ByVal ip As IPAddress, ByVal serverPort As Integer, ByVal severIP As IPAddress)
  153. _port = port
  154. _ip = ip
  155. _serverPort = serverPort
  156. _serverIP = severIP
  157. End Sub
  158.  
  159. Private Sub OnDataReceivedEvent(ByVal args As DataReceivedEventArgs)
  160. If Not _dataReceivedEvent.Equals(Nothing) Then
  161. _dataReceivedEvent(Me, args)
  162. End If
  163. End Sub
  164.  
  165. Private Function ReceiveFixedData(ByVal netStream As NetworkStream, ByVal count As Integer) As Byte()
  166. If (netStream.Equals(Nothing)) Then
  167. Throw New ArgumentNullException("stream")
  168. End If
  169.  
  170. If count <= 0 Then
  171. Throw New ArgumentOutOfRangeException("count", "Parameter's value cannot be 0 or less than 0.")
  172. End If
  173.  
  174. Dim buffer(count) As Byte
  175. Dim receivedCount As Integer
  176. Dim position As Integer = 0
  177.  
  178. ' read until all data is received.
  179. Do While (position < count)
  180. receivedCount = netStream.Read(buffer, position, count - position)
  181. If receivedCount = 0 Then
  182. Return Nothing
  183. End If
  184. position += receivedCount
  185. Loop
  186. Return buffer
  187. End Function
  188.  
  189. Public Sub ConnectServer()
  190. Using client As New TcpClient(New IPEndPoint(_ip, _port))
  191. client.Connect(_serverIP, _serverPort)
  192. Using netStream As NetworkStream = client.GetStream()
  193. While True
  194. ' get the number of bytes to be read in order to retrieve all message
  195. Dim data() As Byte = ReceiveFixedData(netStream, 4)
  196. If data Is Nothing Then
  197. Exit Sub
  198. End If
  199. Dim messageLength As Integer = BitConverter.ToInt32(data, 0)
  200. If messageLength > 0 Then
  201. data = ReceiveFixedData(netStream, messageLength)
  202. If data.Equals(Nothing) Then
  203. Return
  204. End If
  205. Dim formatter As New BinaryFormatter()
  206. Using memStream As MemoryStream = New MemoryStream(data)
  207. Dim message As T = CType(formatter.Deserialize(memStream), T)
  208. OnDataReceivedEvent(New DataReceivedEventArgs(message))
  209. End Using
  210. End If
  211. End While
  212. End Using
  213. End Using
  214. End Sub
  215. End Class
  216. End Namespace

Now build the class library.

Create a Client and a Server application. In both add reference to the DLL you created with the class library. (VS Menu > Project > Add Reference)

Server:
  1. Import yourDLLNamespace.Library
  2.  
  3. Public Class Program
  4.  
  5. Public Sub Main()
  6. Dim data As New List(Of UserLogin)
  7.  
  8. For i As Integer = 0 To 3
  9. Dim ul As New UserLogin("Name " & i.ToString(), "pw" & i.ToString())
  10. data.Add(ul)
  11. Next
  12.  
  13. Dim server As SimpleServer(Of UserLogin) = New SimpleServer(Of UserLogin)(7777, IPAddress.Parse("127.0.0.1"))
  14. server.Data = data
  15.  
  16. Try
  17. server.Listen()
  18.  
  19. Catch ex As Exception
  20. Console.WriteLine(ex.Message())
  21. End Try
  22. End Sub
  23. End Class

Client:

  1. Import yourDLLNamespace.Library
  2.  
  3. Public Class Program
  4.  
  5. Public Sub Main()
  6. Dim client As SimpleClient(Of UserLogin) = New SimpleClient(Of UserLogin)(7778, IPAddress.Parse("127.0.0.1"), 7777, IPAddress.Parse("127.0.0.1"))
  7. client.PassDelegate(AddressOf client_DataReceivedEvent)
  8.  
  9. Try
  10. client.ConnectServer()
  11. Catch ex As Exception
  12. Console.WriteLine(ex.Message())
  13. End Try
  14. End Sub
  15.  
  16. Public Sub client_DataReceivedEvent(ByVal sender As Object, ByVal args As DataReceivedEventArgs)
  17. Dim ul As UserLogin = CType(args.Data, UserLogin)
  18. Console.WriteLine(ul.UserName)
  19. End Sub
  20. End Class

I hope that with this code some other people don't have to spent days searching on the web for a working example like I did.

Thanx for Anton Gochev’s weblog, thats where I translated it from.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Other Threads in the VB.NET Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC