Sending images using a NetworkStream

ozonic

Member
Joined
Jun 17, 2006
Messages
21
Programming Experience
Beginner
I am new to VB.NET and I have a bit of a problem. I've got a Client/Server program using the TcpClient and TcpListener. I am able to send strings from the Client to the Server using a NetworkStream and converting the strings from text to bytes using the following instructions:

'Convert string to bytes
Dim Buffer As [Byte]() = System.Text.Encoding.ASCII.GetBytes("String to send")

'Send contents of buffer (bytes)
NetworkStream.Write(Buffer, 0, Buffer.Length)

My question is: How can I possibly send an image from the client (TcpClient) to the server (TcpListener)? Would I have to convert the image into bytes in the same way as I've done with the strings, and if so how do I do that? If that's not possible, do you have any other suggestions?

I would greately appreciate any ideas.
 
Ahh, Interesting

So much for all that headbanging against the keyboard. LoL. Back to the original drawing board. I am sure I will come up with another question or two before its all over with. Thanks for the input!!
 
So about that Binary Reader Writer Stuff

Aight,

So now I am back to the problem that I had at post 19. I know what you are saying, but the problem is I don't know how to completely implement it.
I get the top half inch and about full inch quarter of the next line from the top left of the screen. :confused: How exactly do I implement the Binary Reader-Writer here so that the server knows how much to recieve?:confused: Thanks for your input in advance!!

Client Side
VB.NET:
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] netSendScreenshot [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] NetworkStream = tcp.GetStream[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] mem [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IO.MemoryStream[/SIZE]
[SIZE=2]Image.FromHbitmap([/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IntPtr(hBMP)).Save(mem, System.Drawing.Imaging.ImageFormat.Jpeg)[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] buffer [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Byte[/COLOR][/SIZE][SIZE=2]() = mem.GetBuffer[/SIZE]
[SIZE=2]netSendScreenshot.Write(buffer, 0, buffer.Length)[/SIZE]
[SIZE=2]DeleteObject(hBMP)[/SIZE]

Server Side
VB.NET:
[SIZE=2][SIZE=2][COLOR=#0000ff]While[/COLOR][/SIZE][SIZE=2] StopServer = [/SIZE][SIZE=2][COLOR=#0000ff]False[/COLOR][/SIZE]
[SIZE=2]l.Start()[/SIZE]
[SIZE=2]System.Windows.Forms.Application.DoEvents()[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] tcp [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] TcpClient = l.AcceptTcpClient[/SIZE]
[SIZE=2]System.Windows.Forms.Application.DoEvents()[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] netRecieveScreenshot [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] NetworkStream = tcp.GetStream[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] Buffer(tcp.ReceiveBufferSize) [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Byte[/COLOR][/SIZE]
[SIZE=2]netRecieveScreenshot.Read(Buffer, 0, Buffer.Length)[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] mem [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IO.MemoryStream[/SIZE]
[SIZE=2]mem.Write(Buffer, 0, Buffer.Length)[/SIZE]
[SIZE=2]PictureBox1.Image = Image.FromStream(mem)[/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]While[/COLOR][/SIZE]
[/SIZE]

THANKS!!
 
You didn't write the byte count first so the receiver doesn't know how many bytes to read to get a complete image.
 
Byte Count?

Thats the part that i am not sure of. I don't know how to really get the byte count to begin with, then I don't know how to send the byte count or recieve the byte count. Sorry first time I am working with TCP. Just a newbie learning, but you gotta start learning new things somewhere.
 
You wanted to write buffer.Length number of bytes so that is your number. This Length property is type Integer (32bits), so you use the methods BinaryWriter.Write and BinaryReader.ReadInt32 to transfer it.
 
BinaryWriter & Reader with a Network Stream

John,

Am I on the right track for the client side? Not sure if this is what you were talking about or not.

VB.NET:
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] netSendScreenshot [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] NetworkStream = tcp.GetStream[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] mem [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IO.MemoryStream[/SIZE]
[SIZE=2]Image.FromHbitmap([/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IntPtr(hBMP)).Save(mem, System.Drawing.Imaging.ImageFormat.Jpeg)[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] buffer [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Byte[/COLOR][/SIZE][SIZE=2]() = mem.GetBuffer[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] bw [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IO.BinaryWriter(tcp.GetStream)[/SIZE]
[SIZE=2]bw.Write(buffer, 0, buffer.Length)[/SIZE]
[SIZE=2]DeleteObject(hBMP)[/SIZE]

Thanks!
 
You didn't write the byte count first so the receiver doesn't know how many bytes to read to get a complete image. You wanted to write buffer.Length number of bytes so that is your number. This Length property is type Integer (32bits), so you use the methods BinaryWriter.Write and BinaryReader.ReadInt32 to transfer it. buffer.Length is the number of bytes you are about to send, you have send this number first so the receiver know how many of the bytes in the stream to follow the comprise the full image. So you send bw.Write(buffer.Length) before you send the actual bytes that is the image.

Also instead of mem.GetBuffer use mem.ToArray because the buffer may be many more (empty/0) bytes than the actual image since this is how the memorystream works with a dynamic increasing capasity. The ToArray only returns the used bytes it contains.
 
Binary Reader-Writer - Network Stream

John,

That second post I believe cleared up the client side for me. Just making sure that this is what you were talking about before venturing off to the server side.

VB.NET:
[SIZE=2]
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] netSendScreenshot [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] NetworkStream = tcp.GetStream
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] mem [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IO.MemoryStream
Image.FromHbitmap([/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IntPtr(hBMP)).Save(mem, System.Drawing.Imaging.ImageFormat.Jpeg)
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] buffer [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Byte[/COLOR][/SIZE][SIZE=2]() = mem.ToArray
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] bw [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IO.BinaryWriter(tcp.GetStream)
bw.Write(buffer.Length)
bw.Write(buffer, 0, buffer.Length)
DeleteObject(hBMP)
[/SIZE]

If thats correct, how would I catch the size on the server size, and then how would I use that size to catch the whole image.

Thanks!
 
Last edited:
With the 'br' BinaryReader:
VB.NET:
Dim img As Image = Image.FromStream(New IO.MemoryStream(br.ReadBytes(br.ReadInt32)))
 
Good, it takes some time to explain, while a code sample is useful it often also help to talk some about around the issue, understanding what needs to be done and how to do it is necessary to write the code. Socket programming also spans a lot of general base topics like threading and working with different streams and the byte representation of various data - and the knowledge required to combine all that is more than one would initally think.
 
Thanks!

Yeah I see all that coming together now. I am now going to try to hyperthread the capture screen process, because I believe that is now my hold back of the chopiness. It updates like 2 or 3 times a second, i was hoping that hyperthreading a few instances of the capture process might speed up the refresh rate.
 
Sending Multiple Images/Items at the Same Time?

I was wondering is there any way to send multiple items at once. I don't mean send them in succession, but actually send them simultaneously. Such as if I had a large image transferring, and wanted to send a small image, both would send at the same time, but the smaller one would complete first. It would not start first, but only complete first because it is smaller. Same thing if I was trying to send a large image, but also try to send text at the same time. The image would continue sending as I sent text.

I guess my main question is it possible to send multiple things simultaneously over a single network stream? Or is it possible to have multiple network streams in single TCP connection? Or do I have to run multiple TCP connections on separate ports.

Any input would be greatly appreciated!
 
The network stream is a wrapper for the socket connection, so they are the same thing. You can't send different data through the same connection at the same time, but you can make multiple connections from the same client to the same server at same port. Using multithreading on both sides this enables you to do what you ask, sending different things asynchronous at the same time from same client to same server.
 
Sending Multiple Images/Items at the Same Time?

So must I use both the asychronous client and multithreading, or are they one in the same. I used part of your simple asychronous example from post #15 and I can send an image file and send text seperately, but if I try to send both text and the image at the same time, neither gets successfully passed to the server. Would some code help?

Thanks
 
Back
Top