?
Solved

Reading Binary data from a socket connection

Posted on 2003-12-10
11
Medium Priority
?
846 Views
Last Modified: 2008-02-01
I have an application that firstly reads a file into a BinaryReader. That BinaryReader then transmits this over a socket as follows:

Dim socket As New tcpClient()
Dim socketWriter As New IO.StreamWriter(socket.GetStream)
Dim diskFile As FileStream
Dim fileToSend As BinaryReader
Dim iCounter as Integer

        diskFile = New FileStream(fileName, FileMode.Open, FileAccess.Read)
        fileToSend = New BinaryReader(diskFile)

        For iCounter = 1 To System.Convert.ToInt32(diskFile.Length)
                Dim tmpByte As Byte = fileToSend.ReadByte
                socketWriter.Write(tmpByte)
                Console.WriteLine(tmpByte)
        Next iCounter

        socketWriter.Flush()


This works (to the best of my knowledge) fine. Issue I have is how the hell do I read the reverse. I have the following code that I filtched from somewhere but it doesnt work, I always get a file that is 32k which is the size of the obj_SocketState.Buffer byte array (Public Buffer(32767) As Byte):

' CallBack Procedure to accept incoming data from a connected Socket.
    Private Sub onDataArrival(ByVal ar As IAsyncResult)

        Try
            Dim writer As New BinaryWriter(File.Create("C:\test.zip"))
            Dim obj_SocketState As StateObject = CType(ar.AsyncState, StateObject)
            Dim obj_Socket As System.Net.Sockets.Socket = obj_SocketState.WorkSocket
            Dim BytesRead As Integer = obj_Socket.EndReceive(ar)

            If BytesRead > 0 Then
                writer.Write(obj_SocketState.Buffer)
            End If
        Catch e As System.Exception
            Console.WriteLine(e.ToString)
        End Try

    End Sub

Looking forward to any reply...just about :-)

Andrew
0
Comment
Question by:andrewharris
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
11 Comments
 
LVL 18

Assisted Solution

by:testn
testn earned 1000 total points
ID: 9911691
Try

   Dim writer As New BinaryWriter(File.Create("C:\test.zip"))


   Private Sub onDataArrival(ByVal ar As IAsyncResult)

        Try
            Dim obj_SocketState As StateObject = CType(ar.AsyncState, StateObject)
            Dim obj_Socket As System.Net.Sockets.Socket = obj_SocketState.WorkSocket
            Dim BytesRead As Integer = obj_Socket.EndReceive(ar)

            If BytesRead > 0 Then
                writer.Write(obj_SocketState.Buffer)
            Else
                writer.Close()
            End If
        Catch e As System.Exception
            Console.WriteLine(e.ToString)
        End Try

    End Sub

and you have to change your code so that it will check the number of bytes returned from EndReceive. If it is greater then zero, you have to start another BeginReceive
0
 
LVL 4

Expert Comment

by:krznpsk
ID: 9913181
You need to close the socketwriter in the server app, as well as flush it.
0
 
LVL 4

Author Comment

by:andrewharris
ID: 9915506
testn,

I have uped the points to 500, could you explain your last line, that is that part I am looking for.

krznpsk,

At what point should you flush it? Just before close? Before/After each receive?

Regards

Andrew
0
Amazon Web Services EC2 Cheat Sheet

AWS EC2 is a core part of AWS’s cloud platform, allowing users to spin up virtual machines for a variety of tasks; however, EC2’s offerings can be overwhelming. Learn the basics with our new AWS cheat sheet – this time on EC2!

 
LVL 4

Author Comment

by:andrewharris
ID: 9915741
Ohh....Hang on, you mean do something like this:



Private Sub onDataArrival(ByVal ar As IAsyncResult)

        Try
            Dim obj_SocketState As StateObject = CType(ar.AsyncState, StateObject)
            Dim obj_Socket As System.Net.Sockets.Socket = obj_SocketState.WorkSocket
            Dim BytesRead As Integer = obj_Socket.EndReceive(ar)

            If BytesRead > 0 Then
                writer.Write(obj_SocketState.Buffer)
                obj_Socket.BeginReceive(obj_SocketState.Buffer, 0, obj_SocketState.BufferSize, 0, New AsyncCallback(AddressOf onDataArrival), obj_SocketState)
            Else
                writer.Close()
            End If
        Catch e As System.Exception
            Console.WriteLine(e.ToString)
        End Try

    End Sub

