Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I transfer a BMP or JPG using Winsock?

Status
Not open for further replies.

tedsmith

Programmer
Nov 23, 2000
1,762
AU
I am trying to send a snapshot of a 1 meg bitmap from my video camera between computers using TCPIP.(it comes from a picturebox, not a file)
I tried the excellent example by STRONGM (2003) using propertybag but it only transfers pictures less than 8192 bytes each.
I tried various methods such as breaking the array into hundreds of 8000 byte chunks but you have to buffer and acknowledge each chunk before you send the next one which is very cludgy and momentarily slows down the sending computer if you have a lot of chunks.
Is there any other neat way to send a large picture array directly or "in the background"?
Each winsock senddata firing takes .06 seconds whereas it only takes .0001 second to break the full pic into chunks or reassemble it.
It's a bit like a mini video streaming appl.
 
Read the picture into the application in binary format so that you end up with a byte array. Send the byte array using via winsock.

If you've got large files you'll want to read the file in, in chunks that are equal to the size of your upload bandwidth.
 
I guess you are referring to thread222-557000. As I pointed out in a later thread )thread222-919107) this is an illustration of the technique, not a rigorous solution.

Yes, the VB winsock control sends the data in chunks of a maximum size of 8192*, so yes you have to collect all the chunks together - but this isn't particularly onerous, nor does it require acknowledgement for each chunk (at least not from your code, although obviously there are protocol ACKS going on behind the scenes)


* This is the default Winsock kernel buffer size, and is tricky to change for the Winsock control. Additionally you really need to know what you are doing down at the protocl level before you go messing with the size of transmission buffers ... If you do want to change it you need to be looking at the SO_SNDBUF and SO_RCVBUF options for the setsockopt API call
 
Thanks STONGM

I don't think I want to change the winsock buffer unless I can expands it to 1 meg!
A 1 meg BMP ends up as 125 chunks.
When I send 125 chunks in a loop, only the first few get through unless I introduce 0.2 secs time delay each send within the loop. The file then takes 25 seconds to send, tying up the computer in the process!
Using an aknowledgement for each chunk is actually faster (7.5 seconds)

I was hoping to send it at full network speed which should only take .01 second plus a little overhead for acks.

Or, put it into a buffer and send it in the background over say .5 second?

(I think Winsock was invented in the days of 28k modems!)

There must surely be a better way to do this?

(I'm going to post the following in the API forum but you might know the answer?)
Do you know a simple way to convert a picturebox image BMP to a JPG before sending out on a LAN?
Many conversion examples are around but they all refer to converting a FILE and saving it directly to disk from memory?
I don't have any files involved, the BMP comes from a USB camera. I currently get the BMP out of my clipboard in binary array form, put it into a picture box to detect motion, send the array thru the LAN and show a freeze frame on another computer's image box when anyone moves in front of the camera.
(A computer supervisor could use this to tell if one of their employees had gone to sleep!)

Now I want to convert the BNP image to JPG before sending (not make a JPG file).

I suppose I could use a ramdisk but that is cludgy too.
Ted Smith
 
On second thoughts so relatively few people use the API forums that I wont post it there!
Maybee they should combine them with this forum as a question there could be overlooked by someone that knows the answer who only browses this popular forum.
 
>Do you know a simple way to convert a picturebox image BMP to a JPG before sending out on a LAN?

Yes. And I've posted how to do it in this forum at least once ... you just have to search ...

>When I send 125 chunks in a loop

You shouldn't need to. You should just send the whole thing in one go. The underlying prorocol will break that into chunks for you so, sure, you have to loop at the receiving end. As for ACKs, the underlying protocol should be handling it all for you.

Using the VB control I can send a 1Mb BMP in under 1 second(and much of the overhead is caused by the fact that we have to copy data out of the transfer buffer into a temporary buffer and then the subsequent concatenation; the pure data transfer only takes about 350ms)
 
The underlying Winsock buffer size should not be a big concern, the default value works reasonably well. Logic within the Winsock control and Winsock will control the transfer of data from your source buffer (the buffer parameter you pass to the .SendData() method) and the actual Winsock buffer.

Generally the more important issue with TCP is the TCP Window size and trying to keep the underlying Winsock buffer "full enough" to use the Window fully. It is seldom worth playing with either the buffer size or Window size though in some cases turning on Window scaling can help.

Most of the time you can get excellent performance with the Winsock control by simply avoiding "Window starvation" on the send side and "Window flooding" at the receiver. I find that tuning my .SendData() chunks to between 16K and 32K and pacing .SendData() calls via the SendComplete event yields very good results. Sometimes a send chunk of around 8K is better, sometimes larger is better. It seems to vary with other characteristics of the program I haven't quantified, thus the need for tuning to find a "pretty good" compromise chunk size.


 
Not having seen STRONGM's second post he referred to, I was stumbling around in the dark following donkeys in other forums!

I notice one person's answer seems to be to stay in a loop in the data arrival sub until the full pic was received. I would think this would momentarily freeze the computer. Others suggest slow down the sending into 64k chunks.

Is there a better way like you normally do with MSComm in having continued dataarrival firings until the receivebuffer is emptied? That way other activities like keyboard entries can happen while the pic is being received.
I can't find any code examples that seems to do this.
Any ideas?
 
>send it in the background over say .5 second?

I repeat, using the propertybag method in a single send I can get a 1Mb image transferred in about 300ms. And then it takes about 200ms to load that image into a picturebox ...

Now, you may think that converting the image to a jPG and sending the smaller file might help you (as per you request both in this thread and in your new thread). However, I would suggest that the time taken to do the conversion and compression and then to convert back again at the other end, would outweigh any raw transmission time gains that you would make on files of this size
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top