Help me...
I want to sent picture with socket programming, from client to server.

client : get picture from OpenFileDialog, after get the picture , I send it to server.

server : after get the picture from client, the picture is saved in a destination folder.

I try my best, but all I can send is only 8kb picture.
if the picture larger than 8 kb, then at destination folder, only 8kb will be saved, and rest of the saved picture are blank...

here my current code:

Client :

Dim fileStream As FileStream = File.Open([filename], FileMode.Open, FileAccess.Read, FileShare.Read)
        Dim reader As BinaryReader = New BinaryReader(fileStream)
        Dim fileLength As Long = fileStream.Length
        Dim sendBytes(fileLength) As Byte
       
        reader.Read(sendBytes, 0, fileLength)       
        serverStream.Write(sendBytes, 0, fileLength)
fileStream.Close()
reader.Close()

Server:

Dim bgStream As NetworkStream = clientSocket.GetStream()
Dim bgbytes(100024) As Byte
bgStream.Read(bgbytes, 0, CInt(clientSocket.ReceiveBufferSize))
         
Dim gmb As New FileStream([filename], FileMode.Create, FileAccess.Write, FileShare.Write)
Dim fileLength As Long = bgbytes.Length
Dim writer As BinaryWriter = New BinaryWriter(gmb)
writer.Write(bgbytes)       
     
writer.Close()
gmb.Close()

thanks before...

Recommended Answers

All 10 Replies

You should read data from the socket in "chunks". Here's a snippet from asynchronous socket data transfer

Private PACKET_SIZE As UInt16 = 4096
.
.
SyncLock Client.GetStream
  Reader = New BinaryReader(Client.GetStream)
  'next we expect a pass-through byte
  Client.GetStream.Read(ReadByte, 0, 1)
  PassThroughByte = ReadByte(0)
  'next expect length of data (Int32)
  NData = Reader.ReadInt32
  LenData = NData
  'now comes the data, save it in a memory stream
  MStream = New MemoryStream
  While NData > 0
    RaiseEvent TransferProgress(Me, PassThroughByte, CSng(1.0 - NData / LenData))
    LData = Me.Client.GetStream.Read(ReadBuffer, 0, PACKET_SIZE)
    MStream.Write(ReadBuffer, 0, LData)
    NData -= LData
  End While
  'Continue the asynchronous read from the NetworkStream
  Me.Client.GetStream.BeginRead(ReadByte, 0, 1, AddressOf ReceiveOneByte, Nothing)
End SyncLock

and I suppose you are able to grab the idea i.e. how the chunks are read from the socket in the while loop.

Use BB code tags to present your source code.

Read this article.

You should read data from the socket in "chunks". Here's a snippet from asynchronous socket data transfer

Private PACKET_SIZE As UInt16 = 4096
.
.
SyncLock Client.GetStream
  Reader = New BinaryReader(Client.GetStream)
  'next we expect a pass-through byte
  Client.GetStream.Read(ReadByte, 0, 1)
  PassThroughByte = ReadByte(0)
  'next expect length of data (Int32)
  NData = Reader.ReadInt32
  LenData = NData
  'now comes the data, save it in a memory stream
  MStream = New MemoryStream
  While NData > 0
    RaiseEvent TransferProgress(Me, PassThroughByte, CSng(1.0 - NData / LenData))
    LData = Me.Client.GetStream.Read(ReadBuffer, 0, PACKET_SIZE)
    MStream.Write(ReadBuffer, 0, LData)
    NData -= LData
  End While
  'Continue the asynchronous read from the NetworkStream
  Me.Client.GetStream.BeginRead(ReadByte, 0, 1, AddressOf ReceiveOneByte, Nothing)
End SyncLock

and I suppose you are able to grab the idea i.e. how the chunks are read from the socket in the while loop.

this code, where should I put it ?? in the server part to recieve data ?? if so, then it means I send the picture from client without divide the data in to litte piece ??

correct me if I wrong... :p

what class should I use for NData, LenData, and LData ?

thanks..

Sorry for so unclear answer.

Here's the code with proper type definitions. And this code is receiving i.e. your server side code

Private PACKET_SIZE As UInt16 = 4096
.
.
Dim Reader As BinaryReader
Dim ReadBuffer(PACKET_SIZE - 1) As Byte
Dim NData As Int32
Dim MStream As MemoryStream
Dim LData As Int32

Reader = New BinaryReader(Client.GetStream)
' Read Length of data (Int32)
NData = Reader.ReadInt32
' Now comes the data, save it in a memory stream
MStream = New MemoryStream
While NData > 0
  LData = Me.Client.GetStream.Read(ReadBuffer, 0, PACKET_SIZE)
  MStream.Write(ReadBuffer, 0, LData)
  NData -= LData
End While

And your client side code changes a bit

Dim fileStream As FileStream = File.Open([filename], FileMode.Open, FileAccess.Read, FileShare.Read)
Dim reader As BinaryReader = New BinaryReader(fileStream)
Dim fileLength As Int32 = CInt(fileStream.Length)
Dim sendBytes(fileLength - 1) As Byte

reader.Read(sendBytes, 0, fileLength)
' Send length first
serverStream.WriteInt32(fileLength)
' Now, send the data
serverStream.Write(sendBytes, 0, fileLength)

