469,578 Members | 1,869 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,578 developers. It's quick & easy.

How to recieve a jpg from server using socket programming?

Hi all,

I have a small problem.

I am trying to download a JPG image from a server using C socket programming.

I use the following to "recv" the byte stream and store it into a file I call "test.jpg".

Expand|Select|Wrap|Line Numbers
  1. int fp = open("c:\\test.jpg", O_RDWR|O_CREAT);
  2.  
  3. /* set up the socket connection */
  4.  
  5. while(recvdata != 0){
  6.    recvdata = recv(sockfd, buff, 100, 0); 
  7.    if(recvdata != 0){
  8.        write(fp, buff, recvdata);
  9.    }
  10. }
  11.  
The problem is, after I try to open the test.jpg, it gives me a "Windows cannot open this image as it appears to be damaged, corrupted, or is too large" message.

If I use fopen to create the file though, I'm able to open the image in a select few image browser softwares, but not in the Windows Photo Viewer.

Can anybody point out what I am doing wrong? Is it possible to transfer an image over sockets like this?

Thanks,
Sid
Aug 23 '10 #1

✓ answered by Oralloy

Sid,

Try setting your file mode to binary. I'm pretty sure that the I/O system is translating LF to CRLF on you.

If I recall correctly, the uSoft open-mode flag is O_BINARY, but don't quote me on that.

Expand|Select|Wrap|Line Numbers
  1. int fp = open("c:\\test.jpg", (O_RDWR|O_CREAT|O_BINARY));
Cheers!

9 2122
Oralloy
983 Expert 512MB
Sid,

Try setting your file mode to binary. I'm pretty sure that the I/O system is translating LF to CRLF on you.

If I recall correctly, the uSoft open-mode flag is O_BINARY, but don't quote me on that.

Expand|Select|Wrap|Line Numbers
  1. int fp = open("c:\\test.jpg", (O_RDWR|O_CREAT|O_BINARY));
Cheers!
Aug 23 '10 #2
johny10151981
1,059 1GB
What is your OS? I think Vista or above wont let you create file on root of OS directory.(sorry didnt read the problem properly)
Aug 24 '10 #3
Airslash
221 100+
You need to make sort of wrapper around the data, or transmit in a seperate packet first the amount of bytes you're going to read from the socket in order to collect the whole image.

Just because you send out 100 bytes for example, does not guarantee that calling recv with 100bytes will read 100 bytes. You basicly need to keep looping on the receiv function untill all the required bytes are read.

I'm currently doing the same in C#.NET, so I have the advantage that the winsock library etc gets loaded for me, but the idea on both platforms is still the same.
Aug 24 '10 #4
Oralloy
983 Expert 512MB
@Airslash,

Good thought.

He might be having network difficulties. The odds are that he isn't, though. TCP/IP is basically guaranteed delivery (the error rates are so low in most cases that they are negligable, and certainly difficult to repeat for any small test image). TCP/UDP would be a different thing, but he's using recv(), and not recvfrom().

Unfortunately the code doesn't show how his network connection is set up, so we have no clue about the protocol he's using. It is entirely possible there's a one- or two- byte error in his protocol, resulting in a corrupt file. Check by sending a small plain text file of known size and content.
Aug 24 '10 #5
Airslash
221 100+
@Orally

You're right.
But I encountered the same problem when dealing with TCP connections to transfer Jpeg images. I often got exceptions on the data transfer and image assignment, but when viewing the image manually it worked fine for me. Kinda the opposite of the OP's case.

It's perfectly possible the buffer used to hold the data is not large enough to contain the whole image.
Aug 24 '10 #6
Oralloy
983 Expert 512MB
@Airslash,

Well, read buffer length is 100, so it's possible that he's got a buffer overrun. The better code would use:
Expand|Select|Wrap|Line Numbers
  1.    recvdata = recv(sockfd, buff, sizeof buff, 0);    
  2.  
Oh well. Hopefully srbakshi gets back with us and lets us know.
Aug 24 '10 #7
Hello all! :D

Sorry for the delay in replying, too much work in office. :'(

Oralloy you were spot on with your first suggestion about opening the file in binary mode. When I was using fopen to create the file, i *was* using the "b" flag to open it in binary mode, and that was the reason why I could open it in IrfanView.

The reason for the file not opening in Windows Photo Viewer was actually a pretty silly mistake. :P I was trying to get the google logo image from the google home page. This is what I was doing:
1. Create a socket connection to port 80 of www.google.com
2. Fire a GET /intl/en_com/images/srpr/logo1w.png request.
3. Receive the response and store it in a file.

The mistake was that the HTTP response had the HTTP header + the image data and both were getting stored into the file test.png. So I simply skipped the HTTP header and wrote the rest of the incoming bytes into the file (made binary using O_BINARY flag) and I got myself the google logo. :D

Thank you Airslash for your inputs as well. I incorporated them in my code. :)

Thank you so very much. :D
Sid
Aug 25 '10 #8
Oralloy
983 Expert 512MB
Sid,

Thanks for the feedback. I do appreciate it.

Especially the part about storing the response headers with the file. I've done that sort of thing before, and its good to have periodic reminders of the silly things that we can do wrong.

Cheers!
Aug 25 '10 #9
Airslash
221 100+
Glad we could help out.
Goodluck with the project.
Aug 25 '10 #10

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

1 post views Thread by Henrik | last post: by
5 posts views Thread by John Sheppard | last post: by
8 posts views Thread by =?Utf-8?B?Sm9obg==?= | last post: by
reply views Thread by suresh191 | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.