Sending Structure across .net sockets

onepieceking

Well-known member
Joined
Sep 20, 2006
Messages
64
Programming Experience
1-3
Hi,

I wish to send a structure from the client to the server using sockets and the server will also send back a structure to the client upon receiving the client's structure.

I know how to send strings across sockets but i don't know how to do it for structures.

Please advise me on this. Thanks alot in advance.
 
Try declaring your structure as Serializable:

VB.NET:
<Serializable> _
Private Structure bob
    public egg as int32
End Structure

The have a look at the example shown in MSDN on the SerializableAttribute Class section - this shows how to serialize an object down to a Stream using the SoapFormatter class.

This should be adaptable to be allow you to transfer your serialized structure over a socket, to be re-serialized at the other end.

mafro
 
Hi,

From the example,

VB.NET:
' Opens a file and serializes the object into it in binary format.
Dim stream As Stream = File.Open("data.xml", FileMode.Create)
Dim formatter As New SoapFormatter()

What if my data is from some textboxes? As in the user will enter some data into 2 textboxes and I have retrieved the text in the boxes. How do I make them into a stream?

Sorry I am a beginner in VB.NET so please bear with me.

Thanks
 
Have a look at this thread, in second post there is a serialization example, in sixth post I have attached client-server socket example projects that use this technique for transfer.
 
Client-code

VB.NET:
Class TCPCli
 
    <Serializeable()> _
    Structure testing
        Dim var1 as integer
        Dim var2 as integer
    End Structure

    Shared Sub Main()

        Dim tcpClient As New System.Net.Sockets.TcpClient()
        tcpClient.Connect("127.0.0.1", 8000)
        Dim networkStream As NetworkStream = tcpClient.GetStream()
        If networkStream.CanWrite And networkStream.CanRead Then
            ' Do a simple write.
            Dim tst as testing
            tst.var1 = 1
            tst.var2 = 2
   
            Dim formatter as New BinaryFormatter
            formatter.Serialize(networkStream, tst)

            ' Read the NetworkStream.
            formatter = New BinaryFormatter
            Dim returntst as testing
            returntst = Ctype(formatter.Deserialize(networkStream), testing)

            ' Output the data received from the host to the console.
            Console.WriteLine(("Host returned: " + returntst.var1))
        Else
            If Not networkStream.CanRead Then
                Console.WriteLine("cannot not write data to this stream")
                tcpClient.Close()
            Else
                If Not networkStream.CanWrite Then
                    Console.WriteLine("cannot read data from this stream")
                    tcpClient.Close()
                End If
            End If
        End If
        ' pause so user can view the console output
        Console.ReadLine()
    End Sub
End Class

Server-code

VB.NET:
Class TCPSrv
 
    <Serializeable()> _
    Structure testing
        Dim var1 as integer
        Dim var2 as integer
    End Structure  

    Shared Sub Main()
        Const portNumber As Integer = 8000
        Dim tcpListener As New TcpListener(portNumber)
        tcpListener.Start()
        Console.WriteLine("Waiting for connection...")
        Try
            'Accept the pending client connection and return 
            'a TcpClient initialized for communication. 
            Dim tcpClient As TcpClient = tcpListener.AcceptTcpClient()
            Console.WriteLine("Connection accepted.")
            
            ' Get the stream
            Dim formatter as New BinaryFormatter
            Dim client as testing
            client = Ctype(formatter.Deserialize(networkStream), testing)
            ' Return the data received from the client to the console.
            Console.WriteLine(("Client sent: " + client.var1))
            
            Dim response As testing
            response.var1 = 3
            response.var2 = 4

            formatter = New BinaryFormatter
            formatter.Serialize(networkStream, response)
            Console.WriteLine(("Message Sent /> : " + response.var1))
            'Any communication with the remote client using the TcpClient can go here.
            'Close TcpListener and TcpClient.
            tcpClient.Close()
            tcpListener.Stop()
            Console.WriteLine("exit")
            Console.ReadLine()
        Catch e As Exception
            Console.WriteLine(e.ToString())
            Console.ReadLine()
        End Try
    End Sub
   End Class

It doesn't work. Please help me with this
 
Your code does work with a few minor error corrections. I haven't got VB2003 .Net 1.1 here but have attached the VB2005 .Net 2.0 project. (you can get the free VB2005 Express or just read out the corrected code from the projects.) Listed are the corrections done (as adviced by the VS debugger errors):
- added imports (you probably didn't paste that here).
- fixed spelling error attribute 'serializeable' to correct 'serializable'.
- put the structure in a common class library (I told you so in the post I referred to, you have to do this when seralizing between different assemblies.).
- a few casting errors fixed .ToString.
- fixed networkStream not defined in server.

The attachment contains single solution with both console projects and the class library, solution configured for multiple startup projects when debugging.
 

Attachments

  • vbnet20-ConsoleSockets.zip
    36.1 KB · Views: 72
Hi John,

Thanks for your reply and help. It is working now. I have another question. My code now is synchronous transfer. I need to make the transfer to asynchronous. How do i do it?

PS. I haven't studied your previous code.
 
Back
Top