OK, I got that, but I still have this issue of a byte array that is my buffer which is 32767 bytes. If I only receive 32600 bytes I still get a file that is 32767 (32k).

Regards

Andrew
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 9916154
With the BinaryWriter, you can specify how many bytes to write to the file:

writer.Write(obj_SocketState.Buffer, 0, BytesRead)
0
 
LVL 4

Author Comment

by:andrewharris
ID: 9916739
OK, but.... I have a buffer of 32767 bytes. If I only receive (and am only ever going to receive) 32600 bytes, thebuffer is still 32767 bytes. How do I know that I should only write 32600 bytes?

Regards

Andrew
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 1000 total points
ID: 9919919
When you receive 32600 bytes, what is the value of BytesRead?
0
 
LVL 4

Author Comment

by:andrewharris
ID: 9926343
Dah!! I am such a moron...

OK I have managed to get it working as a proof of concept doing this at the client:

Dim socket As New tcpClient()
Dim socketWriter As New IO.StreamWriter(socket.GetStream)
Dim diskFile As FileStream
Dim fileToSend As BinaryReader
Dim iCounter as Integer

        diskFile = New FileStream(fileName, FileMode.Open, FileAccess.Read)
        fileToSend = New BinaryReader(diskFile)

        socketWriter.Write(fileToSend.ReadBytes(System.Convert.ToInt32(diskFile.Length)))
        socketWriter.Flush()

Then this on the server:

Private Sub onDataArrival(ByVal ar As IAsyncResult)

Private bytesReceived as Integer

        Try
            Dim obj_SocketState As StateObject = CType(ar.AsyncState, StateObject)
            Dim obj_Socket As System.Net.Sockets.Socket = obj_SocketState.WorkSocket
            Dim BytesRead As Integer = obj_Socket.EndReceive(ar)
            bytesReceived = bytesReceived + BytesRead

            ' The file I am sending is 931 bytes so this works only when the file is this size.
            If bytesReceived < 931 Then
                obj_Socket.BeginReceive(obj_SocketState.Buffer, 0, obj_SocketState.BufferSize, 0, New AsyncCallback(AddressOf onDataArrival), obj_SocketState)
            Else
                writer.Write(obj_SocketState.Buffer, 0, bytesReceived)
                writer.Flush()
                writer.Close()
                obj_Socket.BeginReceive(obj_SocketState.Buffer, 0, obj_SocketState.BufferSize, 0, New AsyncCallback(AddressOf onDataArrival), obj_SocketState)
            End If
        Catch e As System.Exception
            Console.WriteLine(e.ToString)
        End Try


Now the few issues I have are:

1. Figuring the size of the file without sending it
2. writer.Close() doesnt close the file off. I have to exit the application.

If you can answer those then I am done. If not, no biggy I will just post another question. Either way I am going to split the points between testn and TheLearnedOne

Regards

Andrew
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 9927890
I only see writer.Close when bytesReceived < 931 .  You should probably add a Finally within the Try...Catch to close the Writer.

If the file is written to disk:  
      Dim file As System.IO.FileInfo = New System.IO.FileInfo("<path>")
      dim length As Integer file.Length()

0
 
LVL 4

Author Comment

by:andrewharris
ID: 9936695
TheLearnedOne,

In my example, the file I am sending is always 931 and the statement gets executed, but the files is inaccessible until I stop the debug session.

Regards

Andrew
0
 
LVL 4

Author Comment

by:andrewharris
ID: 9940265
OK Ignore my last stuff. really just irrelevant tothis question.

Split and away we go.

Thanks again.

Andrew
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary Displaying images in RichTextBox is a common requirement with limited solutions available. Pasting through clipboard or embedding into RTF content only support static images.  This article describes how to insert Windows control objects int…
In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question