943,860 Members | Top Members by Rank

Ad:
  • VB.NET Discussion Thread
  • Marked Solved
  • Views: 2208
  • VB.NET RSS
Feb 22nd, 2009
0

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

Expand Post »
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

VB.NET Syntax (Toggle Plain Text)
  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.
Reputation Points: 10
Solved Threads: 1
Light Poster
Ossehaas is offline Offline
32 posts
since Jan 2008
Feb 23rd, 2009
0

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

Ossehaas,

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

According MSDN:

VB.NET Syntax (Toggle Plain Text)
  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
Reputation Points: 33
Solved Threads: 10
Junior Poster in Training
4advanced is offline Offline
67 posts
since Nov 2008
Feb 25th, 2009
0

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

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.
Reputation Points: 10
Solved Threads: 1
Light Poster
Ossehaas is offline Offline
32 posts
since Jan 2008
Feb 25th, 2009
0

Serialized object over a Networkstream using the BinaryFormatter

Ok, here goes the code, it works and it's also Generic.

First build a class library and add the following classes

VB.NET Syntax (Toggle Plain Text)
  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:
VB.NET Syntax (Toggle Plain Text)
  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:

VB.NET Syntax (Toggle Plain Text)
  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.
Reputation Points: 10
Solved Threads: 1
Light Poster
Ossehaas is offline Offline
32 posts
since Jan 2008

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in VB.NET Forum Timeline: Add new XML file
Next Thread in VB.NET Forum Timeline: DataGridView and combobox





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC