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.
 
Worked for me.

Hi JohnH and ozonic
Thank you so much ozonic for your reply...
Many Thanks JohnH for the Sample Solutions you posted...they are very usefull..
i installed VS2005 on my machine and tried them...and they worked successfully... now i am able to send files multiple and Asynchronously.
thank you again.
shelal



 
Can't Completely Load Images

I have the following code on my client side. After few days of fiddling with it, I came across this thread. It was then that I figured out that you could not store the image as a Bitmap, you had to store it as a jpeg before doing anything with it. The Bitmap just wouldn't be recognized when it came to image.fromstream part on the server side.:confused:

Anyways, here is the simplified code of what I have on the client side:

VB.NET:
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] DesktopImage [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.IO.MemoryStream = [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] System.IO.MemoryStream()[/SIZE]
[SIZE=2]Image.FromHbitmap([/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IntPtr(hBMP)).Save(DesktopImage, System.Drawing.Imaging.ImageFormat.Jpeg)[/SIZE]
[SIZE=2]networkStream.Write(DesktopImage.ToArray, 0, DesktopImage.Length)[/SIZE]

However, on the server side, it only loads partially. When using this simplified code:

VB.NET:
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] networkStream [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] NetworkStream = tcpClient.GetStream()[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] bytes(tcpClient.ReceiveBufferSize) [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Byte[/COLOR][/SIZE]
[SIZE=2]networkStream.Read(bytes, 0, bytes.Length)[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] memoryStream [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] System.IO.MemoryStream[/SIZE]
[SIZE=2]memoryStream.Write(bytes, 0, bytes.Length)[/SIZE]
[SIZE=2]PictureBox2.Image = Image.FromStream(memoryStream)[/SIZE]

How do you add the header/info to send before the file, and also how do you on the flip side recieve that info and use it to recieve the entire image as it was sent.

Any help on this would be greaty appreciated. :)
 
Last I tested Image.Save(networkstream, imageformat) worked for sending, and Image.FromStream(networkstream) worked for receiving.

What do you mean 'header'? If you mean sending filename stirng for example first then I found using the BinaryWriter/BinaryReader was convenient.
 
Loading Images from NetworkStream

Yeah that works. Thanks for the quick reply as well.

Sorry, I guess I didn't word my questions specifically enough.

The problem now is that the image that I receive is messed up most of the time; like only the top half will come through or it will be faded in different colors (pink, blue, purple etc.).

Like the server side does not completely recieve the image.

Just from reading the thread, I was under the impression of having to send the size of the image first from the client, and then on the server recieve the size of the image and use that to know when the entire image has been recieved.

Problem is i don't know how exactly to put this into code. I saw the example you posted, but it loses me with the Asyn and the packets going on. I just want to take the image directly from the network stream, send it to a memory stream and then display it.

What i am trying to do is simply send a screen shot from the client and display it on the server which I made into a form with a picturebox before implementing what I have in mind any further.
 
Ok, here is the easiest client-server ever, just start up the solution and both projects will run. Client have a button where you get dialog to choose an image file, it is streamed to server which displays both the filename and image on form. Tested with much different image formats and sizes, no problems seen here. There is only 10 lines of code in each project, none is commented.
 

Attachments

  • vbnet20-ImageStreamSet.zip
    24 KB · Views: 66
Thanks!

THANK YOU JOHN! I manipulate the code a little for the client to capture a screenshot and transfer it from the client to the server.

Works great! THANKS:) :D :p
icon14.gif
 
hi guys

im just curious, i would like to have an updater program for the application i am creating, could this sort of thing be applied to get an updated executable or something?

cheers
adam
 
Yes, but you would usually do it much easier with for example load Xml document from web server to check versions and paths and WebClient.Download... to load the file. ClickOnce deployment also includes this feature.
 
cheers for the response johnh

i havent really explored the ClickOnce deployment thing, but i am under the impression that it pretty much takes care of EVERYTHING for you... personally, i would much rather have complete control over what is happening rather than trusting some other thing to do it itself.

i will bookmark this thread for when i start the updater.

cheers mate, much appreciated
adam
 
Any Way to Send a Stream of Images Without Closing TCP Stream?

I was wondering if there was a smoother way of sending a stream of images from the client to the server. I believe that I am getting a little bit of chopiness because the stream closes and the tcp connection has to be completely reestablished all over again.:( Is there anyway to succesfully send the image and keep the stream open at the same time? I was hoping that this would smooth things about a bit. Or must the stream be closed in order to send the image? If you need more clarificatoin, let me know. Thanks
 
No, you can keep the stream open. As for "smoother" I don't understand you, is there a smoother way than one line of code? (image.save(stream))
 
Streaming Images Without Closing Stream?

John,

I tried that, however, the program just does nothing when I run it.

I stepped through it step by step and it gets hung up at:

"PictureBox1.Image = Image.FromStream(tcp.GetStream)" on the server side. :(

Here is bits of my code that pertain to the problem area.


Client Side Code
VB.NET:
[SIZE=2]ThisImage.Save(tcp.GetStream, System.Drawing.Imaging.ImageFormat.Jpeg)[/SIZE]

Server Side Code
VB.NET:
[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][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] tcp [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] TcpClient = l.AcceptTcpClient[/SIZE]
[SIZE=2]PictureBox1.Image = Image.FromStream(tcp.GetStream)[/SIZE]
[SIZE=2]System.Windows.Forms.Application.DoEvents()[/SIZE]
 
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]While[/COLOR][/SIZE]

Any ideas? Thanks
 
The code looks much like the project I posted, which works fine. Did you try it? (post 20)
 
Can't Stream Images Without Closing Stream?

John,

It is pretty much your post. But you had the binary writer thing going on with your project. Your code works fine, but in order for me to make it work I need to put a loop that closes the stream and makes it reestablish the tcp connection. I am trying to capture live screen shots from the client and send them to the server.

Thanks
 
I see the problem now, just tried it. I was sure I had working sending multiple images in succession before, but now it doesn't, so I think you're back to post 2 using the MemoryStream to get the bytes off the image in memory and writing those bytes to the stream, use the binarywriter-reader to send the byte count, in order for receiver to know how many bytes each image is. If you pick up the webcam images from file dumps you don't use the MemoryStream but instead the FileStream.
 
Back
Top