since you have to send the length of the data first.

Dim fileStream As FileStream = File.Open(backg, FileMode.Open, FileAccess.Read, FileShare.Read)
        Dim reader As BinaryReader = New BinaryReader(fileStream)
        Dim fileLength As Int32 = CInt(fileStream.Length)
        Dim sendBytes(fileLength - 1) As Byte

        reader.Read(sendBytes, 0, fileLength)
        ' Send length first
        serverStream.WriteInt32(fileLength)
        ' Now, send the data
        serverStream.Write(sendBytes, 0, fileLength)

at the client side, there is some error (the red one).
it's say that:
'WriteInt32' is not a member of 'System.Net.Sockets.NetworkStream'.

btw, i'm Using vb 2005. sorry not to tell U before.

btw, i'm Using vb 2005. sorry not to tell U before.

I was assuming VB.2005.

at the client side, there is some error (the red one).

Oops!

Here's the modified client code. You can't send the whole file at once. You have to also send data in "chunks" (like you noticed in one of your messages). This is basically same code as yours. Instead of "serverStream" I've used a binary writer ("Writer") which writes to socket's data stream i.e. System.Net.Sockets.NetworkStream. You had declared serverStream As System.Net.Sockets.NetworkStream I guess

Private PACKET_SIZE As UInt16 = 4096
.
.
Dim ByteArray() As Byte ' Data buffer
Dim Fs As FileStream = New FileStream(FilePath, FileMode.Open, FileAccess.Read)
Dim Reader As New BinaryReader(Fs)

Try
  Dim Writer As New BinaryWriter(Me.Client.GetStream) ' Get socket's stream
  'send size of file
  Writer.Write(CInt(Fs.Length))
  'Send the file data
  Do
    'read data from file
    ByteArray = Reader.ReadBytes(PACKET_SIZE)
    'write data to Network Stream
    Writer.Write(ByteArray)
  Loop While ByteArray.Length = PACKET_SIZE
  'make sure all data is sent
  Writer.Flush()
  Writer.Close()
  Reader.Close()
Catch ex As Exception
  ' Handle errors
End Try

The advantage of using binary writer is that you have more overloaded Write methods. Actually the code needs only Write(value As Integer) method not found in NetworkStream class to send the length of the data.

First of all, I want to say thank you very much.
the code U gave me... IT WORKS !!!!

allow me to ask another question:
if I want to send an animated GIF format picture, how do I save the picture in deatination folder?
I already using "System.Drawing.Imaging.ImageFormat.gif", but the GIF picture no longer animated, it become like JPEG format.
another help please...
:D

Hi! Nice to hear that you got answer to your problem. Could you please mark the thread as solved. Thank you!

allow me to ask another question:

Not related to sockets. Please, start a new thread for a new question.

That's not to say, I wouldn't answer the question. I would gladly help with that other question too. It's just that people do look for these Questions&Answers with DaniWeb's search or some other way. And if somebody looks for help in question "if I want to send an animated GIF format picture, how do I save the picture in deatination folder?", they hardly look for it in a thread with title "[socket programming]..." :) That's the reason why you should always start a new thread :)

This solution work on visual studio 2012. Really appreciate.

(1) Server code:
Note: I use Timer to start the Thread.

 Dim Client As New TcpClient
 Dim Listener As New TcpListener(9999)
 Private PACKET_SIZE As UInt16 = 4096

 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Listener.Start()

        Timer1.Enabled = True
 End Sub

 Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

    Client = Listener.AcceptTcpClient()

    Dim Reader As BinaryReader
    Dim ReadBuffer(PACKET_SIZE - 1) As Byte
    Dim NData As Int32
    Dim MStream As MemoryStream
    Dim LData As Int32

    Reader = New BinaryReader(Client.GetStream)
    ' Read Length of data (Int32)
    NData = Reader.ReadInt32
    ' Now comes the data, save it in a memory stream
    MStream = New MemoryStream
    While NData > 0
        LData = Client.GetStream.Read(ReadBuffer, 0, PACKET_SIZE)
        MStream.Write(ReadBuffer, 0, LData)
        NData -= LData
    End While

    Timer1.Enabled = False

    Form2.PictureBox1.Image = Image.FromStream(MStream)
    Form2.ShowDialog()

End Sub

(2) Client code:

    Dim imgPath As String = "C:/image.jpg"

    Dim Client As New TcpClient(serverip, 9999)
    Dim ByteArray() As Byte ' Data buffer
    Dim Fs As FileStream = New FileStream(imgPath, FileMode.Open, FileAccess.Read)
    Dim Reader As New BinaryReader(Fs)

    Try
        Dim Writer As New BinaryWriter(Client.GetStream) ' Get socket's stream
        'send size of file
        Writer.Write(CInt(Fs.Length))
        'Send the file data
        Do
            'read data from file
            ByteArray = Reader.ReadBytes(PACKET_SIZE)
            'write data to Network Stream
            Writer.Write(ByteArray)
        Loop While ByteArray.Length = PACKET_SIZE
        'make sure all data is sent
        Writer.Flush()
        Writer.Close()
        Reader.Close()
    Catch ex As Exception
        MessageBox.Show(ex.ToString)
    End Try

 End Sub
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.