기존에 태그매니아 고급강좌부분에 스타일 시트를 2페이지 분량의 간단하게 올려 놨었는데요..... 많은 분들이 그것으로만은 스타일 시트가 뭔지 감이 잡히질 않는 다는 말씀을 하셔서 이번 업데이트 때 스타일 시트 특강을 마련하게 되었습니다. 스타일 시트 역시 기초부터 차근차근 설명해드릴 텐데요...... 제 강좌만 잘 따라오신다면 스타일시트는 자바스크립트 보다는 훨씬 쉽기 때문에 태그처럼 일주일안에 다 배우 실 수 있을 겁니다. 단, 태그나 자바스크립트 역시 마찬가지이지만 태그매니아에서는 어느 정도 중급수준까지는 올려 주지만 나머지 응용부분에서는 여러분들이 직접 웹서핑을 하면서 하나하나 경험하면서 배우셔야 할 겁니다. 그래야 실력도 금방 금방 늘게되고...또한 제가 늘 시간이 많은 게 아니라서요.....응용강좌까지 할려면 내년 이맘때 쯤이 되어야 할 수 있을 까요? 물론 그때까지 태그매니아 홈페이지가 존재한다면은요...^^ 그전까지는 자기가 직접 찾아가면서 배우셔야 할 겁니다. 흠.....^^ 왠지 두부(頭部)가 길어지는데......그럼 이제부터 스타일 시트 특강을 시작하도록 하겠습니다. 잘 보고 배우시길 바랍니다.

※ 스타일 시트(Style Sheets)란?

뭔가를 배우더라도 자신이 지금 배우고 있는 것이 무엇인지는 알고 있어야 겠죠? ^^ 스타일 시트(css)란 쉽게 말해서 HTML의 단점을 보완하기 위해서 나온 언어(?) 라고 할 수 있습니다. 기존에 HTML의 경우 일일이 폰트, 색상, 크기 등을 다 적어주어야 했는데요.....하기사 요즘은 워낙 좋은 웹에디터들이 많이 나와서 일일이 다 태그를 입력하는 일은 없을 텐데요....웹에디터가 없었을 땐 태그명령어를 모두 다 손으로 키보드를 눌러가며 입력해서 홈페이지를 만들 었답니다. 이렇게 하다보니깐 홈페이지 하나 만들려면 시간과 노력이 엄청나게 들어가게 되었죠. 그래서 생각해 낸게 스타일 시트랍니다.

※ 스타일 시트의 장점

일단 웹페이지 관리가 쉬워 집니다.
태그를 입력할 때보다 손이 덜 아프답니다. -_- ;;;
웹페이지를 전보다 멋지게 꾸밀 수 있습니다.
로딩시간도 오래 걸리지 않습니다.
배우기 쉽습니다.
왠지 멋져보입니다. ^^

구체적으로 말하자면 기존에 태그만을 이용할 때는 웹페이지의 2개 이상의 폰트를 정해줄 때 글자마다 각기 다른 폰트명을 적어 주어야 했었는데...스타일 시트를 사용하면 간단하게 몇 줄만 적어주면 모든게 끝나게 되죠. 예를 한번 볼까요?

<html>
<head></head>
<body>
<font face="궁서체" size="2">이건 예제입니다</font><br>
<font face="돋움체" size="4" color="red"><b>태그매니아</font></b><br>
<font face="궁서체" size="2">예제 끝입니다.</font>
</body>
</html> <html>
<head>
<style type="text/css">
font { font-size: 12px; font-family: 궁서체; }
b { font-size: 14px; color : red; font-family : 돋움체; }
</style>
</head><body>
<font>이건 예제입니다.<br><b>태그매니아</b><br>
예제 끝입니다.</body>
</html>

위에 예제를 보면...흠...글쎄....하시는 분들도 계실텐데..... 언듯 보기에는 글자수가 비슷해 보일지는 몰라도 웹페이지가 위에 예제처럼 딸랑 3줄로 끝나고 마는 웹페이지는 없죠. 대부분이 엄청난 양의 태그명령어를 필요로 하지만 스타일 시트를 이용하면 각각의 태그를 공통분모로 잡아줘서 그 상태를 설정해주기 때문에 훨씬 간단하게 웹페이지를 만들 수 있답니다.
흠....-_-;;; 몇 마디 하다보니 벌써 웹페이지 한장이 가득 찼네요. 다음 페이지에서 계속 하도록 하겠습니다.


앞장에 이어 계속 하겠습니다. 앞에서는 간단하게 스타일 시트의 개념에 대해서 알아보았는데요.... 이제부턴 스타일 시트이 기본적인 사용방법에 대해서 알아보도록 하겠습니다. 그런데...여기서 잠시 기본적인 사용방법을 배우기 전에 간단하게 스타일 시트의 원리를 알려드리겠습니다.

<style type="text/css">
<!--
h1 { color : red ; font-size : 14px; font-family :돋움체; }
b { background : green; font-size : 10px; }
-->
</style>

위에 예제를 보면 알 것 같다 하시는 분들은 태그를 열심히 배우신 분일 것이고 모르겠다 하시는 분들은 그렇지 않은 분일 겁니다. 하나 하나 설명해드리자면 <style type="text/css"></style>은 당근 스타일 시트를 나타내줄 때 적어주는 거죠. 자바 스크립트와 같은 방법이죠. 그리고 <!-- -->의 경우 주석문이고요.... 주석문은 스타일 시트를 지원하지 않는 브라우져에 대해서 스타일 시트 소스가 브라우져에 표현되는 걸 막아주는 역할을 하죠.
h1 { color : red ; font-size : 14px; font-family : 돋움체; } ☜ 이것은 <h1><h1> 태그 내에 있는 텍스트 기타 요소에 대해서 색은 빨간색, 글자크기는 14px , 글자체는 돋움체로 하라는 것이죠. 이해되시죠? 마찬가지로.....
b { background : green; font-size : 10px; } ☜이것의 경우는 <b></b> 태그 내에 있는 요소에 대해서 배경색은 녹색, 글자크기는 10px 로 하라는 의미죠. 그런데 여기서 주의 깊게 볼 것이 있습니다. 위의 스타일 시트의 경우 해당 태그내의 요소에 대한 속성을 정해주는 것이죠. 쉽게 말해서.. 해당태그 { 속성:지정; 속성:지정; 속성:지정; } ☜이런 식입니다. 속성지정과 속성지정 사이마다 ; ☜이 표시를 해준다는 것 , 그리고 color : red 이런 식으로 중간에 : ☜이 표시가 들어간다는 것 반드시 기억하시기 바랍니다. 흠.....^^ 간단하게 설명한다는게 설명이 조금 길어졌네요^^

아 ~ ! 그리고 배울게 또 하나 더 있다. 바로 '상속성' 이라는 건데요. 상속이 뭔지는 아시죠? 부모님으로부터 재산을 물려 받을 때 상속받는다고 하는데......참고적으로 우리나라의 가족법상 상속비율은 배우자 1.5 , 자녀들은 아들 딸 구별없이 똑같이 1 의 비율로 상속을 받습니다. 그냥 참고적으로 알고 계시길..... 흠... 계속 이어서 스타일 시트의 상속성에 대해서 이야기 하겠습니다. 스타일 시트에서 상속성이란 ... 흠...뭐라 설명해야 되나?? 굳이 표현을 하자면 스타일 시트로 지정된 해당 태그 내에 다른 태그에 대해서도 지정된 스타일 시트의 속성이 적용되는 것을 말합니다. 이해 되세요? 뭔 소리인지 모르는 분들이 더 많을 것 같아 한가지 예를 들어 설명 드리겠습니다.

<style type="text/css">
<!--
u { color : red ; font-family : 돋움체; }
-->
</style>
<u>u 태그는 내에 있는 <b>b태그는</b> 어케?</u>


위에 예제를 보면 <u></u>태그에 대해서 스타일 시트를 지정해 주었죠. 색은 빨간색, 글자체는 돋움체로 지정해주었는데.....예제를 보면 <u></u>태그 내에 있는 <b></b>태그에 대해서까지 그 속성이 적용되죠. 이걸 바로 스타일 시트의 상속성이라고 합니다. 어때요? 간단하죠? 이것은 주로 어디에 많이 쓰냐면 은요....해당 웹페이지 전체에 공통적으로 해당되는 속성을 지정해 줄때 사용됩니다. body { font-size : 13px; } ☜이런 식으로 하면 해당 웹페이지의 글자크기가 모두 13px가 된답니다. 그렇다면 여기서 의문점이 하나 생기죠? 만약 위와 같이 설정한 웹페이지에서 글자크기가 다른 글자를 표현할려면 어떻게 해야 할까요? 쉽게 말해서 모두 글자크기가 13px인데 그 중 일부분을 15px로 해주고 싶다면...? 거 역시 간단하죠.....아래 예제를 보면 바로 이해가 되실 겁니다.

<style type="text/css">
<!--
u { color : red ; font-size : 13px; font-family : 돋움체; }
b { color : blue ; font-size : 15px; font-family : 궁서체; }
-->
</style>
<u>u 태그는 내에 있는 <b>b태그는</b> 어케?</b>


어때요? 일부분(b 태그)에 대해서 정의를 해주면 간단하게 해결되죠? 일단 선행태그에 의해 상속이 되어도 일부분에 대해서 따로 지정을 해주면 그 부분에 대해선 따로 지정된 속성이 지정되게 되는 거죠. 그렇지만 따로 지정되지 않은 사항에 대해선 그대로 상속이 된답니다.
기본적인 사용방법 설명하기로 했는디.....원리와 상속성 설명하다보니 한 페이지가 벌써 다 차버렸네요...^^ 어쩔 수 없이 다음 페이지에서 이어서 설명드리져..^^


드뎌..... 기본 사용방식에 대해서 설명드리네요.^^ 스타일 시트의 사용방식은 세가지 형태로 나누어 지는데요.... 사용방식이 3가지 형태로..? 말이 좀 이상하죠? 흠..-_- ;;; 사용방식이라고도 할 수 있는데...쉽게 말해서 웹페이지에 스타일 시트를 넣어서 사용하는 방법을 말합니다. 세가지란 우리가 지금까지 예제로 봐왔던 "embeded 방식" , 그리고 css파일을 만들어 "링크시키는 방식" , 마지막으로 직접 HTML태그내에 스타일 시트를 적용시키는 "인라인방식" 으로 나눌 수 있습니다.

☞ embeded (임베이드) 방식

<style type="text/css"></style> 을 사용하여 스타일을 지정하는 방식으로써 웹페이지의 <head></head>부분에 들어가게 되죠. 일명 웹페이지 포함 방식입니다. 일반적으로 공통된 스타일 시트가 적용되는 웹페이지의 수가 몇 개 안되는 경우에 사용됩니다.

☞ 링크시키는 방식

일반적으로 메모장에 스타일 시트를 적어 확장자를 css파일로 해서 저장한 다음 이 파일을 각각의 웹페이지에 링크시키는 방식으로써 공통되는 스타일 시트가 적용되는 웹페이지의 수가 많을 경우 <head></head>사이에
<link rel = stylesheet href="lovestory.css" type="text/css"> ☜이런 방식으로 링크를 시켜주는 방법입니다.

☞ 인라인 방식

HTML태그 내에 직접 스타일 시트를 적용시켜 주는 방식입니다. 채팅방에서 많이 사용됬던 태그 중 하나였는데요...^^ 예제를 보시면 바로 알 수 있습니다.

<body>
<font style="font-size:20pt; color:red; font-family:돋움체;">태그매니아</font>
<p style="background:yellow; font-size:15; font-family:궁서체;">방갑습니다.</p>
</body>

이상으로 스타일 시트의 기본적인 방식 3가지에 대해서 말씀드렸습니다. 일반적으로 임베이트 방식이 가장 많이 사용되는 거 같구요. 태그매니아 홈페이지도 임베이드 방식으로 사용하고 있는데....언제 날 잡아서 링크방식으로 바꿔야 겠군요...요즘 시간이 없어서리.....-_- ;;; 아....그리고 혹시 링크시키는 방식에서 css파일을 어떻게 만들어야 하는가 궁금해 하실 분들이 있을 것 같아 간단하게 설명드리겠습니다. 일단 메모장에다가 임베이트 방식으로 스타일 시트를 적어 넣습니다. 그런다음 저장을 할 때 확장자를 css로 해서 저장을 시키세요. 그런 다음 위에서 설명한 것처럼 링크방식을 이용해서 웹페이지의 head 부분에 넣어주시면 되죠. 간단하죠?

흠......스타일 시트 첫번째 특강은 여기서 마치도록 하겠습니다. 두번째 특강에서는 class 사용방법에 대해서 알아보도록 하겠습니다. 푸~하~(하품하는 소리 -_- ;; ) 잠이 와서 안되겠습니다. 오늘 셤도 끝나고 해서 올나이트를 한번 해볼까 했는데....역시 나이는 못 속이는 구만요........ 한창땐...3일동안 밤을 세워도 끄떡 없었는데......... zzzzz

그럼 20000

☞ class

특강1 마지막에 예고 드렸듯이 이번에는 스타일 시트에서의 class를 지정하는 방법을 배워보겠습니다. 여기서 말하는 class는 자바 애플릿에서 사용되는 class파일과 전혀 다른 것이니 혼돈하지 마시길 바랍니다.
스타일 시트는 임의의 태그에 그 속성을 지정해주어서 해당 태그에 속하는 요소에 대해서 그 속성을 나타내어 주게 하는 작용을 하는 데요.....그럼 여기서 같은 스타일을 적용받는 태그내에서 다른 스타일을 적용시킬려면 어떻게 해야 할까요? 앞에서 배운 인라인 방식을 이용해서 직접 해줄 수 있겠지만 그건 일일이 태그내에 다 적어주어야 하기 때문에 좀 짜증나죠? 바로 여기서 사용될 수 있는게 class입니다. 예를 한번 볼까요?

<style type="text/css">
<!--
body { color : red; font-size:12px; font-family: 돋움체; }
h1 { color: blue; font-size:25px; }
p { color : green; font-size: 14px; }
p.love { color : black; font-size: 15px; }
p.story { color : skyblue; font-size: 18px; }
-->
</style>
<body>
<h1>태그매니아</h1>
<br>스타일 시트에서의 class사용법(여긴 body 부분)
<p>사용방법은 다음과 같다.(여긴 p 부분) </p>
<p class=love>여긴 class=love 인 곳이다.</p>
<p class=story>여긴 class=story 인 곳이다.</p>
<p>어때요? 확 차이가 나죠? </p>
</body>

