YesYo.com MintState Forums
뒤로    YesYo.com MintState BBS > Tech > PHP
검색
멤버이름    오토
비밀번호 
 

한번의 커넥션으로 이미지 모두 전송하는 방법

페이지 정보

작성자 MintState 댓글 0건 조회 12,369회 작성일 08-11-03 10:25

본문

한번의 커넥션으로 이미지 모두 전송하는 방법

(BASE64로 인코딩한 이미지 data를 직접 HTML 문서에 추가하는 방법)

- 작성자 : san2(at)linuxchannel.net
- 작성일 : 2002.05.07
- 수  준 : 초중급
- 내  용 : HTML/PHP

http://www.linuxchannel.net/docs/img-src-base64.txt

이 문서는 이미지를 전송하는 과정에서 여러번의 커넥션 없이 한번으로 모두 전송하 방법을 소개합니다.

*주의)
서로의 장단점을 정확히 습득함을 요합니다.

reference : http://www.faqs.org/rfcs/rfc2397.html

1. 배경 및 개요
2. "data" URL scheme
3. IMG 태그 형태
4. 이미지 파일을 모두 BASE64로 인코딩 하기
  4-1. 커맨드라인에서 작업하기(파이썬 base64.py)
  4-2. PHP로 인코딩해 보기
5. 인코딩된 data를 HTML에 추가하기
  5-1. 단순 HTML만을 사용할 경우
  5-2. PHP를 사용할 경우
6. 벤치마크(속도대결)
7. 결론
8. 후기

---------------------------------------------------

*문맥상 간혹 경어를 생략했습니다. 양해해 주시길 바랍니다.

1. 배경 및 개요

클라이언트(이하 '웹브라우저')가 특정 HTML문서(new document)를 요청시 맨처음 한번의 커넥션이 이루어지고, 그 다음 HTML문서안에 <IMG> 태그가 만약 10개 있다면, 이는 추가적으로 10번의 재커넥션이 이루어질 수 있다는 점에서 초점을 맞추어 봅니다.

일반적으로 속도를 높이기 위해서 서버에서는 KeepAlive 기능을 사용하지만 상당히 바쁜 서버일 경우는 keepAlive를 off 하는것이 더 효과적입니다(리소스 문제).

이와같이 이미지를 모두 전송받기 위해서 웹브라우저는 추가적인 커넥션을 시도하는데, HTTP 상태코드가 302일 경우는 웹브라우저는 서버에서 이미지를 전송받지 않고 디스크 캐쉬나 메모리캐쉬에서 이미지를 가져와 출력합니다. 반면 302 코드가 아닐 경우는 직접 서버에서 이미지를 전송받습니다.

문제는 후자와 같이 직접 이미지를 전송받는 과정에서 여러번의 커넥션이 이루어지는데, 서버의 부하나 네트워크 장애 등등의 원인으로 상당히 지연되는 경우를 경험했을 겁니다.

이 문서는 이와 같이 이미지를 전송하는 과정에서 여러번의 커넥션 없이 한번으로 모두 전송하는 방법을 소개합니다.



HTTP 상태코드 302가 많은 경우는 오히려 역효과적임을 주의하시길 바랍니다.


2. data" URL scheme

RFC 2397에 의하면,



'[' 와 ']'으로 감싸인 부분은 옵션입니다.

"data:"
일부 어플리케이션에서는 URLs길이 제한이 있으므로 주의함. (RFC 1866)

<mediatype>
data의 media type(옵션).
만약 이 옵션이 없다면 기본값으로 text/plain;charset=US-ASCII 을 사용함.

";base64"
BASE64로 인코딩되어 있다는 의미(역시 옵션).
이 옵션이 없다면 ASCII, URL 표준 %xx hex 인코딩으로 대체된다.

예: data:,A%20brief%20note


<data>
실제로 BASE64로 인코딩된 data가 위치하거나 URL hex 인코딩된 문자열이 들어감.


그 외 참고사항,



3. IMG 태그 형태


다음의 태그를 긁어서 출력해 보세요..


뭐가 나오나요?


4. 이미지 파일을 모두 BASE64로 인코딩 하기

이미지 파일을 BASE64로 인코딩하면 약간 파일이 커짐에 주의하도록 합니다(약 30%이상 커짐).

4-1. 커맨드라인에서 작업하기(파이썬 base64.py)
다른 툴이 있는지 모르겠지만 필자는 커맨드라인에서 다음의 파이썬 스크립트를 이용한다.

/usr/lib/python1.5/base64.py



BASE64로 인코딩하려면 ?
(옵션이 없거나 -e 옵션 사용)



디코딩하려면?
(-d 옵션 사용)



다음과 같은 간단한 쉘스크립트를 이용해서 파일끝에 .enc를 붙여 인코딩 파일을 생성합니다.

-- img2base64.sh -------------------------------


사용법 :




4-2. PHP로 인코딩해 보기
PHP를 사용할 경우 base64_encode()함수를 사용한다.
예:
------------------------------------------------
<?php
fucntion get_file($file)
{
  if($fp = @fopen($file,r)) {
    $content = fread($fp,filesize($file));
    fclose($fp);
  }
  return $content;
}

$imgfile = get_file('foobar.gif');
$imgfile = base64_encode($imgfile);

echo $imgfile;
echo "\n<BR>\n<IMG SRC='data:base64,$imgfile'>\n";
?>



5. 인코딩된 data를 HTML에 추가하기

각각의 이미지 파일마다 BASE64로 인코딩된 파일을 생성했다는 가정입니다.

5-1. 단순 HTML만을 사용할 경우
앞의 IMG 태그 예제와 같이 직접 BASE64로 인코딩하여 그 data를 IMG 태그안에 손수 집어넣어야 합니다. (상당한 중노동이 필요할 듯......^.^)


5-2. PHP를 사용할 경우
------------------------------------------------
<?php
function get_file($file)
{
  if($fp = @fopen($file,r)) {
    $content = fread($fp,filesize($file));
    fclose($fp);
  }
  return $content;
}

function img_src($imgfile, $border=0, $argument='')
{
  $base64data = get_file('$imgfile.enc'); // encoded img file
  return "<IMG BORDER=$border $argument SRC='data:base64,$base64data'>";
}

echo img_src('images/foobar.gif');
echo "\n<BR>\n";
echo img_src('images/foobar2.gif',1);
echo "\n<BR>\n";
echo img_src('images/foobar3.gif",0,'WIDTH=200 HEIGHT=1');
echo "\n<BR>\n";
echo img_src('images/foobar4.gif',0,"ALT='foobar4'");
?>


위와 같이 직접 이미지 data를 전송하면 재 커넥션 없이 한번의 커넥션만 이루어집니다.
비교적 파일크기가 작고 여러번의 커넥션이 이루어진 홈페이지라면 상당히 유용할 겁니다. 용량이 큰 파일일 경우는 오히려 역효과가 날 수 있습니다.

참고로, 아파치 로그파일에서 이미지 파일에 접근 기록이 없어야 정상입니다.

다만, 주의할 점은 웹서버나 다른 어플리케이션에서 BODY의 길이를 제한하면 에러를 낼 수 있습니다. 또한 다른 장애(?)도 발생할 수 있습니다.

직접 테스트해 보시고
장점과 단점을 서로 비교해 보세요.


6. 벤치마크(속도대결)

start_time :
(1)클라이언트에서 문서 요청 -->
(2)웹서버 처리 -->
(3)클라이언트에게 전송 -->
(4)웹브라우저에서 문서 출력
end_time :

여기에서는, 실제로 웹브라우저가 출력하는데까지의 시간 측정은 상당히 어려우므로(?) (4)번 과정은 제외하고 (1)-(3)번까지의 과정을 wget 과 time으로 시간을 측정해 봅니다. (wget 이 가져온 결과를 /dev/null로 보냄)

주의할 점은 일반 HTML 문서에는 실제로 링크된 이미지 모두를 가져오는데 까지 시간을 측정해야 합니다.

- 크고 작은 이미지를 여러개 준비합니다
  준비한 이미지를 모두 BASE64로 인코딩합니다.
  (5개 이상으로 자신의 홈페이지 기준).

- 문서1(tmp.html)
  비교기준이 되는 일반 문서를 작성합니다.
  예: <IMG SRC='images/foobar.gif'> 와 같은 형식

- 문서2(tmp.php)
  PHP를 이용해서 한번의 커넥션이 이루어지도록 작성합니다.
  예: <IMG SRC='data:base64,$base64data'>

- 문서3(tmp.enc.html)
  인코딩된 data를 직접 HTML 문서에 추가합니다.
  예: <IMG SRC='data:base64,R0lGODdhMQAiAPcA...>
  하나하나씩 작성하기 힘드므로 문서2에서의 결과를
  저장합니다.

다음과 같은 쉘스크립트를 작성해서 테스트해 봅니다.
가능한 같은 네트워크의 다른 PC에서 테스트해 보세요.

-------------------------------------------------



아마 결과는 그리 만족하지 않을 겁니다. T.T


7. 결론

먼저 결론을 내리기 전에 필자는 이 문서를 작성해 놓고 상당히 고민했습니다.
이유는, 테스트에 대한 그 객관성이 상당히 결여되어 있고, 또한 당연한 결과인줄 알면서도 무모하게 도전한(?) 아둔한 생각 때문에...


굳지 결론을 내리자면,

 1) 일반적인 홈페이지일 경우 이 방법은 필요없습니다.
 2) 다만, 웹서버와 웹브라우저 간의 커넥션이 빈번하게 이루어지고 비교적 이미지가 자주 바뀌는 경우에 유용.
 3) 커넥션 수를 줄여서 그 효과를 볼 수 있는 경우.
 4) 양자를 혼용했을 경우 그 효과를 볼 수 있는 경우.
 5) 특별하게 따로 이미지 파일을 만들고 싶지 않을 경우(하나의 문서로 제공할경우).


8. 후기

생략(필자의 습관상 붙이는 단원)

__EOF__
첨부 파일
파일 종류: txt img-src-base64.txt (10.3K, 42 views)

댓글목록

등록된 댓글이 없습니다.

Total 165건 5 페이지
PHP 목록
번호 제목 글쓴이 조회 날짜
65 MintState 19195 11-03
64 MintState 26089 11-03
63 MintState 12708 11-03
62 MintState 18589 11-03
61 MintState 20549 11-03
60 MintState 15155 11-03
59 MintState 14291 11-03
58 MintState 11897 11-03
57 MintState 12198 11-03
56 MintState 18181 11-03
55 MintState 14962 11-03
54 MintState 16082 11-03
53 MintState 16898 11-03
열람중 MintState 12370 11-03
51 MintState 12249 11-03
50 MintState 12951 11-03
49 MintState 13094 11-03
48 MintState 14287 11-03
47 MintState 13414 11-03
46 MintState 13445 11-03
45 MintState 14335 10-31
44 MintState 12191 10-31
43 MintState 12528 10-31
42 MintState 14973 10-31
41 MintState 10721 10-31
게시물 검색
모바일 버전으로 보기
CopyRight ©2004 - 2024, YesYo.com MintState. ™