2016-10-31 3 views
1

간단한 http 서버를 만들고 있습니다. 지금까지 소켓은 html 파일을 위해 작동합니다. 이제 작업 이미지를 만들려고합니다. 그런 다음c 소켓을 통해 이미지 보내기

char * fbuffer = 0; 
long length; 
FILE *f; 

if ((f = fopen(file, "r")) == NULL) 
{ 
    perror("Error opening file"); 
    exit(1); 
} 

fseek (f, 0, SEEK_END); 
length = ftell(f); 
fseek (f, 0, SEEK_SET); 
fbuffer = malloc(length); 
int total = 0; 
if (fbuffer) 
{ 
    while (total != length) 
    { 
     total += fread(fbuffer, 1, length, f); 
    } 
} 
fclose (f); 

난 그냥 소켓에 데이터를 전송 :

char response[20048]; 
snprintf(response, sizeof(response), "HTTP/1.1 200 OK\nContent-Type: %s\nContent-Length: %i\n\n%s", type, (int) strlen(fbuffer), fbuffer); 
n = send(newsockfd, response, strlen(response)+1, 0); 

가 왜 이미지 작동하지 않습니다

이 내가 파일을 읽을 어떻게? 브라우저에서 오류 The image “http://127.0.0.1:1050/image.gif” cannot be displayed because it contains errors. HTTP 응답을 보여주는 것은 :

Content-Length: 7 
Content-Type: image/gif 

이미지가 247 바이트를 갖는다. 변수 길이와 합계는 247입니다. 변수 fbuffer는 GIF89a (+ 1 char -> 0 0 1 0 값을 가진 일부 2 진 사각형)를 포함합니다.

내가 뭘 잘못하고 있니?

감사합니다.

답변

1

fbuffer에는 이진 데이터가 포함되어 있지만 치료하려고하는 것은 strlen과 같은 함수를 사용하고 %s 형식 지정자를 사용하여 문자열을 처리하는 것입니다.

이진 데이터에는 null 바이트가 포함될 수 있으므로 null 바이트를 사용하여 문자열의 끝을 표시하므로 문자열 기능이 작동하지 않습니다.

출력 버퍼에 데이터를 넣으려면 memcpy과 같은 함수를 사용해야합니다.

char response[20048]; 
int hlen; 

hlen = snprintf(response, sizeof(response), 
    "HTTP/1.1 200 OK\nContent-Type: %s\nContent-Length: %d\n\n", type, length); 
memcpy(response + hlen, fbuffer, length); 

n = send(newsockfd, response, hlen + length, 0); 
+0

저 memcpy가 어떻게 작동하는지 설명해 주시겠습니까? HTTP 헤더를 int로 저장하면 어떻게 복사 할 수 있습니까? – dontHaveName

+0

@dontHaveName'memcpy' 함수는 지정된 바이트 수를 한 버퍼에서 다른 버퍼로 복사합니다. 버퍼에있는 내용은 중요하지 않습니다. 이 경우 우리는'snprintf'를 사용하여 텍스트 인 헤더를 만듭니다. 이 함수는 기록 된 바이트 수를 반환했습니다. 그런 다음이 값을 사용하여'memcpy'에게 버퍼에 많은 바이트 즉, 헤더 뒤에있는 바이너리 데이터를 써야한다고 알려줍니다. – dbush

+0

나는 다시 같은 문제가있다. 이번에 나는 stidin에서 2 개의 char 변수를 가지고있다. 나는 이처럼 읽는다. while ((c = getchar())! = EOF) {a [index] = c; b [index] = c; 색인 ++)}'. 그런 다음'write (newsockfd, & a, strlen (b)) '를 사용하여 소켓에 직접 씁니다. 다시 GIF89a를 표시합니다. 왜? 나는'a' 변수에 strlen이나 printf 함수를 사용하지 않습니다. 고마워요. 원한다면 새로운 질문을 만들 수도 있습니다. – dontHaveName

2

C의 문자열은 \0 문자로 끝납니다. 이미지의 이진 표현에는 데이터 내의 어딘가에이 문자가 들어있을 가능성이 큽니다. 즉, %s, strlen(..) 등이 단순히 \0 문자로 멈춰서 이진 데이터로 사용할 수없는 경우에 사용할 수 있습니다.

+0

흠, 흥미로운 감사와 솔루션은 다른 유형으로 fbuffer를 변경하는 것입니다? – dontHaveName

+0

@dontHaveName : 이동 방법은 http://stackoverflow.com/questions/13656702/sending-and-receiving-strings-over-tcp-socket-separately를 참조하십시오. –

+0

거기에 답변을 찾을 수 없지만 @dbush는 이미 저에게 대답했습니다. 둘 다에게 감사드립니다. 그것은 작동합니다. – dontHaveName

관련 문제