위에 예제를 태그연습장에서 실행시켜보면 같은 p태그 내에서도 class로 따로 스타일을 지정해준 곳은 해당 스타일이 적용되는 것을 볼 수 있습니다. 구체적으로 <p> 태그에서도 love와 story로 class를 지정해준 곳은 해당 지정 스타일인 love 의 경우 검정색과 글자크기 15px 이 적용이 되고 story 의 경우 하늘색과 글자크기 18px 이 적용되는 것을 볼 수 있습니다. 그리고 마지막 class를 지정해주지 않은 <p> 태그 부분은 원래의 <p>태그에 지정된 스타일이 적용되죠. 어때요? 이해되시죠? 여기서 class의 이름은(love , story)는 여러분들 맘에 드는 단어(한글도 가능)로 지정해주시면 됩니다. 단, 주의 할 점은 head 부분에 들어가는 class 이름과 태그에 들어가는 클래스 이름이 반드시 일치해야만 해당 스타일이 적용됩니다. 음..... 그리고 중요한 게 하나 있는데....head 부분에 지정되는 class 이름 앞에 . ☜ 점을 꼭 해주어야 합니다. 만약 점(.)을 해주지 않으면 그 뒤에 오는 class 이름을 태그로 인식을 합니다. 그러면 당연히 해당 스타일 시트가 적용되지 않고 의도한 바와는 다른 엉뚱한 결과가 나오게 되겠죠. 점(.)을 안 해주는 경우에 대해선 좀 있다가 배우도록 하고요.........
그럼 이번에는 class를 지정해주는 방법 중 하나인데....... 헉 o.0 ;; 그런데 벌써 스크롤 바가 상당부분 하단으로 내려와 있네요...^^> 웹디자인의 기본원칙 중에 하나의 페이지에 너무 많은 글을 적지 말라는 말이 있는데요.....왜냐면 너무 많은 글을 적게 되면 그 글을 읽는 사람들이 읽다가 질려버린다고 하더군요... 맞는 말인거 같아요... -_-;;; 태그매니아 홈페이지는 글자가 넘 많은 거 같테..... 근데...그건 자세히 설명 하다보면 어쩔 수 없이 늘어나게 되더군요. 이해해주시길..... 대신 이렇게 질렸다 싶을 때 다음 페이지로 넘어 가게 하고 있답니다...... 핫핫 ^^ 다음 페이지에서 이어 계속 설명드리도록 하겠습니다.

흠.... 뭐하다가 넘어오게 된거죠? -_- ? ??? .... 하~! 맞져! class 파일 지정하는 다른 방법에 대해서 설명하려다가 넘어온거죠. 계속 설명드리도록 하죠. ^^ 앞장에서는 태그.클래스이름 ☜ 이런 식으로 지정해주었는데요.... 이번 예제에서는 약간 다르게 해준 거랍니다.

<style type="text/css">
<!--
.love { color : red; font-size: 13px; font-family: 돋움체; }
.story { color : blue; font-size: 18px; }
.kiss { color : skyblue; font-size: 23px; }
-->
</style>
<body class=love>
<h1 class=kiss>태그매니아</h1>
<p>여기는 love 클래스의 영향을 받게 되지요 ^^</p>
<p class=story>여기엔 story 클래스가 지정됬구요..^^</p>
이상 태그매니아 였습니다. ^^v
</body>

위에 예제를 보시면 head 부분의 스타일 시트 정의부분에서 class 이름을 지정해 줄때 앞에 태그를 생략해주었죠. 이런 경우에는 보시다시피 태그부분에서 클래스를 아무 태그부분에나 지정을 해주면 그 태그 내에서 해당 클래스의 스타일이 적용이 되게 됩니다. 예제를 가지고 좀더 자세히 설명하자면 <body> 부분에 love 클래스를 연결 시켜주고...<h1> 부분에 kiss 클래스를 연결 시켜주었죠. 그리고 <p>태그에는 story 클래스를 연결시켜 주었구요. 그러자 각각 해당 클래스에 지정된 스타일이 적용이 되는 군요. 이런 경우 앞장에서 배운 경우 보다는 좀더 신축성있게 스타일 시트를 적용할 수 있을 겁니다. 그쵸? ^^ 실제로 복잡한 웹페이지에서 스타일 시트를 사용할 때는 class 를 많이 적용해서 사용한답니다.
여러분들 웹서핑을 하다가 가끔씩 웹페이지 소스를 보면 스타일 시트 부분에 아래와 같은 것을 많이 봤을 겁니다.

A:link { text-decoration:none; color: 00448B;}
A:visited { text-decoration:none; color: 00448B;}
A:active { text-decoration:underline; color: 00448B;}
A:hover {color: blue; text-decoration:underline;}

이걸 앵커 가상 클래스라고 하는데...보통 우리가 홈페이지의 링크된 부분에 마우스를 가져다 대면 색이 바뀌면서 밑줄이 생기기도 하고 또한 한번 클릭한 링크부분은 다른 곳과 색이 달라지게 되기도 하는데....그걸 조절하는 스타일 시트랍니다. 당연 <a> 태그에 적용되는 거니깐 앞에 A 가 붙게 되고 그 다음 link는 아직 방문을 하지 않은 링크부분, visited는 한 번 이상 방문한 부분, active는 마우스로 클릭하는 순간의 지정해주는 것입니다. 마지막으로 hover의 경우는 마우스를 링크위에 올려놨을 때의 스타일을 지정하는 거죠. 그리고 나중에 또 배우겠지만 세부적인 사항으로 text-decoration:none; ☜이건 링크된 부분에 밑줄을 나타나게 해줄 것인지 아닌지를 경정해주는 것이랍니다. underline의 경우 밑줄이 생기는 것이고 none의 경우는 생기지 않는 경우이죠. 위에 설명한 앵커 가상 클래스는 실질적으로 스타일 시트에서 가장 많이 쓰인다고 해도 과언이 아닐 정도로 주로 사용됩니다. 반드시 숙지하고 계시길......... (앵커 가상 클래스에 대한 예제는 특강 마지막 부분에서 다루도록 하겠습니다.) 다음 페이지에서 이어 계속 설명드리겠습니다. Let's Go!


특강 2 의 마지막 페이지이네요.^^ 강좌를 쓴다는게 한 페이지 쓰는데 보통 1시간 이상 걸린답니다. 보기에는 간단한 것 처럼 보여도....직접 쓰는 사람한테는 엄청난 시간과 노력이 필요하답니다. 예제를 하나 만들 때도 이렇게 생각해보고 저렇게도 생각해보고... 하고 하고 해서..... 올리곤 한답니다. 그렇다고 강좌 잘 썼다고 누가 상주는 것도 아니고 단지 자기만족과 부수적으로 실력향상 차원에서 하는 거죠. 그러니깐 딴 생각하지 마시고 집중해서 보시길 바라겠습니다. (헉.... 왠지 선생님이 된 느낌..-_- ;;; ) 제가 특강2 첫장에서 클래스를 정의해줄때 점(.) 을 붙여주지 않으면 그 뒷부분은 태그로 인식한다고 한 적이 있는데요..(기억 안 나시는 분은 빨랑 확인하고 오세요 -.-) 이번에는 그에 관한 것을 배우보도록 하겠습니다. 일단 예제를 보고 설명드리도록 하겠습니다.

<style type="text/css">
<!--
h1 b { color: red; }
p u { color: blue; font-family: 궁서체; }
-->
</style>
<body>
<h1>태그<b>매니</b>아</h1>
<p>스타일 시트 <u>특강 중</u> 입니다.</p>
</body>

위에 예제를 실행시켜봐서 음...뭔지 알겠다 하시는 분은 지금까지 스타일 시트를 잘 이해하고 있다고 볼 수 있습니다. 그렇다고 그렇지 안 으신 분들은 걱정할 필요가 없습니다. 왜냐면 제가 이제부터 설명을 드릴 테니까요.^^ 제가 class 정의할 때 점(.)을 찍어 주지 않으면 뒤에 오는 클래스명을 태그로 인식한다고 했었는데요....그건 좀 쉽게 설명드리기 위해서 그렇게 한거구요......위에 예제는 클래스하고는 아무런 상관이 없는 예제입니다. 위에 예제를 보시다시피 태그 2개를 같이 스타일 시트를 정의시켜 줄 경우에는 앞에 오는 태그 내에 있는 뒤에 오는 태그에 대한 스타일 정의를 해주는 거죠. 즉, <h1> 태그 내에 있는 <b> 태그 부분에 대해서 스타일이 적용되는 것입니다. 이해되시죠? 다시 설명하자면 두번째 라인의 스타일 시트 부분인 p u { color: blue; font-family: 궁서체; } ☜ 이 부분을 풀이해보면 <p>태그 내에 있는 <u>태그의 요소에 대해서 색은 파란색, 글자체는 궁서체로 하라는 말이죠. 어떠요? 이번에는 확실히 이해되시죠? 이 스타일 시트 방법을 사용하면 특정 태그안에 있는 특정 요소에 대해서 그 속성을 설정해 줄 수 있게죠^^ 그런데 아직까지도 모르겠다하시는 분은 없을 줄 아는데...혹시 계신다면 연습 많이 해보세요. 더 이상 쉽게 설명은 곤란합니다. -_- ;;;

이렇게 해서 스타일 시트 특강2는 마무리 되어지는 군요. ^^ 지금까지 뭘 배웠었는지 머리 속으로 한번씩 떠 올려보시고 ...... 어떤 철학자가 이런 말을 했죠. 인간은 망각의 동물이다. 한번만 보고 돌아선다면 오래 못가 잊어 먹게 되니...홈페이지 만들때 직접 사용해보기도 하고 자주 연습해보세요. 그럼 절대 잊는 일은 없을 겁니다. 그럼 즐거운 하루 되시고 여기서 마치도록 하겠습니다.


특강 3장부터는 각각의 스타일 시트의 속성에 대해서 알아보도록 하겠습니다. 먼저 글자에 대해산 스타일 시트의 속성에 대해서 알아볼 텐데요.... 글자에 대한 속성으로는 font-family , font-size , font-style , font-variant , text-transform , text-decoration 이 있습니다. 앞에 family 와 size 는 알겠는데... 나머지 뒤에 3개에 대해선 잘 모르겠다구요? ^^ 이미 알고 계시는 분도 있을 테지만, 스타일 시트 첨 하시는 분이라면 당연 모르겠죠. 그 궁금증을 이제부터 풀어드리죠 ^^

☞ font-family

글자...그리고 가족? 이란 뜻인데요...-_- ;;; 글자가족? 바로 글꼴을 의미하는 겁니다. 글꼴이 뭔지는 아시겠죠? ^^ 돋움체, 명조체, 궁서체, 바탕체.. 기타 등등을 글꼴이라고 하죠. 물론 영자체도 포함됩니다. 이 글꼴을 스타일 시트에서 조정해주는 속성이 font-family 이죠. 일단 예제를 하나 볼까요?^^

<style type="text/css">
<!--
h2 { font-family: 가는각진제목체, 솔체, 궁서체, 돋움체; }
b { font-family: verdana, helvetica, sans-self; }
-->
</style>
<body>
<h2> font-family 속성은 글자체를 결정해줍니다.</h2><br>
<b>tagmania since 1999 </b>
</body>

위에 예제를 실행시켜보면 여러분들의 컴퓨터 사정에 따라 글자체가 각각 다르게 나타날 텐데요....일반적으로 폰트의 경우 홈페이지를 제작하는 사람이 '가는각진제목체'를 이용해서 글자를 적어주었다면 그 홈페이지를 보는 방문객의 컴퓨터에 '가는각진제목체'라는 글자가 있어야 만히 볼 수가 있답니다. 만약 해당 홈페이지를 보는 방문객의 컴퓨터에 '가는각진제목체' 라는 글자체가 없다면 그 방문객에게는 기본글자체로 밖에 보이질 않는답니다. 즉, 원래 홈페이지 제작자가 의도했던 대로 홈페이지를 보여줄 수 없게 되는 거죠. 이러한 사고(?)를 방지하기 위해선 홈페이지를 제작할 때 모든 방문객들의 컴퓨터에 들어있는 공통된 글자체, 즉 돋움체, 궁서체, 바탕체, 굴림체, 신명조체 같은 기본글자체를 이용해서 만드는 것이 가장 좋은 방법입니다. 물론 화려하고 자신의 마음에 꼭 드는 폰트(글자체)가 있을 땐 해당 폰트를 사용하는 건 자기 맘이지만 일반적으로 방문객들이 가지고 있는 폰트(글자체) 가 아닌 폰트를 사용한다면 자기와 해당폰트를 가지고 있는 소수의 방문객들에게만 보여지게 되겠죠.
그런데....위에 예제의 경우 글자체를 하나만 적어준게 아니라 여러 개를 적어주었죠? 가는각진제목체, 솔체, 궁서체, 돋움체 ☜이렇게 4개의 글자체를 순서대로 적어주었는데...이렇게 적어준 이유는 만약 방문객의 컴퓨터에 '가는각진제목체' 가 없다면 그 다음 폰트인 '솔체'가 보여지게 되죠. 그런데 '솔체'도 없다고 하면 그 다음인 '궁서체'가 보여지게 되는 겁니다. 궁서체까지 없다면 최후로 돋움체가 보여지게 되겠죠. ^^ 돋움체는 기본폰트 이니깐 다 보여지게 되겠죠. ^^ 이때 주의 할 점이 될 수 있는 대로 마지막에는 기본폰트를 적어주라는 것입니다. 왠지는 아시겠죠? ^^
영자체도 위에 설명한 것과 마찬가지랍니다. 그리고 인라인 스타일을 사용할 때는 폰트의 이름에 작은 따옴표를 해줍니다. 이런식으로 해주죠. ☞ body { font-family: "센스체","돋움체","궁서체" } 또한 다른 속성과 함께 사용할 때는 font-family 속성을 가장 나중에 적어 줍니다. 익스플러워3.0에서는 font-family 속성이 가장 나중에 있지 않으면 이후의 모든 css 를 무시해버리기 때문이라고 하는데........그런데..아직도 익스플러워 3.0 사용하시는 분 계시나요? ^^
다음 페이지에서는 font-size 에 대해서 알아보도록 하겠습니다.

☞ font-size

이번에는 font-size 에 대해서 알아보도록 하겠습니다. 말 그대로 글자크기를 조절해주는 속성입니다. 일반적으로 태그를 사용해서는 글자크기를 최대로 해봤자 <font size="7"> 까지나 <H1> 까지밖에 표현을 못해 줍니다. 그러나 스타일 시트를 이용하면 글자크기를 얼마든지 사용자 맘대로 크게 하거나 작게 표현 할 수 있답니다.
우선 font-size 속성을 사용하는 경우 글자크기의 수치는 포인트(pt) , 픽셀(px) , 인치(in) , 센티미터(cm) 등이 있습니다. 이 중에서 여러분들이 쓰기 가장 편한 것을 골라 사용하시면 됩니다. 왜냐면 어떤 것을 쓰나 크기만 정확히 나타내어 주면 되는 거기 땜시... 핫핫 ^^> 단, 한가지만 골라서 그것만 계속 사용하시길.... 안 그러면 나중에 헤갈려여... 일반적으로 포인트(pt)나 픽셀(px)을 가장 많이 쓴답니다.(태그매니아에선 무조건 픽셀을 사용함-_-+) 이제 예제를 하나 봐볼까요? ^^

<style type="text/css">
<!--
p { font-size : 13px ; }
b { font-size : 13pt ; }
h1 { font-size : -1in ; }
u { font-size : -1cm ; }
-->
</style>
<body>
<p>일반적으로 픽셀(px)과 포인트(pt) 값이</p><br>
<b>비교적 정확하게 크기를 설정해줄 수 있습니다.</b><br>
<h1>안녕하세요? 인치(in)와 센티미터(cm)의 경우는 </h1><br>
<u>마이너스(-) 1값을 사용할 수 있답니다.</u>
</body>

예제를 확인해보셨나요? px과 pt 의 경우는 여러분들이 넣는 수치만큼 글자크기가 조절됩니다. (마이너스값은 적용되지 않음) 그리고 인치(in)와 센티미터(cm)의 경우 값을 1로 정해주어도 폰트의 크기가 엄청커지기 때문에 잘 사용되지 않습니다.
그리고 퍼센트(%) 와 키워드 방식의 단위가 있으나 이건 거의 사용되지 않는 답니다. 페센트 값의 경우 부모인자에 대한 그 페센테 값만큼 크기를 조절해 주는 방식이며..키워드 방식은 xxsmall , xsmall , small , medium , large , xlarge , xxlarge 등의 키워드를 이용해서 크기를 조절해주는 방식입니다. 이건 그렇게 중요한게 아니라서 예제는 생략하도록 하겠습니다

흠....속성 하나에 한 페이지씩 공간을 차지하네요 ^^ 설명하는 게 넘 더딘거 같아 좀더 스피드하게 설명드리도록 하겠습니다. 다음 페이지로 가시져.....
/^_^/______________________@ 내 휴지는 내가 굴린다....-_- ;;

☞ font-style , font-variant , font-weight

font-style 속성은 글자체의 스타일을 지정해주는 것으로서 normal , italic , oblique 값을 사용할 수 있습니다. 그런데 font-style 속성을 이용해보면 알겠지만 italic은 말 그대로 이탤릭체이고 oblique는 이탤릭체와 비스므레(^^)한 정도로 볼 수 있습니다 .
font-variant 의 경우는 단순히 보통의 텍스트를 작은 대문자 폰트를 이용해서 작은 대문자로 바꾸어 주는 것입니다. 예컨데 p { font-variant : small-caps } ☜이런식으로 사용할 수 있죠. ^^
font-weight 의 경우는 폰트의 굵기를 지정해주는 속성으로서 lighter , light , normal , bold ,bolder 값을 지정해 줄 수 있습니다.
예제를 봐 볼까요?

<style type="text/css">
<!--
body { font-style : italic ; }
p { font-variant : small-caps ; }
u { font-weight : bold ; }
-->
</style>
<body>
안녕하세요? 태그매니아 입니다.<br>
<p> tagmania ☜이건 소문자 였는데..대문자로 나오네요</p>
<u> TAGMANIA </u>
</body>

위의 예제를 실행시켜 보면 글자가 다 이탤릭체로 나오게 됩니다. 그리고 font-variant 속성이 적용된 부분(tagmania)은 글자가 소문자임에도 불구하고 대문자로 표현되서 나오게 됩니다. 그리고 font-weight 속성의 경우 bold 로 지정되었기 때문에 더 굵게 나오게 되는 거죠. 단, font-weight 속성의 경우 표현되는 글자체에 bold체가 있어야 합니다. 예컨데..arial 체의 경우 arial bold체가 있어야만히 표현이 된다는 거죠. 각각의 글자체에 bold 체가 없는 경우엔 font-weight 속성은 적용될 수가 없습니다. 주의하시길......근뎅....bold체가 있는지 없는지 어떻게 확인하냐구요? 그건 여러분들의 컴퓨터의 [시작메뉴] -> [ 설정] -> [제어판] -> [글꼴] 을 클릭해서 확인해보시면 될겁니다. 또한 font-weight 속성의 경우 100~900까지 숫자로 굵기를 조절해줄 수 있는데요....단, verdana체와 arial체에서만 적용이 되기 때문에 제한적이라고 할 수 있답니다.

☞ text-transform , text-decoration

text-transform 속성은 모든 글자를 대문자나 소문자로 바꿔준다거나 단어의 첫글자만 대문자로 출력해주는 기능을 합니다. (물론 영문자에만 효과가 있습니다.)
uppercase lowercase capitalize none
모든 글자를 대문자 변환 모든 글자를 소문자 변환 첫글자만 대문자로 변환 아무런 효과를 주지 않음

text-decoration 속성은 글자에 밑줄 , 윗줄 , 가운데 줄을 긋게하는 기능을 합니다. (영문이나 한글 모두 적용)

underline : 밑줄을 긋는 효과
overline : 윗줄을 긋는 효과
line-through : 가운데 줄을 긋는 효과
blink : 깜빡이게 하는 효과
none : 아무 효과도 없게 함


속성을 설명을 했으니 이제 예제를 보면서 실제로 어떻게 사용되는지 알아볼까요?

<style type="text/css">
<!--
h1 { font-size:30px; font-weight:bold; }
body { font-size:20px; }
.love { text-transform:lowercase; text-decoration:underline; }
.story { text-transform:uppercase; text-decoration:line-through; }
.kiss { text-transform:none; text-decroation:none; }
a { text-transform:none; text-decoration:none; }
-->
</style>
<body>
<h1>스타일 시트</h1>
<p class=love>TAGMANIA에서는 태그와 각종 자바스크립 예제를 제공하고 있습니다.</p>
<p class=story>style sheet 특강을 실시하고 있습니다.</p>
<a href="이건 연습"> 링크인디....밑줄이 없네...</a>
</body>

예제를 실행시켜 보니 바로 알겠죠? ^^ 잘 모르겠다고 하시는 분들은 소스를 주의깊게 째려보신 다음에 위에 속성 설명한 거하고 비교하면서 하나씩 봐보세요. 그러면 제가 굳이 설명 안 하더라도 다 아실 수 있을 겁니다.
여기까지 읽어주신 거 고맙고요...여기서 세번째 특강은 마무리 짓도록 하죠. ^^


벌써 네번째 특강인가요? ^^ 하루에 특강 하나씩 만들다 보니...벌써 업데이트 준비한지 나흘이 지났군요. 헉..-_- ;; 공부도 해야 되는디....... 공부 이야기가 나왔으니간 하는 말인데......요즘 대학에서의 학문의 의미는 단지 직업을 갖기 위한 하나의 수단으로 밖에 보여지질 않네요..... 진정한 학문으로서 탐구는 없고..... 조금이라도 좋은 먹고 살 자리를 갖기 위한 도구(?)라고 할 수 있을 까요? -_- ;;; 가끔씩은 대학에 가기위해 발버둥(?)을 치고 있는 고3생들을 보면 안타깝다는 생각이 들기도 하구........ 왜 그렇게 대학에 올려고 하는지.....--;;; 하긴 나도 그땐 그랬으니깐..... 오잉? o.0 ! 근뎅 무슨 이야기 하다가 옆길로 빠졌는지....핫핫^^> 스타일 시트 네번째 특강 시작하도록 하죠 ^^

☞ word-spacing , letter-spacing

word-spacing 속성은 단어사이의 여백을 조절해주는 기능을 하고, letter-spacing 속성은 글자사이의 여백을 조절해주는 기능을 합니다. 넘 간단한 거라 더 이상 말이 필요 없습니다. 예제 하나 보고 담으로 넘어가겠습니다.

<style type="text/css">
<!--
h1 { word-spacing:5px; }
h2 { letter-spacing:7px; }
-->
</style>
<body>
태그매니아 스타일 시트
<h1>word-spacing 속성은 단어사이의 여백 조정</h1>
<h2>letter-spacing 속성은 글자사이의 여백 조정 </h2>
</body>

여기서 속성값의 수치단위는 픽셀, 포인트, 센치, 인치 등을 사용할 수 있습니다.

☞ line-height

직역해보면....선-높이가 되죠. 말 그대로 줄과 줄 사이의 수직 간격을 조절해주는 속성입니다. 이걸 뭐라그러더라???? 자간이라고 하나? 줄간? -_-;;; 갑자기 생각이 나지 않네....... 하여간 줄 간격 조절해주는 것이라고만 알고 있으면 됩니다. 역시 예제하나 보고 설명 드리겠습니다.

<style type="text/css">
<!--
p { font-size:13px; line-height:2; }
h3 { font-size:20px; line-height:200%; }
.love { font-size:12px; line-height:10px; }
-->
</style>
<body>
<h3> LCD와 PDP의 인기</h3><br>
<p> 디스플레이의 경우 보다 부피가 적은 모니터와 선명하고 안정적인 화면이 동시에 요구되고 있어 LCD와 PDP제품의 개발 및 줄시가 증가하고 있다. LCD모니터는 일본시장에서 이미 테스크탑 모니터의 50%이상을 차지하는 등 빠른 성장세를 나타내고 있으며 가격도 지속적으로 하락하고 있어 국내에서도 올 하반기를 기점으로 시장점유율이 큰 폭으로 상승할 것으로 전망된다.</p>
<p class=love>PDP는 현재까지 40인치 이상의 대형화면을 표현하는 데 가장 적합한 매체로 알려져 대형화면을 요구하는 소비자를 대상으로 판매가 확대되고 있다. PDP는 기존 모니터와 비교해 처박형이면서 완전평면으로 대형화면표시가 가능하며, 시야각이 160도 이상으로 넓어 차세대 디스플레이로 각광받고 있다....</p>
</body>

자~ 위에 예제를 태그연습장에서 실행시켜 보면 재미있는 결과가 나타날 것이다. <h3>태그에 적용된 스타일 시트의 경우 글자크기가 20px임에도 불구하고 line-height를 200%로 잡아주었기 때문에 그 두배인 40px 크기로 브라우져에 표현된죠. 또한 <p>태그에 적용된 스타일 시트의 경우 글자크기13px에 line-height를 수치단위 없이 2로만 적어 주었을 경우 마찬가지고 앞의 글자크기에 2배가 곱해지기 때문에 line-height의 값은 26px이 되는 것입니다. 또한 love class를 적용시킨 부분의 경우 오히려 앞의 글자크기12px보다 line-height의 값이 작기 때문에 예제에서 보시다 시피 줄끼리 겹쳐지는 상황이 나타나게 됩니다. 어때요? 이해되십니까? ^^ 아마 이 부분에서 막 헤갈릴려고 하시는 분들이 계실지도 모르나.....모를 경우에는 예제의 수치를 바꿔가면서 연습해보세요. 그럼 언젠가는 이해가 되실 겁니다. ^^ (헉..넘 무책임한 운영자 -_-;;;) 다음 페이지로 넘어가져^^


☞ text-align , text-indent

text-align 속성은 뭘 까요? 그냥 척 보면 알겠죠.... 정렬해주는 기능이죠. 뭘 정렬해주냐고요? 글자뿐만 아니라 이 속성에 포함된 요소의 정렬방식을 결정해주는 기능을 합니다. text-indent속성은 들여쓰기의 길이를 정해주는 기능을 합니다. 들여쓰기가 뭔지는 아시겠죠? 문단의 첫 부분을 다른 행에 비해 조금씩 넣어주는 것을 말하죠. 자...그럼 예제를 보겠습니다.

<style type="text/css">
<!--
p { font-size:13px; color:blue; text-align:right; }
.love { text-indent:5%; text-align:left; }
-->
</style>
<body>
<p> 디스플레이의 경우 보다 부피가 적은 모니터와 선명하고 안정적인 화면이 동시에 요구되고 있어 LCD와 PDP제품의 개발 및 줄시가 증가하고 있다. LCD모니터는 일본시장에서 이미 테스크탑 모니터의 50%이상을 차지하는 등 빠른 성장세를 나타내고 있으며 가격도 지속적으로 하락하고 있어 국내에서도 올 하반기를 기점으로 시장점유율이 큰 폭으로 상승할 것으로 전망된다.</p>
<p class=love>PDP는 현재까지 40인치 이상의 대형화면을 표현하는 데 가장 적합한 매체로 알려져 대형화면을 요구하는 소비자를 대상으로 판매가 확대되고 있다. PDP는 기존 모니터와 비교해 처박형이면서 완전평면으로 대형화면표시가 가능하며, 시야각이 160도 이상으로 넓어 차세대 디스플레이로 각광받고 있다....</p>
</body>

어때요? 첫번째 문단의 경우 우측정렬이 되져...그리고 두번째 문단은 좌측정렬이 되면서 문단 첫머리가 지정해준 만큼 들여쓰기가 되구요.....

☞ margin-top , margin-left , margin-bottom , margin-right

마진(margin).....이란..? 설명하자면 여백을 조절하는 속성이라고 할 까요? 제가 말솜씨가 없어서 그런지 ... 아님 원래 우리말로 표현이 어려운 건지.....더 이상 어떻게 설명 드리는 게 좀 힘 드네요..^^ 이건 예제를 보면서 익히면 금방 이해하실 수 있을 겁니다. 예제를 보기 전에 참고적으로 , margin속성의 수치단위는 px , pt , in ,cm를 사용할 수 있고요... 마이너스(-)값도 사용할 수 있습니다. 퍼센트 값을 사용할 수 도 있는데 그러면 브라우져에 따라 유동적이기 때문에 원래 원하던 표현이 안될 수도 있답니다. margin 속성은 잘 만 사용하면 정말 멋진 웹페이지를 만들 수 있답니다. 이제 예제를 볼까요?

<style type="text/css">
<!--
body { font-family: 돋움체; }
.love { font-size : 130px; color:red; font-weight:bold; margin-bottom:0px; }
.story { margin-top:-110px; margin-left:87px; margin-bottom:0px; font-size:30px; color: blue; }
.kiss { font-size:15px; margin-left:50px; margin-right:50px; text-align:justify; }
-->
</style>
<body>
<p class=love>태그매니아</p>
<p class=story>태그를 좋아하는 사람들의 배움터</p>
<p class=kiss>태그를 좋아하는 사람들의 모임입니다. 태그를 좋아하는 사람들의 홈페이지입니다. 태그를 좋아하는 사람들의 장소입니다. 태그를 좋아하는 사람들의 터입니다. 태그를 좋아하는 사람들의 공간입니다. 태그를 좋아하는 사람들의 클럽입니다. 태그를 좋아하는 사람들의 지대입니다. </p>
</body>

