problem sending image file over the socket in c
I am writing a C based server supporting HTTP. &buffer[5] has the file name. I set the header in next step and then send the file in block of 8Kb. It is working fine when I am requesting a txt file, but when I request a jpg file, it is not giving any o/p. Is there any specific care I need to take for image file or there is some other problem.
void web(int fd)
{
int j, file_fd;
int buflen; int len;
long i, ret;
char * fstr;
static char buffer[BUFSIZE+1]; /* static so zero filled */
ret =read(fd,buffer,BUFSIZE); /* read Web request in one go */
if(ret == 0 || ret == -1) { /* read failure stop now */
//log1(SORRY,"failed to read browser request","",fd);
}
if(ret > 0 && ret < BUFSIZE) /* return code is valid chars */
buffer[ret]=0; /* terminate the buffer */
else buffer[0]=0;
for(i=0;i<ret;i++) /* remove CF and LF characters */
if(buffer[i] == '\r' || buffer[i] == '\n')
buffer[i]='*';
log1(LOG,"request",buffer,1);
if( strncmp(buffer,"GET ",4) && strncmp(buffer,"get ",4) )
log1(SORRY,"Only simple GET operation supported",buffer,fd);
for(i=4;i<BUFSIZE;i++) { /* null terminate after the second space to ignore extra stuff */
if(buffer[i] == ' ') { /* string is "GET URL " +lots of other stuff */
buffer[i] = 0;
break;
}
}
for(j=0;j<i-1;j++) /* check for illegal parent directory use .. */
if(buffer[j] == '.' && buffer[j+1] == '.')
log1(SORRY,"HTTP/1.0 400 Bad Request: Invalid URI: \n Parent directory (..) path names not supported",buffer,fd);
if( !strncmp(&buffer[0],"GET /\0",6) || !strncmp(&buffer[0],"get /\0",6) ) /* convert no filename to index file */
(void)strcpy(buffer,"GET /index.html");
/* work out the file type and check we support it */
buflen=strlen(buffer);
fstr = (char *)0;
for(i=0;extensions[i].ext != 0;i++) {
len = strlen(extensions[i].ext);
printf("%s\t%s\t%d\n", &buffer[buflen-len],extensions[i].ext, strncmp(&buffer[buflen-len], extensions[i].ext, len));
if( !strncmp(&buffer[buflen-len], extensions[i].ext, len)) {
fstr =extensions[i].filetype;
break;
}
}
if(fstr == 0)
log1(SORRY,"HTTP/1.0 400 Bad Request: Invalid URI:\n file extension type not supported",buffer,fd);
printf("Buffer Value: %s\n",&buffer[5]);
if(( file_fd = open(&buffer[5],O_RDONLY)) == -1) /* open the file for reading */
{
log1(SORRY, "HTTP/1.0 404 Not Found\n failed to open file",&buffer[5],fd);}
printf("file Descrptr:%d\n",file_fd);
log1(LOG,"SEND",&buffer[5],1);
(void)sprintf(buffer,"HTTP/1.0 200 OK\r\nContent-Type: %s\r\n\r\n", fstr);
(void)write(fd,buffer,strlen(buffer));
printf("Buffer Header:%s\n",buffer);
//int rec = read(file_fd, buffer, 10*BUFSIZE);
/* send file in 8KB block - last block may be smaller */
while ( (ret = re开发者_如何学Cad(file_fd, buffer, BUFSIZE)) > 0 ) {
(void)write(fd,buffer,ret);
printf("BufferData:%d\n",strlen(buffer));
}
#ifdef LINUX
sleep(1); /* to allow socket to drain */
#endif
exit(1);
}
o/p for jpg file:
server: got connection from 127.0.0.1
Buffer Header:HTTP/1.0 200 OK
Content-Type: image/jpeg
BufferData:4
BufferData:95
BufferData:122
BufferData:24
BufferData:217
for txt file:
Buffer Value: config.txt
file Descrptr:4
Buffer Header:HTTP/1.0 200 OK
Content-Type: text/plain
BufferData:416
If your code is working for txt files, give fread/fwrite a try instead of read/write . There might be a problem with NULL characters in jpg image which are not present in txt files. And do include a content length in header otherwise in some cases your browser will keep on requesting even if your download has finished. In simple words browser don't know when to stop.
You probably need to specify the correct Content-Type in the HTTP header. It isn't just 'text' any more.
HTTP response lines are supposed to end with CRLF - read the standard. Most internet protocols require this line ending, in fact.
You haven't specified a Content-Encoding; you haven't specified the length of the data. I think you're supposed to do both.
Why don't you send a request to a web server that handles requests correctly for a small JPEG file, and see what it generates. You'd check that the URL works in a browser, showing you the image, then you'd use a low-level program (possibly even telnet web.server.example.com 80
) to send the request and collect the response. Compare that with what your code generates.
Or you could read the standard.
You should check that the number of bytes written was the number you intended to write(). If you get a short write, you should try again to write the rest - so you need a loop around your write (or a function that contains the loop). You should also report errors if an error is reported to you (by write()
, for instance).
Here's a shell script that sends a request to a particular server and collects a 368-byte gif:
{
echo "GET /img/mailtruck.gif HTTP/1.0^M"
echo "^M"
} |
tee request |
nc my.earthlink.net 80
The '^M
' characters are carriage returns; I used CONTROL-V and CONTROL-M to enter those. The program nc
(netcat) sends the request to the server. The response comes back starting with:
HTTP/1.1 200 OK
Cache-Control: Tue, 25 Jan 2011 16:34:03 GMT
ETag: W/"368-1219455793000"
Last-Modified: Sat, 23 Aug 2008 01:43:13 GMT
Content-Type: image/gif
Content-Length: 368
Date: Tue, 25 Jan 2011 08:34:03 GMT
Server: Apache-Coyote/1.1
Connection: Keep-Alive
The full response in a hex-dump format is:
0x0000: 48 54 54 50 2F 31 2E 31 20 32 30 30 20 4F 4B 0D HTTP/1.1 200 OK.
0x0010: 0A 43 61 63 68 65 2D 43 6F 6E 74 72 6F 6C 3A 20 .Cache-Control:
0x0020: 54 75 65 2C 20 32 35 20 4A 61 6E 20 32 30 31 31 Tue, 25 Jan 2011
0x0030: 20 31 36 3A 33 32 3A 35 39 20 47 4D 54 0D 0A 45 16:32:59 GMT..E
0x0040: 54 61 67 3A 20 57 2F 22 33 36 38 2D 31 32 31 39 Tag: W/"368-1219
0x0050: 34 35 35 37 39 33 30 30 30 22 0D 0A 4C 61 73 74 455793000"..Last
0x0060: 2D 4D 6F 64 69 66 69 65 64 3A 20 53 61 74 2C 20 -Modified: Sat,
0x0070: 32 33 20 41 75 67 20 32 30 30 38 20 30 31 3A 34 23 Aug 2008 01:4
0x0080: 33 3A 31 33 20 47 4D 54 0D 0A 43 6F 6E 74 65 6E 3:13 GMT..Conten
0x0090: 74 2D 54 79 70 65 3A 20 69 6D 61 67 65 2F 67 69 t-Type: image/gi
0x00A0: 66 0D 0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 74 f..Content-Lengt
0x00B0: 68 3A 20 33 36 38 0D 0A 44 61 74 65 3A 20 54 75 h: 368..Date: Tu
0x00C0: 65 2C 20 32 35 20 4A 61 6E 20 32 30 31 31 20 30 e, 25 Jan 2011 0
0x00D0: 38 3A 33 32 3A 35 39 20 47 4D 54 0D 0A 53 65 72 8:32:59 GMT..Ser
0x00E0: 76 65 72 3A 20 41 70 61 63 68 65 2D 43 6F 79 6F ver: Apache-Coyo
0x00F0: 74 65 2F 31 2E 31 0D 0A 43 6F 6E 6E 65 63 74 69 te/1.1..Connecti
0x0100: 6F 6E 3A 20 4B 65 65 70 2D 41 6C 69 76 65 0D 0A on: Keep-Alive..
0x0110: 0D 0A 47 49 46 38 39 61 25 00 21 00 B3 08 00 FD ..GIF89a%.!.....
0x0120: 9C 00 DE 36 03 58 44 29 19 15 04 D2 D3 D3 F1 85 ...6.XD)........
0x0130: 66 A4 A4 A3 FE FE FE FE FE FE 00 00 00 00 00 00 f...............
0x0140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 ...............!
0x0150: F9 04 01 00 00 08 00 2C 00 00 00 00 25 00 21 00 .......,....%.!.
0x0160: 00 04 FF 10 C9 49 AB BD 38 EB 49 84 27 5B 78 19 .....I..8.I.'[x.
0x0170: 1E 60 7A 86 28 76 82 E9 9E 02 A8 8E E5 6B 03 E8 .`z.(v.......k..
0x0180: CC D5 77 FF A9 A4 56 6F E8 12 84 58 C4 E4 69 43 ..w...Vo...X..iC
0x0190: 52 26 03 81 C1 A5 83 20 0C 9C 43 28 54 6A B1 22 R&..... ..C(Tj."
0x01A0: 3C 03 21 56 5B 28 6C A7 03 EB 60 CD CB 06 08 E5 <.!V[(l...`.....
0x01B0: F2 B9 0B 5E B3 C3 6E F3 5B 1F CD D8 FF 6C 62 00 ...^..n.[....lb.
0x01C0: 64 7A 70 5A 5C 16 02 77 80 61 2D 01 02 5A 04 01 dzpZ\..w.a-..Z..
0x01D0: 07 01 72 73 15 4D 51 8A 8C 26 6B 50 66 72 96 7D ..rs.MQ..&kPfr.}
0x01E0: 89 2F 60 9B 6B 38 9E 7B 7A 83 87 74 37 8B 2D 9B ./`.k8.{z..t7.-.
0x01F0: 50 86 50 AD 97 13 82 36 9B A9 61 B4 7C 66 A7 32 P.P....6..a.|f.2
0x0200: 12 4D 44 01 83 76 9F 96 7A 8D 6B C3 06 C7 4A 51 .MD..v..z.k...JQ
0x0210: 5A 95 05 70 7C 03 06 24 69 13 DA 04 4F D4 BF 95 Z..p|..$i...O...
0x0220: 87 69 DE 14 DA 41 6E E1 E1 1E ED 31 98 50 EE 36 .i...An....1.P.6
0x0230: EB EC EF 55 06 C3 12 56 05 00 05 EE 62 D4 20 1D ...U...V....b. .
0x0240: B2 A7 A1 83 36 13 FE 3E 48 22 37 40 53 BE 0D 2C ....6..>H"7@S..,
0x0250: B4 F1 F3 67 80 8F 22 16 0F 81 A0 30 60 E2 98 16 ...g.."....0`...
0x0260: 45 07 1D 8C E8 A0 23 40 E2 20 61 22 47 5A 08 82 E.....#@. a"GZ..
0x0270: 2E 46 44 95 19 58 94 84 39 43 1B CD 9B 30 23 00 .FD..X..9C...0#.
0x0280: 00 3B .;
0x0282:
The request is minimal; the response probably is not, but you'll have to experiment with what you have to send.
精彩评论