어때요? HTML로는 도저히 표현할 수 없는 효과를 낼 수 있죠? margin-top은 상단여백을 조정해주고 , left는 왼쪽여백 , right 는 오른쪽여백 , bottom은 당연 아래쪽 여백을 조절해주는 속성이죠. 멋지죠? 예제에서 봤듯이 margin속성을 이용하면 글자끼리도 겹치게 할 수 도 있고 해당 요소를 부라우져의 경계선에서 반쯤 걸쳐있게 할 수 도 있습니다. 엄청난 기능이죠.^^ 연습 많이 해서 완전히 자기 것으로 만들면 더욱 더 좋겠죠?
margin속성에 대해선 이 정도에서 마치도록 하고 다음 페이지로 넘어가도록 하겠습니다.


☞ padding-top , padding-left , paddding-bottom , padding-right

앞페이지에서 배운 margin하곤 비슷한 기능인데요...역시 여백조정 속성입니다. 그러나 padding속성은 margin속성에 비해 글자나 요소간에 겹치게 할 수가 없답니다. margin보다는 그리 많이 사용되지 않는 듯 하네요..^^

☞ border-width , border-color , border-style

border속성은 해당요소의 테두리의 스타일을 지정하는 기능을 합니다. margin보다는 좁은 영역을 가지는 데요.....(이 말을 이해하실지....ㅜ.- ) border-width 속성은 테두리의 굵기를 지정해주고, border-color 속성은 색상을 , border-style 속성은 스타일을 지정해주는 기능을 합니다. 예제 하나 볼까요? ^^

<style type="text/css">
<!--
body { margin-left:10%; color:red; font-size:13px; font-weight:bold; font-family:arial; }
h1 { font-size:30px; }
.love { border-width:10px; border-style: inset; border-color:yellow; }
.story { border-width:20px; border-style: double; border-color:skyblue; }
.kiss { border-width:30px; border-style: outset; border-color:black; }
-->
</style>
<body>
<h1>태그매니아</h1>
<p class=love> i love you</p>
<p class=story> i love you</p>
<p class=kiss> i love you</p>
</body>

border-width 의 값이 커질 수록 테두리의 두께가 두꺼워지고 border-style의 경우 예제에서 보여진 inset , double , outset 뿐만 아니라 solid , dotted , dashed , ridge 등이 있습니다. 또한 border-color의 경우 그 border-style에 따라 그 색상이 잘 나타날 때도 있고 그렇지 않는 때도 있다는 것을 유의하시길 바랍니다.
현재 시각 새벽 02시 20분이네요.....잠도 오고.....피곤도 하고.....낼 학교도 일찍 가봐야 되는데..... 이 말은 즉...." 여기서 네번째 특강 마치도록 하겠습니다." ☜이 말을 하고 싶다는 말이져....^^>핫핫~ 여기서 마치도록 하겠습니다. 마지막으로 한 마디...『 연습 많이 하세요 』

이번 강좌에서는 컬러와 관련된 스타일 시트에 대해서 알아보도록 하겠습니다. 컬러와 관련된 스타일 시트 속성으로는 color, background-color, background-image, background-repeat, background-attachment, background-position, background 등이 있습니다. 모두 다 색상, 배경색과 배경이미지에 대한 것들인데요....그렇게 어려운 것은 없을 테니 설명 잘 들으시기 바라겠습니다. ^^

☞ color , background-color

말 그대로 색상과 배경색을 지정해주는 속성입니다. 사용방법은 아래와 같습니다.

body { color:red; background-color:#FFFFF; }

더 이상 설명이 필요 없겠죠? ^^ 아...그리고 색상을 지정해줄 때 위에 예제에서와 같이 두 가지 방법이 있는데요..첫째는 영문색상명(red , blud , yellow , black ...등등)을 적어주는 것이고 두 번째는 RGB색상코드를 적어주는 방법입니다. RGB색상코드에 대해서 알고싶으신 분은 ☞여기를 클릭해보시면 알 수 있습니다. 간단한 예제 하나 보고 넘어가도록 하죠 ^^

<style type="text/css">
<!--
body { color : darkblue ; background-color : #CC99FF ; font-weight:bold; }
-->
</style>
<body>
<p>내가 당신을 얼마만큼 사랑하는지 당신은 알지 못합니다.
이른 아침, 감은 눈을 억지스레 떠야하는 피곤한 마음 속에도
나른함 속에 파묻힌 체 허덕이는 오후의 앳된 심정속에도
당신의 그 사랑스러운 모습은 담겨 있습니다. </p>
</body>

☞ background-image , background-repeat

background-image 속성은 말 안 해도 알고 계시겠죠? ^^ 그쵸. 배경이미지를 지정해주는 속성이죠. background-repeat 속성은, 일반적으로 우리가 HTML를 사용해서 배경이미지를 넣으면 웹페이지의 화면보다 배경이미지가 작은 경우 배경이미지가 화면에 좌우로 반복이 되어서 채워지게 됩니다. 이걸 전문용어로 패턴이라고 하는데요..이러한 패턴을 조절해주는 속성입니다. 조절하기에 따라 한 방향으로만 패턴 되도록 하게 할 수 도 있으며 아예 패턴없이 표현할 수도 있습니다.
background-image 속성의 사용방법은 다음과 같습니다.

b { background-image: url(http://tagmania.net/img/filter1.gif) ;}

background-repeat 속성은 네가지의 값을 정해줄 수 있는데요.....다음과 같습니다.

no-repeat : 배경이미지가 반복이 안되게 합니다.
repeat : 모든 방향으로 반복되게 합니다.
repeat-x : x방향(가로)으로만 반복되게 합니다.
repeat-y : y방향(세로)으로만 반복되게 합니다.

즉 , background-repeat : repeat-x ☜이런 식으로 값을 넣어줄 수 있습니다.
지면 관계상 예제는 다음페이지에서 보도록 하겠습니다. 넘어 가죠? ^^

background-images 와 background-repeat 에 대한 예제를 보도록 하겠습니다.

<style type="text/css">
<!--
body { background-image : url(http://tagmania.net/img/jang.jpg) ; background-repeat : repeat-y ; }
.love { font-size : 13px; color : green; font-family : 돋움체; }
-->
</style>
<body>
<p class=love>배경이미지가 세로방향(y방향)으로만 반복이 되죠. ^^ background-repeat의 속성값을 바꿔가면서 연습을 많이 해보세요. ^^ 그럼 이해가 더욱 더 빠를 겁니다. </p>
</body>

☞ background-attachment

이 속성은 HTML에서의 bgproperties="fixed" 와 같은 기능을 하는 속성을 합니다. 즉, 여러분들이 웹서핑을 하다보면 어떤 곳에서는 스크롤바를 내려도 배경이미지는 고정되어 있고 안에 내용만 스크롤바에 따라 움직이는 것을 보셨을 겁니다. 그건 대부분 HTML을 이용한 건데요....스타일 시트를 이용해서도 같은 효과를 낼 수 있습니다.

<style>
body { color : green ; font-size : 13px; background-image : url(http://tagmania.net/img/jjh.jpg); background-attachment : fixed; }
</style>
<body>
<p>내가 당신을 얼마만큼 사랑하는지 <br>당신은 알지 못합니다. <br>
이른 아침, <br>감은 눈을 억지스레 떠야하는 <br>피곤한 마음 속에도 <br>
나른함 속에 파묻힌 체 <br>허덕이는 <br>오후의 앳된 심정속에도 <br>
당신의 <br>그 사랑스러운 <br>모습은 담겨 있습니다. </p>

<p>내가 당신을 <br>얼마만큼 사랑하는지<br> 당신은 알지 못합니다. <br>
층층 계단을 오르내리며 <br>느껴지는<br> 정리할 수 없는 <br>
감정의 물결속에도 <br>십년이 훨씬 넘은 <br>
그래서 이제는<br> 삐걱대기까지 하는 <br>낡은 피아노 <br>
그 앞에서 지친 <br>목소리로 <br>노래를 하는 내눈 속에도 <br>
당신의 그 <br>사랑스러운 마음은 <br>담겨 있습니다. </p>
</body>

어때요? HTML을 사용한 경우와 같은 효과가 나올 겁니다. 직접 HTML을 사용하지 못하는 경우 스타일 시트를 사용하면 되겠죠? ^^


☞ background-position

배경 이미지의 위치를 조절해주는 속성입니다. 속성값은 키워드식 , 픽셀방식 , 퍼센트(%) 방식이 있습니다.

키워드 방식 body { background-position: top left; }
픽셀방식 body { background-position: 40px 50px }
퍼센트 방식 body { background-position: 40% 50% }

키워드 방식의 경우 top , bottom , left , right , center 등을 사용할 수 있다. 위에 보기처럼 top left 를 사용한 경우 브라우져 상단 왼쪽에 배경이미지를 위치시키는 것을 의미한다. 가운데 쉼표(,)가 없다는 것에 주의 하자. 픽셀과 퍼센트방식은 브라우저의 왼쪽 상단 원점으로부터 해당 수치만큼 x측 y측으로 위치를 지정해주는 것이다.

<style type="text/css">
<!--
body { background-image: url(http://tagmania.net/img/gil2.gif); background-repeat: no-repeat; background-position: bottom right ; }
-->
</style>
<body>
어때요? 길동이 아저씨네요^^<br>
지금 사용한 방식은 키워드 방식입니다.<br>
여러분들이 픽셀방식과 퍼센트 방식으로 <br>
바꿔가면서 연습해보세요.
</body>

위의 예제의 경우 배경이미지를 no-repeat 로 설정해준 다음 background-poition을 키워드 방식으로 해준 것입니다. 여러분들이 픽셀방식과 퍼센트 방식으로 바꿔 가면서 연습을 해보세요. 제가 백번을 말해도 한번 직접 해보는 것이 더 이해가 빠르답니다.

☞ background

지금까지 background 에 대한 속성들을 배워왔습니다.. color , image , repeat , position 을 배웠는데....각각의 속성을 적어줄때 background ☜이 단어를 여러번 써야 하는 불편함이 있습니다.(타수도 잘 안 나오는데..영타로 꼬박꼬박 칠려고 하니 짜증나죠^^) 다음과 같이 하면 단 한번만 쓰고 각각의 속성을 표현해 줄 수 있습니다.

body { background : url (이미지주소) 30% 50% repeat-x fixed white }

background 를 맨 처음에 한번 적어준 다음 각각의 속성값을 적어주면 되죠.^^ 위에 속성들의 순서를 보면 처음에 이미지주소 , 이미지 위치 , 이미지 반복 , 배경이미지고정 , 배경색 이 되겠죠?^^
어때요? 쉽죠? ^^

이번 장에서는 스타일 시트 위치지정과 레이어에 대해서 알아보겠다.

☞ position , left , top

스타일 시트의 요소의 위치를 조절해주는 속성이다.

h2 { left: 100px; top:40px; }

대충 이렇게 사용됩니다. position 속성의 경우 absolute(절대적위치)와 relative(상대적위치)로 값을 지정해줄 수 있습니다. 어떤 말인지 대충 감이 오죠? ^^ 브라우저에서 해당 요소를 표현해줄때 위치를 브라우저의 크기에 따라 상대적으로 해줄 것인가 아니면 브라우저의 크기에 상관없이 항상 고정된 부분에 위치시켜 줄 것인가를 결정해주는 거죠.
left , top의 경우 직접적으로 위치를 적어 주는 속성입니다. left : 50px의 경우 브라우저의 왼쪽으로부터 우측으로 50px 떨어진 곳에... top : 60px의 경우 브라우저 상단에서부터 아래쪽으로 60px 부분에 위치시키란 의미죠. 아시겠죠? ^^

<style type="text/css">
<!--
body { font-family : 돋움체; }
h1 { color : yellow; font-size : 70px; }
.love { left : 100px; top : 43px; }
.story { positon : relative; left : 40px; top : 10px; color : red; }
-->
</style>
<body>
<h1> 태그매니아 스타일 시트 특강</h1>
<div class=love> 태그매니아 홈페이지 제 4차 전면 사이트 개편과 더불어 <span class=story>스타일 시트 특강을 마련 하게 되었다. </span>많은 도움이 됬으면 한다.</div>
</body>

☞ width , height

position 과 같이 사용되며 요소의 넓이와 높이를 조절해서 전체적인 레이아웃을 조절하는 역할을 합니다. width와 height 속성은 다른 크기 지정 속성과 같은 단위(px , pt , cm ,in)를 사용합니다.

☞ z-index

레이어 효과를 사용할 때 레이어의 층의 순서를 결정해주는 속성입니다. z-index 값이 작을수록 아래 층을 의미합니다. 간단한 예제를 볼까요?

<style type="text/css">
<!--
body { font-size : 23px; }
.love { font-color : green; z-index : 1; left : 100px; top : 150px; }
.story { font-color : orange; z-index : 3; positon : absoluet; left : 150px; top : 100px; }
-->
</style>
<body>
<div class=love> 아래층 래이어죠</div>
<div class=story>위층 레이어 입니다.</div>
</body>

기본적인 스타일 시트 강좌는 여기서 마치도록 하겠습니다.

특강6장 까지는 스타일 시트의 원리 및 사용방법 , 각 속성에 대해서 알아보았습니다. 지금부터는 웹에서 주로 사용되는 스타일 시트에 대해서 알아보도록 하겠습니다.

☞ 밑줄 없애기 & 앵커 가상 클래스 효과

먼저 우리가 글자에 하이퍼링크를 설정해주면 글자가 파란색으로 변하면서 밑줄이 쫙~ 생기죠... 이걸 없에는 방법이 있습니다. 물론 스타일시트를 이용해서 없앨 수 있습니다. 게다가 앵커 가상 클래스까지 첨부시키면 더욱 멋져 보이죠. 이걸 스타일 시트라인에 넣어보세요 a { text-decoration : none; color : black; } 그럼 밑줄이 없어 질겁니다. 자~~ 보세요.....

<style type='text/css'>
<!--
body { font-family: "돋움", "돋움체", "Arial";}
A:link { text-decoration:none; color: 00448B;}
A:visited { text-decoration:none; color: green;}
A:active { text-decoration:underline; color:red ;}
A:hover {color: black; text-decoration:underline;}
-->
</style>
<body>
<a href="3"><h2>밑줄 없애는 것과 앵커 가상 클래스 효과</h2></a>
어때요? 잘 되죠? ^^
</body>

설명을 드리자면 text-decoration 속성을 이용해서 처음 link 부분에서는 none 값을 주어서 밑줄을 없애는 거죠. 다른 visited 부분에서도 밑줄을 없애주고 active와 hover 부분에서는 underline 를 주어서 마우스가 링크 위에 가면 밑줄이 생기게 하는 거죠. 또한 색상도 마찬가지로 각각 다른 게 설정을 해주면 마우스를 대면 색상이 변하게 됩니다. 좋은 틱이죠? ^^ 여러분들 홈페이지에 맞게 고쳐서 사용해보세요. ^^

☞ 배경이미지를 하나만 나타나게 하기 (패턴 없애기)

HTML을 이용해서 배경이미지를 넣으면 배경이미지가 반복이 되어 화면에 가득차게 됩니다. 원래 패턴을 위한 배경이미지라면 몰라도 그렇지 않은 배경이미지는 보기에 별로 좋지 않을 겁니다. 이럴 경우를 해결하기 위해 배경이미지를 자신이 원하는 위치에 딱 하나만 넣을 수 있는 방법에 대해서 알아보겠습니다.

<style type="text/css">
<!--
BODY {background: url(http://tagmania.net/images/5.jpg); background-repeat:no-repeat;
background-position:50% 50%}
-->
</style>
<body>
<font color="green" size="2" face="돋움">
어때요? 근사하죠? ^^ 브라우저의 크기를 변하게 해도 <br>퍼센트를 지정이 되었기 때문에 <br>항상 정 가운데 배경이미지가 놓이게 되죠 ^^
</font>
</body>

위에 예제는 스타일 시트의 background-repeat 와 background-position 속성을 이용해서 표현을 한 거죠. 지금까지 특강을 잘 들어 오신 분이라면 충분히 이해하실 수 있을 겁니다.

이번 강좌에서는 실제로 스타일 시트가 어떻게 사용되는 가에 대해서 간단하게나마 알아볼 수 있도록 하겠습니다.개인 홈페이지의 경우 그렇게 자주 스타일 시트가 사용되지는 않습니다. 그러나 포털 사이트나 커뮤니티 등 개인이 아닌 회사가 직접 운영하는 사이트의 경우 여러 웹 전문가들이 만들기 때문에 스타일 시트가 많이 사용되죠. 스타일 시트만 해도 한 페이지 분량정도 되는 사이트도 있답니다.(그렇지 않은 사이트도 많음) 이럴 경우 따로 css 파일을 만들어서 링크를 시켜야 겠죠. ^^ 예제로 하나 볼까요? ^^


<style type="text/css">
<!--
.base {font-family: "굴림"; font-size: 9pt;}
.baseup {font-family: "굴림"; font-size: 9pt;line-height:100%;}
.header {font-family: "굴림"; font-size: 10pt; font-weight: bold}
.header1 {font-family: "굴림"; font-size: 10pt; color:#4770AD; font-weight: bold;}
body {margin-top: 0px; margin-left: 16px}
a {font-family: "굴림"; font-size: 9pt; color:#333399; text-decoration: none}
.base1 {font-family: "Verdana", "Arial", "Helvetica", "sans-serif"; font-size: 8pt; }
.text1 {font-family: "굴림", "굴림체", "돋움", "돋움체"; font-size: 9pt; text-decoration: none; color: #A4C7EA}
.text2 {font-family: "Verdana", "Arial", "Helvetica", "sans-serif"; font-size: 8pt; text-decoration: none; color: #A4C7EA }
.text3 {font-family: "Arial", "Helvetica", "sans-serif"; font-size: 8pt; text-decoration: none; color: #A4C7EA; font-weight: bold}
a:hover {font-family: "굴림"; font-size: 9pt; background-color:none; color:DarkBlue; text-decoration:underline;}
a.header1:hover {font-family: "굴림"; font-size: 10pt; background-color:none; color:DarkBlue; text-decoration:underline; font-weight: bold;}
a.text1:hover {font-family: "굴림", "굴림체", "돋움", "돋움체"; font-size: 9pt; text-decoration: underline; color: #A4C7EA}
a.text2:hover {font-family: "Verdana", "Arial", "Helvetica", "sans-serif"; font-size: 8pt; text-decoration: underline; color: #A4C7EA }
//-->
</style>

사이버 방송영상 정보센타 홈페이지의 메인페이지 스타일 시트인데요....여기의 경우 주로 글자에 대한 색상과 글꼴 , 가상앵커클래스 효과를 사용한 것이죠. 흠...-_-;; 굉장히 복잡하게 보여도.... 자세히 보면 간단하죠. ^^
예제를 하나 더 본다면....

<style TYPE="text/css">
<!--
A:active {text-decoration:none;color:black}
TD, TH {font-size:9pt}
font {font-size:9pt}
.black {text-decoration:none;color:black}
.none {text-decoration:none}
.blue {color:blue}
.red {color:red}
.line {line-height:140%}
.line1 {text-decoration:none;color:black}
-->
</style>

위의 예제의 경우 어느 pc통신업체 홈페이지 스타일 시트입니다. 앵커가상클래스효과와 글자색상 등에 대해서 정의한 것이네요. ^^ 처음 것보단 간단하지만 내용은 거의 비슷하다고 할 수 있겠네요.
이렇듯 스타일 시트는 웹의 여러 부분에서 사용되고 있습니다. 여러분들도 이제 스타일 시트를 배웠으니 홈페이지 제작하는데 반드시 사용해보시기 바랍니다. 아마 홈페이지 제작하는데 많은 도움이 될겁니다.

지금까지 스타일 시트 강좌 들어 주신 거 감사 드리고요.... 시간에 쫒겨 강좌를 쓰다 보니 자세히 설명 못드리고 대충 넘어가는 부분이 많이 있을 겁니다.. 언제나 홈페이지만 잡고 살수 있는 것이 아니기 땜시.... 열심히 써볼려고 했었는데...잘 안된거 같아...좀 그렇네요. ^^> 하여간 지금까지 봐주신거 감사드리고 앞으로도 열심히 하는 태그매니아 될 수 있도록 노력하겠습니다.

'Web(웹) Study > HTML & CSS' 카테고리의 다른 글

css 테두리관련 스타일  (0) 2007.11.03
border-collapse: collapse  (0) 2007.11.03
textarea  (0) 2007.11.03
스타일시트로 말줄임 표시  (0) 2007.11.03
word-spacing 과 letter-spacing  (0) 2007.11.03

스타일 시트를 이용한 색 사용하기

글이 긴 사이트를 보면 글자 간격이나 줄간격이 다닥다닥 붙어서 답답했던적이 한번쯤은 있었을 것입니다.
이럴때 사용할수 있는 스타일 시트에 대해 공부해 볼까요...

word-spacing 과 letter-spacing

word-spacing은 단어사이의 여백을 설정해 주는 속성이고, letter-spacing은 글자 사이의 여백을 설정해 주는 속성입니다. 이 속성의 값은 font-size와 마찬가지로 픽셀이나 포인트, 인치, 센티미터등으로 지정이 가능합니다.

'Web(웹) Study > HTML & CSS' 카테고리의 다른 글

css 테두리관련 스타일  (0) 2007.11.03
border-collapse: collapse  (0) 2007.11.03
textarea  (0) 2007.11.03
스타일시트로 말줄임 표시  (0) 2007.11.03
스타일 시트(Style Sheets)  (0) 2007.11.03
다시 처음부터 시작한다...

그 동안의 내 블로그가 이상하게되 한글 지원이 됬다가 않 됬다가....ㅡ,.ㅡ;;

결국 싹~~ 밀고... 서버 이전도 하고...

이참에 아주 규격에 마춰서 데이터 구분도 알맞게 해서...

다시 시작 해보려는 참이담... ㅎㅎ

원래는 내년 부터 다시 하려고 했지만... ㅋㅋ

지금 부터라도... 내가 수집한 자료를 한곳에 모아 놓을 곳이 없어서...

자... 회사 일때문에 바쁘기도 하지만... 틈틈히...

시간내서 블로그를 다시 활성화 시켜 봐야지... 아자아자!! 화이팅!!

일일 방문자 500명을 향하여.... 다시 새롭게 출~~ 발~~ ㅎㅎ
사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지 사용자 삽입 이미지

개발 기간 : 6개월
참여 인원 : 혼자

학과 홈페이지로써 그누보드를 기본으로 하여 사물함관리 시스템 및 랜카드 사용신청서 등록 관리 시스템 개발, 학사연동
사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지

개발 기간 : 4개월
참여 인원 : 혼자

강의 관련 홈페이지로 강의 과목 등록시 자동으로 매 학기마다 게시판이 자동으로 변경 되도록 처리.
사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지

제작 기간 : 2개월
참여 인원 : 혼자
개발 언어 : PHP ,Mysql

제로보드를 이용하여 만든 홈페이지.
내부 신청곡 시스템 별도 적용및 MP3스트리밍, 동영상 스트리밍 서비스 가능하도록 기능추가 작업
사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지

개발 기간 : 4개월
참여 인원 : 혼자
개발 언어 : PHP, Mysql

게시판에서 부터 내부 인트라넷 구성 전부 원웅산업 전용으로 별도 개발
사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지 사용자 삽입 이미지

제작 기간 : 8개월
참여 부분 : 디자인 에서 메뉴 구성 모두다...
운영 기간 : 중 3년 ~ 대학 2년

중 3때 제작해서 직접 운영해오면서 최종 리뉴얼 버전.
제로보드와 웹 폰트를 이용한 홈페이지 제작.

getchar()

: Enter Key를 누를 때까지 버퍼에 data를 입력받아 맨 앞 data 1문자를 읽어온다.


- 버퍼에서 읽어온 문자 1개를 특정 변수에 저장하는 방식은 다음과 같다.

   a = getchar();


- getchar는 scanf와 비슷하지만 차이가 있다.

   scanf는 다양한 타입과 서식을 지원해, 프로그래머가 원하는 방식으로 입력받을 수 있는 것에 반해 getchar는 오직 문자 1개만 입력받을 수 있다.


- getchar는 'Enter'키의 입력도 하나의 문자로 간주한다.

   때문에 *.exe 파일을 실행했을 때 출력문을 채 보기도 전에 프로그램이 종료되는 현상을 코드의 마지막에 getchar()를 넣음으로써 막을 수도 있다.


- getchar와 scanf는 버퍼에 저장된 것을 읽어오기 때문에 주의해야한다.

   여러 번에 걸쳐서 getchar나 scanf를 사용할 경우, 버퍼에 누락된 'Enter'키 같은 data를 읽어올 수 있다. 따라서 여러 번에 걸쳐서 getchar나 scanf를 사용할 때는 'fflush(stdin)' 명령어를 이용하여 버퍼를 비워주어야 한다.

'공부 해 Boa요. > C & C++' 카테고리의 다른 글

OpenCV(Open Computer Vision Library) 관련  (0) 2008.01.18
  • 이 Server는, Client로 접속했을 때 입력한 값을 그대로 돌려주는 Echo Server이다.
  • vi editor를 이용해서 아래의 source code를 입력한 후 Shift + Z + Z로 저장한다.
  • gcc를 이용하여 컴파일 한 후 Client보다 먼저 실행한다.
  • 이 때 파일명 뒤에 port number를 입력해주게 되는데, 이 port number는 Client와 같아야 한다.
  •     ex) vi echo_server.c
  •           gcc echo_server.c -o echo_server
  •           ./echo_server 50000

 

아래는 echo_server.c에 입력할 souce code이다.


 

#include<sys/wait.h>
#include<signal.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define BUF_LEN 128


void clean();


int main(int argc, char* argv[]) {
     struct sockaddr_in server_addr, client_addr;
     int master_skt, slave_skt;
     int len, len_out;
    int port;
     char buf[BUF_LEN+1];

    if(argc != 3){

          printf("사용법 : %s port\n", argv[0]);

          return -1;

     }

     port = atoi(argv[2]);

     if(master_skt = socket(PF_INET, SOCK_STREAM, 0) < 0){
          printf("서버 소켓 생성 실패\n");
          return -1;
     }

     bzero((char *)&server_addr, sizeof(server_addr));
     server_addr.sin_family = AF_INET;
     server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
     server_addr.sin_port = htons(port);

    if(bind(master_skt, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){
          printf("서버 주소 연결 실패\n");

          return -1;
     }

     listen(master_skt, 5);
     signal(SIGCHLD, clean);

    while(1) {
          printf("Server : Waiting to accept request.\n");
          len = sizeof(client_addr);

          if(slave_skt = accept(master_skt, (struct sockaddr *)&client_addr, &len) < 0){
               printf("Fail to accept the server\n");
              return -1;
          }


          printf("Server : Client connected.\n");

          switch(fork()) {
               case 0 :
                    close(master_skt);
                    len_out = read(slave_skt, buf, sizeof(buf));
                    write(slave_skt, buf, len_out);
                    exit();

               case -1 :

                    exit();

               default :

                    close(slave_skt);
          }
     }
}

void clean(){
     union wait status;

    while(wait3(&status, WNOHANG, (struct rusage *)0) >= 0){ }
}

'공부 해 Boa요. > Network' 카테고리의 다른 글

Client  (0) 2006.10.15
Raw Socket  (0) 2006.09.29
Consol Echo Client  (0) 2006.09.27
실전 네트웍 프로그래밍 - 4 - IOCP Echo Server  (0) 2005.06.29
'실전 네트웍 프로그래밍 -3  (0) 2005.06.29
사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지 사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지
사용자 삽입 이미지 사용자 삽입 이미지

제로보드 기반
디자인은 동양대학교 실내디자인 학과에서 제공.

제작 기간 : 2개월
참여 인원 : 3명
스트레스 관리 10계명

1. 내 인생은 내가 책임질 수 밖에 없으므로 상대방에게 지나친 기대를 하지 말라.

2. 남들이 내가 원하지 않는 쪽으로 행동할 땐, 나의 의사 전달이 부족할 수도 있으니 더욱 설득하라.

3. 남들로부터 부탁을 받았을 때 원하지 않는 것이면 과감히 거절하라.

4. 남들이 나에 대해 비난할 때에는 일리가 있다고 받아들여라.

5. 때로는 혼자 고독할 때도 있다. 혼자서 견뎌라.

6. 지나간 실수에 대하여 되새기지 말자.

7. 어떻게든 사람은 살게 돼 있다. 앞일을 걱정하지 말라.

8. 완벽한 사람은 없다. 모든 일에 70점을 목표로 하자.

9. 지나친 행복을 바라지 말라. 오히려 현재의 내가 행복할 수 있음을 알라.

10.오늘 하루만 열심히 살라.

사용자 삽입 이미지


플래시는 웹상에서 실행되는 백터방식의 동영상이다. 이런 플래시는 수정/변경가능하지만 웹상에서 실행은 안되는 .fla와 수정/변경불가능 하지만 웹상에서 실행되는 .swf가 있다.

.swf를 .fla로 변경하는 방법은 없다 왜냐하면 .fla를 컴파일하여 .swf로 만들기 때문이다.

하지만 Sothink SWF Decompiler MX2005라는 프로그램을 사용하면 디컴파일이 가능하다.

먼저 프로그램을 실행후에 QUICK OPEN을 눌러 .SWF를 선택후에 다시 Export Fla을 클릭하고 변환하면 수정이 됩니다. 이기능은 2005부터 지원합니다.그리고 웹브라우저에도   SWF Catcher라는 버튼이 생겨서 해당 페이지안에 플래시를 쉽게 저장할수있습니다.악의적인 용도로 쓰지 맙시다.


  • Linux의 Echo Server에 접속할 Client이다.
  • 항상 Server가 먼저 실행된 상태에서 접속해야한다.
  • vi editor로 작성한 다음 아래의 code를 입력한 뒤 저장해 Client 소스 파일을 만든다.
  • gcc를 이용해 Client 소스 파일을 컴파일 하고, Server가 실행된 상태에서 Client를 실행한다.
  •     ex) vi Client.c
  •           source code 입력 후 Shift + Z + Z로 저장.
  •           gcc Client.c -o Client.out

아래는 입력할 source code이다.


#include
<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#define BUF_LEN 80

int main(int argc, char* argv[]){
    int skt, n, len_in, len_out;
    struct sockaddr_in server_addr;
    char* host_addr;
    char buf[BUF_LEN+1];

    if(argc != 3){
        printf("사용법 : %s ip_address\n", argv[0]);
        return -1;
    }

    host_addr = argv[1];


    if(skt = socket(PF_INET, SOCK_STREAM, 0) < 0){
        printf("소켓 생성실패\n");
        return -1;
    }

    bzero((char *)&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(host_addr);
    server_addr.sin_port = htons(atoi(argv[2]));

    if(connect(skt, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){
        printf("연결 실패\n");
        return -1;
    }

    printf("문자열을 입력하시오: ");

    if(fgets(buf, BUF_LEN, stdin)){
        buf[BUF_LEN] = '\0';
        len_out = strlen(buf);
    }
    else{
        printf("오류\n");
        return -1;
    }

    write(skt, buf, 80);

    printf("서버로부터 되돌아 온 문장: ");

    for(len_in = 0, n = 0; len_in < len_out; len_in += n){
        if((n = read(skt, &buf[len_in], len_out - len_in))<0){
            printf("read 오류\n");
            return -1;
        }
    }

    printf("%s", buf);
    close(skt);

    return 0;
}

'공부 해 Boa요. > Network' 카테고리의 다른 글

동시형 서버  (0) 2006.10.27
Raw Socket  (0) 2006.09.29
Consol Echo Client  (0) 2006.09.27
실전 네트웍 프로그래밍 - 4 - IOCP Echo Server  (0) 2005.06.29
'실전 네트웍 프로그래밍 -3  (0) 2005.06.29

#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#define ICMP_ECHO 8// ICMP echo 요청 명령
#define ICMP_ECHOREPLY 0//ICMP echo 응답 명령
#define ICMP_MIN 8 // 최소 ICMP 크기(헤더만) 8 byte
#define default_pkt_size 32
#define max_pkt 1024

typedef struct iphdr {/* IP 헤더 구조 */
    unsigned int h_len:4; // 헤더 길이
    unsigned int version:4; // IP 버전
    unsigned char tos; // 서비스 유형
    unsigned short total_len; // 패킷 전체 길이
    unsigned short ident; // 식별자
    unsigned short frag_and_flags; // 플래그
    unsigned char ttl; // 수명
    unsigned char proto; // 프로토콜 종류(TCP, UDP)
    unsigned short checksum;// IP checksum
    unsigned int sourceIP; // 근원지 IP
    unsigned int destIP;// 목적지 IP
}IpHeader;

// ICMP 헤더 구조
typedef struct _ihdr {
    BYTE i_type;
    BYTE i_code; /* type sub code */
    USHORT i_cksum;
    USHORT i_id;
    USHORT i_seq;
    ULONG timestamp;
}IcmpHeader;

void make_icmp(char *, int);
USHORT checksum(USHORT *, int);
void analyse_response(char *,int ,struct sockaddr_in *);
void errorexit(char *errmsg);


int main(int argc, char **argv){
    WSADATA wsaData;
    SOCKET raw_skt;
    struct sockaddr_in target,from;
    struct hostent *host_ent;
    int return_value, datasize, byte_sent;
    int timeout = 1000, counter=10;
    char *target_ip, *icmp_data, *recvbuf;
    unsigned int addr=0;
    USHORT seq_no = 0;
    char hostname[]="ce.dyu.ac.kr"; // default server

    if(WSAStartup(MAKEWORD(2,1),&wsaData) != 0)
        errorexit("WSAStartup 실패\n");
 
    if(argc < 2)
        fprintf(stderr,"%s 호스트주소 [데이터 크기]\n 정해진 server, 데이터크기 사용함\n", argv[0]);
    else
        strcpy(hostname, argv[1]);

    raw_skt = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,0);

    if(raw_skt == INVALID_SOCKET)
        errorexit("WSASocket() 실패\n");

    return_value = setsockopt(raw_skt, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,sizeof(timeout));

    if(return_value == SOCKET_ERROR){
        fprintf(stderr," 수신 제한시간 설정 실패\n");
        return -1;
 } 
 
    timeout = 1000;
    return_value = setsockopt(raw_skt,SOL_SOCKET,SO_SNDTIMEO, (char*)&timeout,sizeof(timeout));

    if(return_value == SOCKET_ERROR)
        errorexit("송신 제한시간 설정 실패\n");

    memset(&target, 0, sizeof(target));

 /* if((host_ent = gethostbyname(hostname)) == NULL){
        target.sin_addr.s_addr = (IN_ADDR *)(hostname);
        target.sin_family = AF_INET;
    }
    else*/{
        host_ent = gethostbyname(hostname);
        memcpy(&target.sin_addr, host_ent->h_addr, host_ent->h_length);
        target.sin_family = host_ent->h_addrtype;
 }

    target_ip = inet_ntoa(target.sin_addr);

    if(argc >2){/* 사용자가 데이터 크기를 설정했다면 */
        datasize = atoi(argv[2]);
        if(datasize == 0)
            datasize = default_pkt_size;
 }

    else
        datasize = default_pkt_size;

    datasize += sizeof(IcmpHeader);
    if((icmp_data = malloc(max_pkt))==0)
        errorexit("메모리 할당 실패");

    if((recvbuf = malloc(max_pkt))==0)
        errorexit("메모리 할당 실패");

 memset(icmp_data, 0, max_pkt);
 make_icmp(icmp_data, datasize);
 
//////////////////////////////////////////////////////////////////////////
 
 while(--counter>0) { /* 일정한 회수만큼 ICMP를 보냄*/
  int len_addr=sizeof(struct sockaddr);
  ((IcmpHeader*)icmp_data)->i_cksum = 0;
  ((IcmpHeader*)icmp_data)->timestamp = GetTickCount();
  // 왕복 지연 시간을 측정하기 위하여 현재 시간을 기록.
  ((IcmpHeader*)icmp_data)->i_seq = seq_no++;
  ((IcmpHeader*)icmp_data)->i_cksum =
   checksum((USHORT*)icmp_data, datasize);
  byte_sent = sendto(raw_skt,icmp_data,datasize,0,
   (struct sockaddr*)&target,sizeof(target));
  if (byte_sent == SOCKET_ERROR){
   if (WSAGetLastError() == WSAETIMEDOUT) {
    printf("시간 초과\n");continue;
   } errorexit("sendto 실패\n");
  }
 
 
//////////////////////////////////////////////////////////////////////////
 
  if (byte_sent < datasize ) fprintf(stdout,"%d bytes 전송\n",byte_sent);
  return_value = recvfrom(raw_skt,recvbuf,max_pkt,0,
   (struct sockaddr*)&from,&len_addr);
  if (return_value == SOCKET_ERROR){
   if (WSAGetLastError() == WSAETIMEDOUT) {
    printf("시간 초과\n");continue;
   }fprintf(stderr,"recvfrom 실패\n");
  }
  analyse_response(recvbuf, return_value, &from);
  Sleep(1000);
 }
 return 0;
}

/////////////////////////////////////////

void analyse_response(char *buf, int bytes,struct sockaddr_in *from) {     IpHeader *iphdr; IcmpHeader *icmphdr;  unsigned short iphdrlen;  iphdr = (IpHeader *)buf;   iphdrlen = iphdr->h_len * 4 ;
        if (bytes  < iphdrlen + ICMP_MIN) {
         printf("패킷 크기가 너무 작음%s\n",inet_ntoa(from->sin_addr)); }
        icmphdr = (IcmpHeader*)(buf + iphdrlen);
        if (icmphdr->i_type != ICMP_ECHOREPLY) {
                errorexit("에코 응답이 아님\n"); }                
        if (icmphdr->i_id != (USHORT)GetCurrentProcessId()) {
                errorexit("식별자가 다른 패킷임\n"); // 자신이 보내지 않은 엉뚱한 곳으로부터 응답이 도착했다. 
  }
        printf("%s로부터 %d bytes 도착", inet_ntoa(from->sin_addr),bytes);
        printf(" icmp 순서번호 = %d. ",icmphdr->i_seq);
        printf(" 왕복 지연 시간 : %d ms\n", GetTickCount()-icmphdr->timestamp); }
/////////////////////////////////////////////////////////////
USHORT checksum(USHORT *buffer, int size) {
  unsigned long cksum=0;
  while(size >1) {
        cksum+=*buffer++;   size -=sizeof(USHORT);  }
  if(size) {
        cksum += *(UCHAR*)buffer;  }
  cksum = (cksum >> 16) + (cksum & 0xffff);
  cksum += (cksum >>16);
  return (USHORT)(~cksum);
}
//////////////////////////////////////////////////////////////
void make_icmp(char * icmp_data, int datasize){
  IcmpHeader *icmp_hdr;
  icmp_hdr = (IcmpHeader*)icmp_data;
  icmp_hdr->i_type = ICMP_ECHO;
  icmp_hdr->i_code = 0;
  icmp_hdr->i_id = (USHORT)GetCurrentProcessId();
  icmp_hdr->i_cksum = 0;
  icmp_hdr->i_seq = 0;
  memset(icmp_data+sizeof(IcmpHeader), 0xaa , datasize - sizeof(IcmpHeader));
                /* 0xaa 임의 데이터로 채우기 */
}

void errorexit(char *errmsg){
 fprintf(stderr,errmsg);
 exit(-1);

'공부 해 Boa요. > Network' 카테고리의 다른 글

동시형 서버  (0) 2006.10.27
Client  (0) 2006.10.15
Consol Echo Client  (0) 2006.09.27
실전 네트웍 프로그래밍 - 4 - IOCP Echo Server  (0) 2005.06.29
'실전 네트웍 프로그래밍 -3  (0) 2005.06.29

#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void errorexit(char *);
BOOL parse(int, char **);
int socket_type = SOCK_STREAM;
char *server_name = "192.168.2.210"; // server adress
unsigned short port = 07;

int main(int argc, char **argv){
    char Buffer[128];
    int result;
    unsigned int addr;
    struct sockaddr_in server;
    struct hostent *hp;
    WSADATA wsaData;
    SOCKET serve_socket;

    if(parse(argc, argv)==FALSE)
        exit(-1);

    if((result = WSAStartup(0x202,&wsaData)) != 0)
        errorexit("WSAStartup 실패\n");

    if (port == 0) errorexit("사용법을 다시 보세요\n");

    if(isalpha(server_name[0]))
        hp = gethostbyname(server_name);

    else{
        addr = inet_addr(server_name);
        hp = gethostbyaddr((char *)&addr, 4, AF_INET);
    }
    if(hp == NULL)
        errorexit("%s 라는 주소를 구할 수 없음 \n");

    memset(&server,0,sizeof(server));
    memcpy(&(server.sin_addr),hp->h_addr,hp->h_length);
    server.sin_family = hp->h_addrtype;
    server.sin_port = htons(port);

    serve_socket = socket(AF_INET,socket_type,0);
    if(serve_socket < 0)
        errorexit("소켓 열수 없음\n");

    printf("%s 서버에 연결 성공\n",hp->h_name);
    if(connect(serve_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
        errorexit("연결 실패\n");

    wsprintf(Buffer,"클라이언트 테스트 중");
    result = send(serve_socket, Buffer, sizeof(Buffer), 0);
    if(result == SOCKET_ERROR)
        errorexit("전송 실패\n");

    printf("보낸 데이터 [%s]\n",Buffer);
    result = recv(serve_socket, Buffer, sizeof(Buffer), 0);
    if(result == SOCKET_ERROR) {
        fprintf(stderr,"recv() 실패\n");
        closesocket(serve_socket);
        WSACleanup();
        return -1;
    }
    if (result == 0){
        printf("서버 연결을 닫음\n");
        closesocket(serve_socket);
        WSACleanup();
        return -1;
    }

    printf("데이터 수신 성공 : %s\n",Buffer);

    closesocket(serve_socket);
    WSACleanup();
    exit(0);

}

BOOL parse(int argc, char **argv){
    int i;

    if(argc > 1){
        for(i=1; i < argc; i++){
            if((argv[i][0] == '-') || (argv[i][0] == '/')){
                switch(tolower(argv[i][1])){
                    case 'p':
                        if(!stricmp(argv[i+1], "TCP"))
                            socket_type = SOCK_STREAM;
                        else if(!stricmp(argv[i+1],"UDP"))
                            socket_type = SOCK_DGRAM;
                        else{
                            fprintf(stderr,"사용법 : %s -p [protocol] -s [server] -n[port num]\n",argv[0]);
                            return FALSE;
                        }
                        i++;
                        break;

                    case 's':
                        server_name = argv[i++];
                        break;
                    case 'n':
                        port = atoi(argv[i++]);
                        break;

                    default:
                        fprintf(stderr,"사용법 : %s -p [protocol] -s(server) -n[port num]\n",argv[0]);
                        return FALSE;
                    }
            }
            else{
                fprintf(stderr,"사용법 : %s -p [protocol] =s [server] -n [port num]\n",argv[0]);
                return FALSE;
            }
        }
    }
}

void errorexit (char *err_msg){
    fprintf(stderr, err_msg);
    WSACleanup();
    exit(-1);
}

 

'공부 해 Boa요. > Network' 카테고리의 다른 글

Client  (0) 2006.10.15
Raw Socket  (0) 2006.09.29
실전 네트웍 프로그래밍 - 4 - IOCP Echo Server  (0) 2005.06.29
'실전 네트웍 프로그래밍 -3  (0) 2005.06.29
'실전 네트웍 프로그래밍 - 2  (0) 2005.06.29
딜레이 뿐 아니라.. 쓸데 없는 넘이 메모리 까지 잡아 먹는다.
해서 ms싸이트까지 가서 삭제법을 알아내 지웠더니..
좋아졌다. 음.. 잘은 모르겠지만.. 이로써 포토샵에서 한글 안되는것까지 해결된듯하다.. 음.. 더 두고 봐야하지만,
중요한건 진짜 쓸데없는 파일이다.. 삭제해도 된다..


Ctfmon.exe(ctfmon) 파일이란 무엇입니까?
Ctfmon.exe는 다른 입력 도구 TIP(Text Input Processor)와 Microsoft Office 입력 도구 모음을 활성화합니다.


Ctfmon.exe 파일이 수행하는 작업은 무엇입니까?
Ctfmon.exe는 활성 창을 모니터링하며 음성 인식, 필기체 인식, 키보드, 번역 및 기타 다른 입력 도구 기술에 대한 텍스트 입력 서비스를 지원합니다.


Ctfmon.exe 파일을 제거할 수 있습니까?
Ctfmon.exe를 제거하면 Office XP 프로그램에 문제가 발생할 수 있으므로 제거하지 않는 것이 좋습니다. Ctfmon.exe를 실행하지 않도록 하려면 아래 단계를 수행합니다.

1단계: 다른 입력 도구 제거\r\n다른 입력 도구 기능을 제거하려면 Office XP 설치 프로그램에서 설치 상태를 사용하지 않음으로 설정합니다.

Microsoft Windows Millennium Edition(Me), Microsoft Windows 98 또는 Microsoft Windows NT 4.0:

1. 모든 Office 프로그램을 끝냅니다.
2. 시작을 누르고 설정을 가리킨 다음 제어판을 누릅니다.
3. 제어판에서 프로그램 추가/제거를 두 번 누릅니다.
4. 설치/제거 탭에서 Microsoft Office XP 제품을 선택합니다. 여기서 Office XP 제품은 사용 중인 특정 Office 제품 이름입니다. Office 프로그램 중 하나의 독립 실행형 버전을 사용 중인 경우에는 목록에서 해당 제품을 선택합니다. 추가/제거를 누릅니다.
5. 유지 관리 모드 옵션 대화 상자에서 기능 추가/제거를 선택하고 다음을 누릅니다. 그러면 Office 응용 프로그램 및 도구의 설치 옵션을 모두 선택하십시오. 대화 상자가 표시됩니다.
6. Office 공유 기능 옆의 더하기 기호(+)를 눌러 목록을 확장합니다.
7. 다른 입력 도구 옆에 있는 아이콘을 누른 다음 사용하지 않음을 선택합니다.
8. 업데이트를 누릅니다.

참고: Office XP Professional, Publisher 2002 같은 Office XP 제품이 여러 가지 설치된 경우 설치된 각 제품에 대해 앞의 단계를 반복해야 합니다.

Microsoft Windows 2000 및 Microsoft Windows XP:

1. 모든 Office 프로그램을 끝냅니다.
2. 시작을 누르고 설정을 가리킨 다음 제어판을 누릅니다. 참고: Windows XP에서는 시작을 누른 다음 제어판을 누릅니다.
3. 제어판에서 프로그램 추가/제거를 두 번 누릅니다.
   a. 시작을 누른 다음 실행을 누릅니다.
   b. 실행 대화 상자에서 다음 명령을 입력합니다.
   Regsvr32.exe /u msimtf.dll
   c. 확인을 누릅니다.
   d. Msctf.dll 파일에 대해 1-3단계를 반복합니다.
4. 현재 설치된 프로그램 목록에서 Microsoft Office XP 제품을 선택합니다. 여기서 Office XP 제품 은 사용 중인 특정 Office 제품 이름입니다. Office 프로그램 중 하나의 독립 실행형 버전을 사용 중인 경우에는 목록에서 해당 제품을 선택합니다. 변경을 누릅니다.
5. 유지 관리 모드 옵션 대화 상자에서 기능 추가/제거를 선택하고 다음을 누릅니다. 그러면 Office 응용 프로그램 및 도구의 설치 옵션을 모두 선택하십시오. 대화 상자가 표시됩니다.
6. Office 공유 기능 옆의 더하기 기호(+)를 눌러 목록을 확장합니다.
7. 다른 입력 도구 옆에 있는 아이콘을 누른 다음 사용하지 않음을 선택합니다.
8. 업데이트를 누릅니다.
참고: Office XP Professional, Publisher 2002 같은 Office XP 제품이 여러 가지 설치된 경우 설치된 각 제품에 대해 앞의 단계를 반복해야 합니다.

2단계: 텍스트 서비스에서 다른 입력 도구 서비스 제거

1. 시작을 누르고 설정을 가리킨 다음 제어판을 누릅니다.
2. 제어판에서 텍스트 서비스를 두 번 누릅니다. 참고: Windows XP에서는 날짜, 시간, 언어 및 국가별 옵션을 누른 다음 국가 및 언어 옵션을 누릅니다. 언어 탭에서 자세히를 누릅니다.
3. 설치된 서비스에서 나열된 각 입력 항목을 선택한 다음 제거를 눌러 항목을 제거합니다. 다음 입력 서비스를 제외한 모든 항목을 하나씩 제거해야 합니다.

English (United States)- default Keyboard United States 101

3단계: Msimtf.dll 및 Msctf.dll 파일에서 Regsvr32 /U 실행
1. 시작을 누른 다음 실행을 누릅니다.
2. 실행 대화 상자에서 다음 명령을 입력합니다.
Regsvr32.exe /u msimtf.dll
3. 확인을 누릅니다. \r\n4. Msctf.dll 파일에 대해 1-3단계를 반복합니다.

시작 -> 실행

Regsvr32.exe /u msimtf.dll -> 메세지가 나오면-> 확인-> 엔터
Regsvr32.exe /u msctf.dll -> 메세지가 나오면 -> 확인 -> 엔터
위와같이 하면
ctfmon.exe의 실행을 유도하는 두개의 dll 파일이 제거 됨.
시작->실행->regedit-> 엔터
HKEY_CURRENT_USER->Software->Microsoft->Windows->CurrentVersion->Run 에서, ctfmon.exe ->삭제 하면 쉽게 해결됩니다.
저번회에 간단하게 IOCP에 대해서 알아 보았다.

저번회를 바탕으로 이번회엔 IOCP Echo Server를 만들것다. 클라이언트로 부터 들어온 메시지를 해당 클라이언트로 되돌려 주는 기능을 하는 아주 단순한 서버이다.

하지만, 근래에 들어서 느끼는 점이 하나 있다. "단순한 놈일수록 견고하게 만들어라." 이말에 공감하시는 분들도 꽤 될거라 생각한다.

각설하고, 우선 소스를 먼저 보자.

#include
#include
#include

#define BUFSIZE 512

// 소켓 정보 저장을 위한 구조체
struct SOCKETINFO
{
OVERLAPPED overlapped;
SOCKET sock;
char buf[BUFSIZE+1];
int recvbytes;
int sendbytes;
WSABUF wsabuf;
};

// 소켓 입출력 함수
DWORD WINAPI WorkerThread(LPVOID arg);
// 오류 출력 함수
void err_quit(char *msg);
void err_display(char *msg);

int main(int argc, char* argv[])
{
int retval;

// 윈속 초기화
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
return -1;

// 입출력 완료 포트 생성
HANDLE hcp = CreateIoCompletionPort(
INVALID_HANDLE_VALUE, NULL, 0, 0);
if(hcp == NULL) return -1;

// CPU 개수 확인
SYSTEM_INFO si;
GetSystemInfo(&si);

// (CPU 개수 * 2)개의 작업자 스레드 생성
HANDLE hThread;
DWORD ThreadId;
for(int i=0; i<(int)si.dwNumberOfProcessors*2; i++){
hThread = CreateThread(NULL, 0, WorkerThread, hcp, 0, &ThreadId);
if(hThread == NULL) return -1;
CloseHandle(hThread);
}

// socket()
SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if(listen_sock == INVALID_SOCKET) err_quit("socket()");

// bind()
SOCKADDR_IN serveraddr;
ZeroMemory(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9000);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
retval = bind(listen_sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr));
if(retval == SOCKET_ERROR) err_quit("bind()");

// listen()
retval = listen(listen_sock, SOMAXCONN);
if(retval == SOCKET_ERROR) err_quit("listen()");

while(1){
// accept()
SOCKADDR_IN clientaddr;
int addrlen = sizeof(clientaddr);
SOCKET client_sock = accept(listen_sock, (SOCKADDR *)&clientaddr, &addrlen);
if(client_sock == INVALID_SOCKET){
err_display("accept()");
continue;
}
printf("[TCP 서버] 클라이언트 접속: IP 주소=%s, 포트 번호=%d\\n",
inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));

// 소켓과 입출력 완료 포트 연결
HANDLE hResult = CreateIoCompletionPort((HANDLE)client_sock, hcp,
(DWORD)client_sock, 0);
if(hResult == NULL) return -1;

// 소켓 정보 구조체 할당
SOCKETINFO *ptr = new SOCKETINFO;
if(ptr == NULL){
printf("[오류] 메모리가 부족합니다!\\n");
break;
}
ZeroMemory(&(ptr->overlapped), sizeof(ptr->overlapped));
ptr->sock = client_sock;
ptr->recvbytes = 0;
ptr->sendbytes = 0;
ptr->wsabuf.buf = ptr->buf;
ptr->wsabuf.len = BUFSIZE;

// 비동기 입출력 시작
DWORD recvbytes;
DWORD flags = 0;
retval = WSARecv(client_sock, &(ptr->wsabuf), 1, &recvbytes,
&flags, &(ptr->overlapped), NULL);
if(retval == SOCKET_ERROR){
if(WSAGetLastError() != ERROR_IO_PENDING){
err_display("WSARecv()");
}
continue;
}
}

// 윈속 종료
WSACleanup();
return 0;
}

DWORD WINAPI WorkerThread(LPVOID arg)
{
HANDLE hcp = (HANDLE)arg;
int retval;

while(1){
// 비동기 입출력 완료 기다리기
DWORD cbTransferred;
SOCKET client_sock;
SOCKETINFO *ptr;
retval = GetQueuedCompletionStatus(hcp, &cbTransferred,
(LPDWORD)&client_sock, (LPOVERLAPPED *)&ptr, INFINITE);

// 클라이언트 정보 얻기
SOCKADDR_IN clientaddr;
int addrlen = sizeof(clientaddr);
getpeername(ptr->sock, (SOCKADDR *)&clientaddr, &addrlen);

// 비동기 입출력 결과 확인
if(retval == 0 || cbTransferred == 0){
if(retval == 0){
DWORD temp1, temp2;
WSAGetOverlappedResult(ptr->sock, &(ptr->overlapped),
&temp1, FALSE, &temp2);
err_display("WSAGetOverlappedResult()");
}
closesocket(ptr->sock);
printf("[TCP 서버] 클라이언트 종료: IP 주소=%s, 포트 번호=%d\\n",
inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
delete ptr;
continue;
}

// 데이터 전송량 갱신
if(ptr->recvbytes == 0){
ptr->recvbytes = cbTransferred;
ptr->sendbytes = 0;
// 받은 데이터 출력
ptr->buf[ptr->recvbytes] = '\\0';
printf("[TCP/%s:%d] %s\\n", inet_ntoa(clientaddr.sin_addr),
ntohs(clientaddr.sin_port), ptr->buf);
}
else{
ptr->sendbytes += cbTransferred;
}

if(ptr->recvbytes > ptr->sendbytes){
// 데이터 보내기
ZeroMemory(&(ptr->overlapped), sizeof(ptr->overlapped));
ptr->wsabuf.buf = ptr->buf + ptr->sendbytes;
ptr->wsabuf.len = ptr->recvbytes -ptr->sendbytes;

DWORD sendbytes;
retval = WSASend(ptr->sock, &(ptr->wsabuf), 1,
&sendbytes, 0, &(ptr->overlapped), NULL);
if(retval == SOCKET_ERROR){
if(WSAGetLastError() != WSA_IO_PENDING){
err_display("WSASend()");
}
continue;
}
}
else{
ptr->recvbytes = 0;

// 데이터 받기
ZeroMemory(&(ptr->overlapped), sizeof(ptr->overlapped));
ptr->wsabuf.buf = ptr->buf;
ptr->wsabuf.len = BUFSIZE;

DWORD recvbytes;
DWORD flags = 0;
retval = WSARecv(ptr->sock, &(ptr->wsabuf), 1,
&recvbytes, &flags, &(ptr->overlapped), NULL);
if(retval == SOCKET_ERROR){
if(WSAGetLastError() != WSA_IO_PENDING){
err_display("WSARecv()");
}
continue;
}
}
}

return 0;
}

// 소켓 함수 오류 출력 후 종료
void err_quit(char *msg)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, WSAGetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf, 0, NULL);
MessageBox(NULL, (LPCTSTR)lpMsgBuf, msg, MB_ICONERROR);
LocalFree(lpMsgBuf);
exit(-1);
}

// 소켓 함수 오류 출력
void err_display(char *msg)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, WSAGetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf, 0, NULL);
printf("[%s] %s", msg, (LPCTSTR)lpMsgBuf);
LocalFree(lpMsgBuf);

'공부 해 Boa요. > Network' 카테고리의 다른 글

Raw Socket  (0) 2006.09.29
Consol Echo Client  (0) 2006.09.27
'실전 네트웍 프로그래밍 -3  (0) 2005.06.29
'실전 네트웍 프로그래밍 - 2  (0) 2005.06.29
실전 네트웍 프로그래밍 - 1  (0) 2005.06.29
1 IOCP 만들기

HANDLE CreateIoCompletionPort (
 HANDLE FileHandle,
 HANDLE ExistingCompletionPort,
 ULONG_PTR CompletionKey,
 DWORD NumberOfConcurrentThreads
);

이름 그대로 IOCP를 만들어 주는 함수 이다. 처음 IOCP를 만들 때는 네개의 인자 모두를 사용하는 것이 아니라 처음의 한개 인자만을 사용한다.그냥 단순히 IOCP를 생성하기만 하는 것 이므로,

HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

와 같이 생성하면 된다.

이제 IOCP를 생성했으므로, 앞에서 말했던 것 처럼 이 IOCP를 통해 입출력 완료가 일어난 결과를 통보 받기만 하면 된다.

결과를 통보 받는다 하여 사용자에게 이벤트나 기타의 방법으로 알려 주는 것이 아니다. IOCP는 입출력 완료가 일어나면 그 결과를 특정한 큐에 집어 넣어 둔다. 때문에 사용자는 이 큐를 항상 감시 하고 있어야 한다. 이 큐에 먼가가 들어 오게 되면 입출력 작업중 하나가 완료 된 것이다. 그럼, 이 큐를 감시할 스레드를 만들어야 할 것이다. 보통은 이 스레드를 작업자 스레드(WorkerThread)
라 부른다.

_beginthreadex(NULL, 0, WorkerThread, , (LPVOID)hIOCP, 0, NULL);

작업자 스레드까지 생성 했으므로, 실제로 입출력을 할 FileHandle을 만들어야 한다. 우리는 소켓을 통해 입출력을 할 것 이므로 소켓을 생성해 주면 된다. 물론 파일 핸들을 통해서도 네트웍입출력이 가능하긴하 지만 그냥 편하게 소켓을 사용하자.

소켓을 생성할 때 주의할 것은 이 소켓이 Overlapped가 가능한 소켓이어야 한다는 것 이다. 그냥 일반적으로 소켓을 생성하면 Overlapped가 가능한 소켓이 된다. Winsock2의 WSASocket()을 사용하여 처음 소켓을 만들때 Overlapped 인자를 주어 소켓을 생성할 수도 있다.

SOCKET hSocket = WSASocket(AF_INET, SOCKET_STREAM, 0, NULL, WSA_FLAG_OVERLAPPED);

이제 이 소켓을 IOCP에 연결 해 준다. 그럼 이 소켓에서 입출력 완료가 일어났을 때 완료 통보가 완료큐에 들어가게 되고, 그럼 이 완료큐를 감시하고 있던 스레드에서 그 결과를 가져와서 해당 작업을 할 수있게 되는 것 이다.

CreateIoCompletionPort((HANDLE)hSocket, hIOCP, CompletionKey, 0);

IOCP를 만들고, 스레드를 만들었고 소켓을 만들어 IOCP에 등록까지 마쳤다. 이제 소켓을 통해 입출력 작업을 하면 된다. 그러면 입출력 작업이 완료 되었을 때 우리는 그 결과를 가져 올 수 있을 것 이다.


그럼, 입출력이 완료 되었을 때 완료 큐에서 결과를 가져 오는 방법을 알아야 할 것 이다.
GetQueuedCompletionStatus(
 HANDLE CompletionPort,
 LPDWORD lpNumberOfBytes,
PULONG_PTR lpCompletionKey,
 LPOVERLAPPED *lpOverlapped,
 WORD dwMilliseconds
);

완료 큐에서 결과를 가져오는 함수 이다. 대충 인자를 살펴보아도 무슨 역할을 하는 지 알 수 있을 것 이다.

자 이제 이것으로 준비는 모두 끝 났다. 이것을 바탕으로 가장 기본적인 IOCP Echo Server를 만들어 보도록 하자.

'공부 해 Boa요. > Network' 카테고리의 다른 글

Raw Socket  (0) 2006.09.29
Consol Echo Client  (0) 2006.09.27
실전 네트웍 프로그래밍 - 4 - IOCP Echo Server  (0) 2005.06.29
'실전 네트웍 프로그래밍 - 2  (0) 2005.06.29
실전 네트웍 프로그래밍 - 1  (0) 2005.06.29
1. IOCP
IO Completion Port. 우리말로 입출력 완료 포트 정도로 번역(?) 될 수 있는 윈속에 있어 최고의 성능을 보여 주는 모델이다.

흔히 요즘 출판되고 있는 윈도우 네트웍 관련 서적에는 빠지지 않고 그 내용이 포함되어 있다. 허나 정작 쓸만한 구현물을 포함하고 있는 서적은 별로 눈에 띄지는 않는다. 하지만 잘 찾아 보면 찾을 수 있을 지도...

우선 먼저 IOCP에 대해 집고 넘어 가자.

IOCP는 윈도우 NT 3.5 이상의 운영체제(OS)가 제공해 주는 입출력을 작업에 관계된 커널오브젝트다. 즉, 입출력에 관계된 핸들(HANDLE)에서 발생하는 작업완료를 통보해 주는 메커니즘이라 할 수 있다.

우리는 특정 입출력 핸들을 하나 생성하고 이것을 IOCP에 등록해 주게 되면 그후부턴 우리가 등록한 핸들을 통해 입출력이 이루어 질 때 마다 이러한 작업의 결과를 통보받을 수 있게 된다. 물론 이러한 통보는 프로그래밍하는 것이 아니라 OS단에서 처리하게 되므로 여러가지 루틴을 거치지 않고 바로 결과를 통보받게 된다.

'공부 해 Boa요. > Network' 카테고리의 다른 글

Raw Socket  (0) 2006.09.29
Consol Echo Client  (0) 2006.09.27
실전 네트웍 프로그래밍 - 4 - IOCP Echo Server  (0) 2005.06.29
'실전 네트웍 프로그래밍 -3  (0) 2005.06.29
실전 네트웍 프로그래밍 - 1  (0) 2005.06.29
MS Winsock 2를 이용한 네트웍 프로그래밍.

현재까지의 자료를 정리도 할겸 네트웍 프로그래밍에 대한 문서를 만들어 보고자 한다. 이기종 간의 통신을 다루는 것이 아니라 단지 Microsoft Windows Socket 2를 사용한 네트웍 프로그래밍에 대한 내용만을 다룰 것이다.

현재 계획한 바로는 한가지 모델을 기본으로 이 모델을 완성해 나가는 방향으로 진행 하고자 한다. 또한 글의 내용은 기초단계는 그냥 대충 넘어가고  Winsock의 고급기능과 Winsock의 동작 방식에 촛점을 맞추어 보도록 하겠다.

기획 모델.
Chatting Server.

일반적인 체팅 서버라 할 수 있겠으나 동접 2~3만을 커버할 수 있는 대용량 체팅 서버를 궁극적인 목표로 진행 할 것이다.

'공부 해 Boa요. > Network' 카테고리의 다른 글

Raw Socket  (0) 2006.09.29
Consol Echo Client  (0) 2006.09.27
실전 네트웍 프로그래밍 - 4 - IOCP Echo Server  (0) 2005.06.29
'실전 네트웍 프로그래밍 -3  (0) 2005.06.29
'실전 네트웍 프로그래밍 - 2  (0) 2005.06.29
1. 꿈을 가지고 있다.

2. 얼굴에 자신감이 넘친다.

3. 어린 아이같은 표정을 갖고 있다.
4. 가정을 소중히 여긴다.

5. 사전에 미리 준비한다.

6. 돈을 어디다 써야할지 잘 판단한다.

7. 끝까지 최선을 다한다.
8. 남자를 반하게 만든다.

9. 거짓말 하지 않는다.

10. 아랫 사람에게도 배운다.
(::우리가 몰랐던 &#39;가공식품의 섬뜩한 폐해&#39;::)“아이에게 과자를 주느니 차라리 담배를 피우게 하라”오랫동안 장애인들을 돌보며 과자 등의 가공식품이 사람에게 주 는 뼈저리게 느꼈다는 어느 건강 전문가가 한 말이다. 과자의 폐해가 담배 못지않다는 얘기다.

하지만 과자 회사에서 16년간이나 근무하다 과자의 해독을 직접 체험한 뒤, 아예 직장을 그만 둬 버린 안병수(49·후델식품건강연구소)소장의 내부고발은 더욱 섬뜩하다. 안 소장은 가공식품이 아이의 몸을 망칠뿐 아니라, 주의 력 결핍, 과잉행동장애, 청소년 범죄 등의 정신장애를 일으키고, 선천성 장애아 출산의 원인이 된다고 말한다. 안소장의 신간 ‘과자, 내 아이를 해치는 달콤한 유혹’(국일미디어)을 따라 과자를 포함한 가공식품이 가진 문제를 살펴본다.

안병수 소장이 저서에서 그 폐해가 ‘섬뜩할’ 정도라고 묘사한 가공식품들은 이른바 불량식품으로 낙인찍힌 것들이 아니다. 더 러는 수십년 동안 장수하며 식품시장을 석권해 온 제품들이다.

아이, 어른할 것 없이 즐기는 라면이나 과자, 사탕, 아이스크림, 청량음료, 드링크류가 대부분 포함돼 있다. 안 소장이 책에서 밝히는 가공식품의 폐해를 종류별로 살핀다.

◈ 라면, 스낵 = ‘식품업계가 낳은 20세기 최대의 걸작.’ 일본의 유명한 건강 저널리스트 이마무치 고이치가 인스턴트 라면을 두고 했다는 말이다. 하지만 이마무치는 덧붙인다. ‘21세기에는 반드시 사라져야 할 식품’이라고. 책에 따르면 라면의 원료는 열처리 과정을 거친‘흰 밀가루’와 ‘첨가물’. 라면에 쓰이는 고열처리된 탄수화물은 입자가 작고 성글어서 소화흡수가 비정 상적으로 빠르다. 혈당치를 급속히 증가시켜 우리 몸의 인슐린 분비 세포에 타격을 가하는 것이다.

제품에 따라 약간 다르지만 인스턴트 라면에는 인공조미료, 향료, 색소, 유화제, 안정제, 산화방지제 따위가 들어간다. 한 가지만 먹어도 좋잖을 이런 여러 종류의 첨가물을 한꺼번에 먹도록 만든 것은 더욱 치명적. 팝콘이나, 쌀튀김처럼 고열처리된 식품이 삶은 것보다 좋지 않은 것도 입자가 작고 성글어 혈당치를 급상승시키기 때문이다. 스낵류의 맛을 내기 위해 들어가는 각종 첨가물이 인체의 생리 시스템을 교란시키는 것은 말할 것도 없다.

◈ 캔디·껌·아이스크림 = 지금까지 캔디(사탕)가 비판받은 이 유는 충치 때문이었다.

하지만 책은 충치는 빙산의 일각일 뿐이 라고 밝힌다. 캔디야말로 정제당과 첨가물 등 오직 문제있는 물 질로만 이뤄졌다고 해도 과언이 아니라는 것이다. 캔디의 기본은 설탕과 정제물엿을 넣고 가열 농축한 것. 말랑말랑한 사탕은 유화제나 경화유를 넣는다. 이 과정이 끝나면 산미료나 조미료 향료 등의 첨가물을 넣고 색소를 쓴다.

물론 대부분의 첨가물과 색소 는 생리기능이나 신경전달기능, 뇌기능 따위에 장애를 일으킬 가능성이 크다. 흔히 물엿을 조청과 같은 당류로 착각하나 시중의 물엿은 영양분이 거의 없는 정제당의 아류일 뿐이다. 정제당 70%와 향료, 색소, 유화제, 가소제, 향 보조제 등 첨가물 30%가 榕 載?껌을 씹는 것은 ‘혐오물질을 씹는 것’이다. 껌에서 가장 위험한 것은 하나에 0.1g이나 들어가는 향료다. 향료는 ppt(1조분 의1)단위에서도 활성화하는데, 체중 50kg인 사람이 껌하나를 씹 으면 향료의 체내 농도는 무려 200만ppt에 이른다. 정제당이 주 성분인 아이스크림에도 발암물질이 체내에서 잘 섞이도록 돕는 유화제를 비롯, 향료와 색소, 안정제, 인공감미료등 유해 첨가물 투 성이다.

◈ 패스트푸드·가공 치즈와 버터·햄·소시지 = 햄버거, 감자튀김, 치킨 세트 등 패스트 푸드의 문제는 보통 2가지로 이야기된다. 하나에 하루권장 지방 섭취량의 최대 82%까지 들어있는 지나친 지방과 열량, 그리고 각종 유해 첨가물이다. 하지만 책은 고 칼로리보다 해로운 것은 튀김과정에서 함유되는 트랜스지방산이 라고 밝힌다.

국내 유통되는 치즈의 대부분을 차지하는 가공치즈에도 조미료와 향, 색소, 보존료 등 첨가물 투성이다. 육류가공품 에서 가장 위험한 것 중의 하나는 햄과 소시지 등에 선홍색을 내기 위해 쓰이는 아질산나트륨. 아질산나트륨은 먹음직스러운 색 을 내면서 다른 맛을 덮어 맛을 부드럽게 하고, 식중독균 등 미 생물 번식을 억제한다. 하지만 이 성분이 육류라면 반드시 榕樗獵?‘아민’ 성분과 결합해 니트로사민을 만드는게 문제다. 동물실 험에 따르면 니트로사민 0.3마이크로그램을 단 한번 투여했더니, 간암이나 폐암이 유발된다는 사실이 확인됐다.

◈ 과자류 = 흔히 ‘정을 전하는데 과자만한 게 없다’고 한다.
하지만 ‘국민과자’, 혹은 ‘과자의 제왕’으로 세계적으로 알 려진 한 장수상품에 대한 책의 분석 내용은 무시무시하다. 먼저 이 과자의 겉을 둘러싼 초콜릿은 초콜릿이 아니다. 수소첨가반응의 산물로 만든 모조 초컬릿이다. 문제는 수소첨가반응 과정에서 모조 초콜릿에 다량 함유될 수 밖에 없는 트랜스지방산이다. 이 성분은 심장병, 동맥경화증을 유발하고 간암, 위암, 대장암, 당뇨병과 관련이 있는 독성 물질. 과자를 부드럽게 만드는 쇼트닝 역시 수소첨가반응의 산물이다. 독성물질인 트랜스지방산이 많이 함유될 수 밖에 없다. 이 과자의 가운데 부분이 말랑말랑하면서도 상온에서 부패하지 않는 것은 90% 이상을 정제당류 덩어리로 만들어 미생물이 번식할 수 없게 했기 때문이다. 물론 이런 문 제는 이 과자에만 있는 것이 아니다. 대부분의 과자가 정제당류, 트랜스지방산, 첨가물 범벅이란 점에서 정도의 차이만 있을 뿐 대동소이하다.

◈ 가공우유·청량음료·드링크류 = 30년 넘은 장수식품으로, 가공우유의 대표 제품인 바나나 우유에는 바나나가 없다. 책에 따 르면 단맛은 액상과당과 백설탕으로, 노란색은 치자황색소로, 바나나맛은 바나나향으로 낸다. 일본 ‘식품첨가물평가일람’은 치자황색소를‘위험등급 3급’첨가물로 분류한다. 체중 1㎏당 0.8~5g을 투여한 쥐의 경우 간장출혈이 있었다는 보고가 있었다. 수 백가지의 화학물질로 이루어진 바나나향도 뇌활동을 교란하는 물질과 호르몬교란물질, 알르레기 유발물질이 얼마나 많은지 알수 없다. 커피우유나 초코우유도 유해 첨가물이 많기는 한가지다.

가공식품이 안고 있는 문제의 백미는 액체사탕이라 할 청량음료 에 있다. 액상과당, 탄산가스, 인산, 향료 등을 주원료로 하는 청 량음료가 비만의 원인이라는 것은 널리 알려져 있지만, 인산 성 분이 아이들의 정신건강까지 위협하는 행동독리학상의 물질이라 는 사실은 잘 알려져 있지않다. 콜라 대신 사이다를 선택했다면 호랑이 무서워 늑대굴로 들어선 셈. 피로회복제로 쓰이는 드링크류의 경우 카페인 못지않게 안식향산나트륨이 문제다. 개를 대상으로, 체중 1㎏당 인식향산나트륨 1g씩을 매일 투여했더니 운동이 불가능해지고 간질성 경련을 일으키더니 250일만에 죽음에 이르는 것이 확인됐다.
맨날 홈페이지 형식으로 만들어서 운영을 하다가...

업데이트에 짜증을 느꼈는데...
설치형 블로그 태터 툴즈를 설치 해봤다...

여기에 올리는 모든 자료는 내가 보관 할 수 있고,
관리 할 수 있다는 점이 좋은 것 같다...

뭐 개인 블로그에 얼마나 많은 사람들이 방문할지는 모르겠지만...
일단 관리가 편하다는 것에 "올인!" 이다! ㅎㅎ

+ Recent posts