TCP/UDP Network Protocol

Posted 2008. 11. 2. 14:00 by MINOK

1. TCP Network란?

- Transmission Control Protocol

- 인터넷 상의 컴퓨터들 사이에서 데이터를 메시지의 형태로 보내기 위해 IP와 함께 사용되는 프로토콜이다. IP가 실제로 데이터의 배달처리를 관장하는 동안, TCP는 데이터 패킷을 추적 관리한다. 여기서 메시지는 인터넷상에서의 효과적인라우팅을 위해 패킷이라는 여러 개의 작은 조각으로 나누어진다. 예를 들어 HTML파일을 Web Server로부터 사용자에게 보내질 때, 서버 내에 있는 TCP프로그램 계층은 파일을 여러 개의 패킷들로 나누고, 패킷번호를 붙인 다음, IP프로그램 계층으로 보낸다. 각 패킷이 동일한 수신지주고(IP주소)를 가지고 있더라도, 패킷들은 네트ㅡ워크의 서로 다른 경로를 통해 정송될 수 있다. 다른 한쪽 편(사용자 컴퓨터 내의 클라이언트 프로그램)에 있는 TCP는 각 패킷들을 재조립하고, 사용자에게 완전한 파일로 보낼 수 있을 때까지 기다린다.

 

2. UDP Network 란?

- User Datagram Protocol

- IP를 사용하는 네트워크 내에서 컴퓨터들 사이에서 메시지들이 교환될 때 제한된 서비스만을 제공하는 통신 프로토콜이다. UDP는 TCP의 대안이며, IP와 함RP 쓰일 때에는 UDP/IP라고 표현하기도 한다. TCP와 마찬가지로 UDP도 한 컴퓨터에서 다른 컴퓨터로 데이터그램이라고 불리는 실제 데이터 단위를 받기 위해 IP를 사용한다. 그러나 UDP는 TCP와 달리, 메시지를 패킷(데이터그램)으로 나누고, 반대편에서 재조립하는 등의 서비스는 제공하지 않으며, 특히 도착하는 데이터 패킷들의 순서를 제공하지 않는다. 이 말은 UDP를 사용하는 응용프로그램은 전체 메시지가 올바를 순서로 도착했는지에 대해 확인 할 수 있어야한다는 것을 의미한다. 교환해야할 데이터가 매우 적은 네트워크 응용프로그램들은 처리시간단축을 위해 UDP를 사용한다.

 

3. TCP와 UDP의 차이점

TCP : 호스트사이에 세션이 설정되어 승인 및 순차적인 데이터 전송이 보장되며 신뢰할 수 있는 데이터 전송만을 보장한다. 때문에 더 느리고 더 많은 오버헤드가 필요하며 지점 간 통신만 지원한다.

-연결형 방식, 점대점 통신

-보장성서비스제공(flow control, error control, congestion(체증) control)

-Full Duplex 통신, Graceful 연결해제

-Byte(stream)-Oriented → segment 단위로 전송하지만 stream of byte로 취급되고 따라서 모든 Bytes는 번호가 붙여진다.

 

UDP : 호스트사이에 세션이 설정되지 않는 연결 없는 서비스이기에 승인 및 순차적인 데이터 전송이 보장되지 않는다. 더 빠르고 오버헤드가 적게 필요하며 지점 간 통신과 지점 대 다중 지점 간(point-to-multipoint)통신을 지원한다.

-비연결형 방식

-비보장성 서비스 제공

-Datagram-Oriented

 


4. Source Code Analyze

◎ TCP/IP - Server

#include "stdio.h"

#include "string.h"

#include "fcntl.h"

#include "stdlib.h"

#include "sys/socket.h"

#include "sys/file.h"

#include "netinet/in.h"

 

int main()

{

int serversock, clientsock;

struct sockaddr_in serveraddr, clientaddr; //socket open

 

int addr_len = sizeof(struct sockaddr);

char buf[1024];

int recv_count;

 

if( (serversock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )

{

perror("socket");

exit(-1);

}

 

bzero( (char*)&serveraddr, sizeof(serveraddr) );

serveraddr.sin_family = AF_INET;

serveraddr.sin_port = htons(2006);

serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

//Bind

if( bind(serversock, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0 )

{

perror("bind");

exit(-1);

}

//Listen

if( listen(serversock, 0) < 0 )

{

perror("listen");

exit(-1);

}

 

printf("listening...\n");

//Accept

clientsock = accept(serversock, (struct sockaddr*)&clientaddr, &addr_len);

printf("connected from %s[%d]\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));

 

while(1)

{

recv_count = recv(clientsock, buf, 1024, 0);

if(recv_count == -1)

break;

printf("%s\n", buf); //수신된 메시지를 출력한다.

send(clientsock, buf, 1024, 0); //수신된 메시지를 재전송한다.

}

 

//socket close

close(clientsock);

close(serversock);

return 0;

}

 

◎ TCP/IP - Client

#include "stdio.h"

#include "fcntl.h"

#include "stdlib.h"

#include "sys/socket.h"

#include "sys/file.h"

#include "netinet/in.h"

 

int main()

{

int client;

 

//socket open

struct sockaddr_in serveraddr;

struct sockaddr_in clientaddr;

char buf[1024];

 

if( (client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0 )

{

perror("socket");

exit(-1);

}

bzero( (char*)&serveraddr, sizeof(serveraddr) );

serveraddr.sin_family = AF_INET;

serveraddr.sin_port = htons(2006);

serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

//Connect

if( connect(client, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0 )

{

perror("connect");

exit(-1);

}

 

while(1)

{

printf("input your data : ");

memset(buf, 0, 1024);

gets(buf); //입력받은 문자열 저장

if(strcmp(buf, "exit") == 0) //exit문자열과 비교 같을 때 빠져나감

break;

 

send(client, buf, 1024, 0); //저장된 문자열 송신

memset(buf, 0, 1024);

recv(client, buf, 1024, 0); //재전송된 메시지 수신

printf("echo data : %s\n", buf); //재전송된 메시지 출력

}

close(socket); //socket close

return 0;

}

 

 

◎ UDP/IP - Server

#include "stdio.h"

#include "string.h"

#include "fcntl.h"

#include "stdlib.h"

#include "sys/socket.h"

#include "sys/file.h"

#include "netinet/in.h"

 

int main()

{

int serversock;

 

//socket open

struct sockaddr_in serveraddr, clientaddr;

 

int addr_len;

char buf[1024];

int recv_count;

 

if( (serversock = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )

{

perror("socket");

exit(-1);

}

 

bzero( (char*)&serveraddr, sizeof(serveraddr) );

serveraddr.sin_family = AF_INET;

serveraddr.sin_port = htons(9000);

serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

 

//bind

if( bind(serversock, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0 )

{

perror("bind");

exit(-1);

}

 

printf("Waiting...\n"); //대기메시지 출력

 

while(1)

{

addr_len = sizeof(clientaddr);

 

//recvform

recv_count = recvfrom(serversock, buf, 1024, 0,(struct sockaddr*)&clientaddr, &addr_len);

if(recv_count == -1)

break;

 

printf("%s\n", buf); //수신메시지 출력

//sendto 수신된 메시지 재전송

sendto(serversock, buf, 1024, 0,(struct sockaddr*)&clientaddr, sizeof(clientaddr));

}

 

close(serversock); //socket close

return 0;

 

}

 

◎ UDP/IP - Client

#include "stdio.h"

#include "fcntl.h"

#include "stdlib.h"

#include "sys/socket.h"

#include "sys/file.h"

#include "netinet/in.h"

 

int main()

{

int client;

//socket open

struct sockaddr_in serveraddr;

 

char buf[1024];

 

if( (client = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )

{

perror("socket");

exit(-1);

}

bzero( (char*)&serveraddr, sizeof(serveraddr) );

serveraddr.sin_family = AF_INET;

serveraddr.sin_port = htons(9000);

serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

 

 

while(1)

{

printf("input your data : ");

memset(buf, 0, 1024);

gets(buf); //입력받은 문자열 저장

if(strcmp(buf, "exit") == 0) //exit문자열과 비교 같을 때 빠져나감

break;

//sendto 저장된 문자열 server부로 전송

sendto(client, buf, 1024, 0,(struct sockaddr*)&serveraddr, sizeof(serveraddr) );

 

 

memset(buf, 0, 1024);

recvfrom(client, buf, 1024, 0,NULL,NULL);//server로부터 재전송된 메시지수신

printf("echo data : %s\n", buf); //재전송된 메시지 출력

}

close(socket); //socket close

return 0;

}

 

 

 

'Computer Engineering > Embedded System Archictecture' 카테고리의 다른 글

Thread 생성과 응답속도  (0) 2008.10.08

컴퓨터로 인해 발생하는 문제점 극복하기

Posted 2008. 10. 23. 12:50 by MINOK




1. 우리의 정신은 건강한가


컴퓨터의 사용이 늘어나면서 사용자들에게 다음과 같은 정신적 장애가 나타

나기도 한다.

대인 접촉 기피증  |

컴퓨터에 빠져 혼자 지내는 시간이 많아지고, 이것이 습관화되면 컴퓨터와

함께 혼자 지내는 것이 더 편하게 느껴지기도 한다.


이러한 대인 접촉 기피증은 원만한 가정 생활이나 친구 관계를 유지하는 데

방해가 되며, 다른 개인적 문제들을 일으키는 원인이 되기도 한다.



감정 절제 부족  |


다른 사람과 만나는 기회가 줄어들면 다른 사람의 감


정을 배려하는 능력이 떨어져 올바른 대인 관계를 유지하기 어려워진다.



정보 과다 
|

컴퓨터는 많은 양의 정보를 제공해 준다. 그러나 과다하게


제공되는 정보는 개인의 올바른 선택 능력을 떨어뜨릴 수 있다.



정보 편식  |

우리들은 자신이 좋아하는 정보에 몰두하는 경향이 있다. 필

요한 정보보다 좋아하는 정보에 몰두하는 것은 올바른 판단력이나 폭넓은

지식을 갖추는 데 바람직하지 않다.



스트레스 |

컴퓨터 기술의 발전 속도는 매우 빠르다. 하루가 다르게 등장

하는 컴퓨터와 소프트웨어에 적응하기 위해서는 끊임없이 새로운 것을 공부

하고 익혀야 한다. 이 과정에서 남에게 뒤떨어지지 않으려는 강박감으로 인

해 우리는 정신적인 스트레스를 받기도 한다.





2. 우리의 신체는 건강한가

오늘날 컴퓨터 중독증을 우려할 정도는 아니지만, 청소년들의 컴퓨터 활용 시간은 점차
늘어나는 추세이다. 성인의 경우에는 직장에서 대부분의 근무 시간에 컴퓨터로 작업하는 것이 일반화되고 있다.
매일 오랜 시간 컴퓨터 작업을 하는 것은 신체의 건강에 좋지 않은 영향을 끼칠 수 있다. 신체상에 생길 수 있는 대표적인 문제로는 VDT 증후군, 눈의 피로, 근육통 등을 들 수 있다.


VDT(Video Display Terminal) 증후군  |
텔레비전이나 컴퓨터 모니터와 같은 영상 표시 장치는 건강에 나쁜 영향을 줄 수 있는 전자파를 발생시킨다. 의학적인 증거는 불충분하지만, 이러한 전자파는 우리의 신체에 좋지 않은 영향을 끼치는 것으로 알려져 왔다. 최근에 생산되는 컴퓨터 모니터는 전자파 차단 기능을 가지고 있으나 안전을 위하여 화면과 일정한 거리를 유지하고, 될 수 있는 대로 전자파 차단 장치를 부착하는 것이 좋다.  

눈의 피로  |
컴퓨터를 이용하여 오랜 시간 작업하는 사람 중에는 눈의 피로와 이상을 호소하는 사람이 많다. 이러한 눈의 피로 증세를 컴퓨터 화면 증후군(CVS:Computer Vision Syndrome)이라고도 한다.
일반적인 증세는 눈의 건조, 충혈, 흐릿함, 두통 등이다. 이를 예방하기 위해서는 화면 차단기를 사용하고, 눈의 피로를 풀어 주는 운동을 하는 것이 좋다.


| 눈의 피로 예방법 |

손바닥을 맞대어 따뜻하게 한 후 눈꺼풀 위에살짝 댄다. 이 방법은 눈의 긴장을 푸는 데 효과가 있다. 또 다른 예방 방법은 창 밖의 먼 곳을응시하다가 재빨리 가까운 물체를 응시하는 동작을 수 초 간격으로 십여 차례 반복하는 것이다. 이 방법은 안구 근육 운동에 효과가 있다.

근육통 |
고정된 자세로 장시간 반복적인 자판 입력 작업을 하는 것은 손목 관절, 목, 등, 어깨 부위 등의 근육 통증을 일으킬 수 있다.
근육통은 올바른 자세와 적절한 휴식, 몇 가지 보조 장비를 사용함으로써 극복할 수 있다. 최근에는 이러한 근육통을 최소화하는 데에 도움을 줄 수 있는 다양한 형태의 자판과 마우스 패드가 개발되고 있다.

앞에서 설명한 여러 가지 개인적 문제점들을 미리 예방하기 위해서 우리는 앞으로 어떻게 대처해야 할까? 정보 시대를 살고 있는 우리는 이러한 개인적 문제 발생을 염려하여 정보 사회의 동반자인 컴퓨터를 전혀 활용하지 않을 수는 없다. 부정적인 면을 염려하여 컴퓨터를 멀리하는 컴퓨터 기피증은 또 다른 문제로 발전할 수 있고, 정보 사회의 시대적 흐름을 거스리는 일이며, 올바른 정보 생활을 불가능하게 한다. 그러므로 컴퓨터 활용에 따르는 개인적 문제를 최소화하기 위해서는 컴퓨터를 사용함에 있어서 맹목적으로 몰입하지 않도록 하고, 일상적인 생활의 질서와 대인 관계를 깨뜨리지 않는 범위 속에서 쾌적한 환경과 올바른 자세를 유지하며 컴퓨터를 활용해야 한다. 또한 정보를 다룰 때, 개인의 문제 해결에 필요한 정보나 미리 계획하고 목적한 정보를 우선적으로 다루도록 하고, 성인용 음란 정보와 같은 불건전한 정보에 접하지 않도록 스스로 노력하고 자제하도록 한다. 끝으로 새로운 기술의 변화에 능동적으로 적응하려는 적극적인 자세를 가지도록 한다.






3. 우리의 사생활은 안전하게 지켜지고 있는가 

컴퓨터 활용이 증가함에 따른 여러 가지 사회적 문제 중에서 사용자 와 가장 밀접한 문제는 사생활 침해이다. 사생활 침해란, 개인의 정보를 타인 또는 단체에 불법적으로 공개, 유통시키거나, 양도하는 일체의 행위를 의미한다.

개인 정보란, 이름, 성별, 나이, 주소, 전화 번호, 가족 사항, 은행 구좌 번호, 학력 등 개인의 신상에 관한 정보를 말한다. 특정의 개인 정보는 거미줄처럼 얽혀 있는 통신망을 통하여 한 기관 또는 한 장소에서 다른 곳으로 아주 쉽고 빠르게 직접 또는 간접으로 유통될 수 있다.

비밀을 보장받아야 할 이러한 개인 정보가 본인 모르게 공개, 유통, 양도되는 것도 바람직한 일이 아니지만, 다른 불법적인 활동에 쓰여질 가능성이 높다는 점에서 그 심각성이 크다고 볼 수 있다.

고도 정보 사회에서는 대부분의 컴퓨터가 통신망으로 서로 연결되기 때문에 개인 정보 유출에 의한 사생활 침해가 매우 쉬워진다는 점에서 우리들 개개인의 철저한 윤리관이 더욱 요구되고 있다.

사생활에 관한 개인 정보를 보호하는 것은 법적인 문제 이전에 사회의 가장 기본적인 윤리라고 할 수 있다. 이러한 사생활 보호 윤리는 비단 컴퓨터의 활용에만 국한되는 것이 아니라 팩스, 전화, 카메라 등 모든 정보 매체의 활용에도 적용되는 것임에 유의해야 한다.





4. 초대받지 않은 손님, 컴퓨터 바이러스

컴퓨터 바이러스란, 컴퓨터에 저장된 자료 또는 시스템 소프트웨어나 응용 소프트웨어를 변형, 파괴, 삭제하는 불법 소프트웨어를 말한다. 이러한 컴퓨터 바이러스는 컴퓨터가 원하는 작업을 제대로 수행하지 못하게 하고, 심한 경우에는 컴퓨터의 작동을 불가능하게 함으로써 우리에게 큰 손실을 끼친다. 컴퓨터 바이러스는 정보 사회의 에이즈(AIDS)라고 불릴 만큼 피해가 클 뿐 아니라 전염성이 매우 강하다. 컴퓨터 바이러스의 감염 경로는 디스켓에 의한 것과 통신망에 의한 것으로 나눌 수 있다. 통신망의 활용 증대에 따라 컴퓨터 바이러스의 감염은 더욱 확산될 것이므로 예방과 올바른 대처가 그 어느 때보다 중요하다. 바이러스에 의한 피해를 줄이기 위한 방법은 다음과 같다.

백신 프로그램 설치 |
컴퓨터 바이러스의 감염 여부를 확인하고, 감염된 경우 이를 치료해 줄 수 있는 백신 프로그램을 설치한 다음, 컴퓨터 내의 모든 프로그램과 자료를 정기적으로 점검하도록 설정해 둔다.

정품 소프트웨어 활용  |
반드시 정품 프로그램을 활용하도록 한다. 특히 디스켓에 담긴 프로그램이나 자료를 읽어들일 때에는 사전에 컴퓨터 바이러스의 감염 여부를 반드시 점검하도록 한다.

자료의 저장 |
만일의 경우에 대비하여 중요한 자료는 별도의 보조 기억 장치에 정기적으로 저장하여 관리한다. 이와 같은 저장 작업은 다소 번거롭기는 하지만 컴퓨터 바이러스 피해에 따른 불의의 사고로부터 자신의 귀중한 자료를 보호할 수 있는 가장 확실한 방법이다.





5. 날로 증가하는 컴퓨터 범죄를 예방하자

컴퓨터 범죄는 불법적인 이익을 얻으려는 목적에서 비롯되는 것이 대부분이지만, 단순한 장난이 그 동기가 되는 경우도 있다.
  

불법 복제 |
컴퓨터 프로그램 또는 자료를 개발한 사람이 가지는 고유한 재산권을 저작권이라 한다. 소프트웨어나 자료에 대한 저작권은 현금이나 주택과 같이 그 소유권을 당연히 보장받아야 한다.이러한 권리를 침해하는 대표적인 사례가 소프트웨어의 불법 복제와 배포 행위이다. 이와 같은 행위는 저작자의 재산권 침해는 물론 사회적으로는 소프트웨어 산업을 위축시킬 수 있으므로 그 심각성이 크다. 
 

컴퓨터를 이용한 금품 절도 |
통신망을 이용하여 얻은 개인의 예금 정보나 신용 카드 정보를 사용하여 타인의 예금을 인출하는 행위가 대표적인 예이다. 최근에는 프로그램을 조작하여 절도 또는 횡령하는 행위도 늘어나고 있다. 
 

불법 침입  |
사용 권한이 없는 타인의 컴퓨터에 침입하는 행위를 불법 침입, 또는 해킹이라고 한다. 해킹은 컴퓨터에 수록된 자료를 변조하거나 파괴하는 행위로 이어지는 경우가 많다. 심한 경우에는 사회적으로 매우 중요한 컴퓨터 시스템이나 전산망을 마비시키기도 한다. 해킹은 청소년들에 의해 발생하는 경우가 많다. 자신이 의도하지 않았다 하더라도 사회 전체에 심각한 손해를 끼칠 수 있다는 점을 생각하여 이러한 행위가 일어나지 않도록 우리 모두 주의를 기울여야 하겠다.


불건전한 정보 유통  |
최근에는 PC 통신이나 인터넷을 통해 특정 개인이나 기업을 비방하고 허위 사실을 퍼뜨리거나 불건전한 정보를 유통시키는 사례가 늘어나 사회적인 문제가 되고 있다. 이러한 컴퓨터 범죄는 전문 기술이 필요하지 않고, 유포시킨 사람을 찾아내기 어려우며, 피해가 광범위하게 발생한다는 점에 문제의 심각성이 있다.   이와 같은 컴퓨터 범죄들을 최소화하기 위해서는 개인과 단체, 그리고 국가가 공동으로 이들을 예방하기 위한 노력을 기울여야 한다.
개인의 노력만으로 모든 컴퓨터 범죄를 예방할 수는 없으나, 정당한 접근 권한이 없는 타인이나 단체의 컴퓨터에 불법으로 접근하지 않는 것이 무엇보다 중요하다. 또한 자신의 컴퓨터를 활용할 때에는 암호 사용을 습관화하고, 여러 가지 보안 프로그램을 활용하는 것이 개인이 실천할 수 있는 컴퓨터 범죄 예방 방법이다.





6. 자원 절약과 환경을 생각하자

개인용 컴퓨터가 처음 등장했을 때 사람들은 컴퓨터의 활용이 자원의 낭비나 환경 오염과 같은 문제를 줄여 줄 수 있을 것으로 기대하였다. 그러나 컴퓨터 활용이 급속도로 확산된 오늘날에 이르러서는 컴퓨터 활용이 오히려 자원의 낭비와 이에 따른 환경 오염을 촉진시키는 원인이 되고 있다. 
 

에너지 절약  |  자원과 환경에 관련한 가장 큰 문제는 컴퓨터가 지나치게 전기 에너지를 낭비한다는 것이다. 전기 에너지의 낭비는 전기를 생산하는 석탄이나 석유와 같은 에너지의 소모와 환경 오염을 유발한다. 국제 환경 보호 협회가 조사한 최근의 결과에 따르면 전 세계의 컴퓨터의 전체 활용 시간 중 무려 80% 정도가 컴퓨터를 사용하지 않는 상태에서 켜져 있는 것으로 밝혀졌다. 따라서, 최근에는 불필요한 전력 낭비를 줄일 수 있는 절전형 또는 자동 전원 차단형 모니터가 일반화되고 있다. 그러나 더욱 확실한 대처 방법은 장시간 동안 자리를 비울 때에는 반드시 모니터와 컴퓨터 전원을 끄는 습관을 가지는 것이다. 
 

종이의 절약  |  컴퓨터는 종이 없는 사무실을 실현해 줄 수 있음에도 불구하고 시간이 흐를수록 종이 사용량은 더욱 늘어나고 있다. 이것은 우리들 각자의 습관과 깊은 관련이 있다. 우리는 자료를 종이로 출력하기에 앞서 완벽하게 수정을 마친 후 출력하는 습관을 가져야 한다.
한 번 사용한 인쇄 용지의 이면을 활용하는 것도 종이를 절약하는 데 큰 도움이 될 수 있다.

디스켓과 토너의 재활용  |  디스켓이나 프린터 토너 등을 반복 활용하거나 재활용함으로써 예산의 절감과 환경 보호의 효과를 거둘 수 있다. 절약과 환경 보호를 위한 이러한 여러 가지 노력은 조금씩 주의를 기울이면 누구나 실천할 수 있는 것이며, 하나뿐인 지구와 우리들의 후대를 위한 가장 중요한 일임을 우리 모두 명심해야 할 것이다.

Overflow란?

Posted 2008. 10. 14. 16:54 by MINOK
※양수+양수=음수 , 음수+음수=양수 >> Overflow
※4bit + 4bit = 4bit를 초과하는 값이 발생 >> Carry

1. 1의보수
2의4제곱 개 표현가능 (16개:0이 2개)
0 1 1 1     >>  +7
    …
0 0 0 0     >>  +0
--------------
1 1 1 1     >>  -0  
    …
1 0 0 0     >>  -7

-0과 +0이 다르게 된다.

2. 2의보수 
(1의보수 +1)
2의 4제곱 -1 개 표현가능(15개:0이 1개) 

1의보수의 음수부에 1의보수를 다시 취하여 1을 더한다.
   0 1 1 1     >>  +7
       …
   0 0 0 0     >>  +0
----------------
1 0 0 0 1     >>  -1
1 0 0 1 0     >>  -2
      …        
1 0 1 1 1     >>  -7

▶최상위 비트가 받아들이는 carry와 최상위비트에서 발생되는 carry의 값이 다를 경우 overflow라고 할수있고, 같을 경우에는 단순 carry만 발생한경우라 할 수 있다.  




2X4 Decoder 설계 VHDL - case & for-loop

Posted 2008. 10. 14. 02:08 by MINOK

Decoder란?
컴퓨터 내부에서 디지털로 코드화된 데이터를 해독하여 그에 대응되는 아날로그 신호로 바꿔주는 컴퓨터 회로이다. 아날로그 데이터를 계산이 가능한 부호, 곧 각 시스템 내에서 사용하는 디지털 코드로 변환시켜 주는 인코더(encoder)의 상대용어로, 흔히 디코더(decoder)라고 한다.

1.case

case문 : 수식값에 따라 문장을 선택한다. when 의 값과 수식값이 일치하면 문장을 수행하고 그렇지 dskg으면 다음의 when의 값을 비교하여 그 문장의 수행여부를 결정한다. 수식을 여러값으로 표현할때는 ‘|’을 사용하면 된다.

<example code>

case sel is

when "00" => y <= d(0);

when "01" => y <= d(1);

when "10" => y <= d(2);

when others => y <= d(3);

end case;

>> 해석 : sel 의 값에 따라 입력단자 (d(0)~d(3))의 값이 출력 y로 연결된다.

*****************************************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-----------입출력 포트 설정------------
entity decoder_case is
port (X : in bit_vector (1 downto 0);
     CHK   : in bit;
      Y : out bit_vector (3 downto 0));
end decoder_case;
---------------------------------------
architecture sample of decoder_case is
begin
 process(X,CHK)
  begin
    if (CHK = '1') then
      case X is
       when "00" => Y <= "0001";
       when "01" => Y <= "0010";
       when "10" => Y <= "0100";
       when "11" => Y <= "1000";
      end case;
    else
      Y <= "1111";
    end if;
  end process;
end sample;

*****************************************************************************

2.For-loop

for-loop : 순차처리문이다. 루프변수가 1씩 증가 또는 감소하며 최종값에 도달할 때까지 loop문에 둘러싸인 순차처리문을 반복처리한다.

*****************************************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;

-----------입출력 포트 설정------------
entity decoder_loop is
port ( X : in std_logic_vector(1 downto 0);
       Y : out std_logic_vector(3 downto 0));
end decoder_loop;

architecture sample of decoder_loop is
begin
 process(X)
 begin  
  for i in 3 downto 0 loop
     if( X = i ) then
       Y(i) <='1';
      else
       Y(i) <='0';
      end if;
    end loop;
   end process; 
end sample;

*****************************************************************************



3. waveform file
case문과 for-loop 둘다 동일한 결과값을 갖는다.


"C" 파일이 포함된 소스라면
Project Settings->C/C++ tab ->category ->Precompiled Headers를 선택
"Not using precompiled headers"를 선택하고 다시 컴파일

debug 폴더 삭제후 컴파일
프리 컴파일 헤더는 stdafx.h 파일을 말한다.

 

'Computer Engineering > Tip' 카테고리의 다른 글

컴퓨터로 인해 발생하는 문제점 극복하기  (0) 2008.10.23
Dev C++ 설치하기  (0) 2008.03.16

GLUT Tutorial GLUT Setting

Posted 2008. 10. 13. 03:35 by MINOK

GLUT 는 OpenGL 을 위한 표준 유틸리티 툴킷입니다. 즉 OpenGL 용 어플리케이션의 개발을 편하게 할 수 있도록 도와주는 도구로 생각하면 됩니다. Mark J. Kilgard 씨가 GLUT 를 만들었는데, 그 이유는 특정 윈도우 시스템들을 알지 못해도 OpenGL 용 어플리케이션을 만들 수 있도록 하기 위해서 였죠. 너무나 고마운 일 아닙니까? Mark J. Kilgard 씨와 GLUT 에 고마워합시다~ :) GLUT 를 사용하면 X 윈도우 시스템이나 마이크로소프트의 윈도우 시스템에 대해서 배우지 않고도 OpenGL 용 어플리케이션을 만들 수 있습니다. Kilgard 씨가 X 윈도우용의 GLUT 를 만들었고 나중에 Nate Robins 씨가 마이크로소프트 윈도우즈용의 GLUT 를 만들었답니다. 우리 모두 이 두사람의 위대한 업적에 갈채를 보냅시다!

이 강좌는 GLUT 를 사용해서 어플리케이션을 만드는 방법을 설명합니다. 단, 예제의 코드를 가능한 간단하게 만들기 위해서 화려한 시각 효과 같은건 만들지 않겠습니다.

무엇이 필요한가요?

GLUT 를 이용해서 어플리케이션을 만들려면 우선 최신버전의 GLUT 가 필요해요. 당연한 얘기인가요 ;) 이 글을 쓸 때, GLUT 의 최신버전은 3.7 이었습니다. GLUT 배포판은 아주 많은 예제를 포함하고 있기 때문에 이 강좌를 다 보고 난 다음에 예제를 분석해 보는 것이 좋겠죠? 당연한 얘기입니다! :) GLUT 가 없거나 GLUT 에 대해서 궁금한 것이 있으면 GLUTs 웹페이지를 살펴보세요.


Visual C/C++ 6.0 환경 설정하기

Visual C/C++ 로 프로젝트를 만들려면 두가지를 설정해줘야 합니다. 하나는 콘솔 프로그램으로 만들 것인지 아니면 Win32 프로그램으로 만들 것인지 정해야합니다. 콘솔로 만들게 되면 어플리케이션은 두 개의 창을 갖게 됩니다. 하나는 콘솔창이고 다른 하나의 OpenGL 창이랍니다. Win32 를 선택했을 때 GLUT 를 사용하면 Win32 로 어플리케이션을 만들 때 만나게 되는 '프로그래머 혼란스럽게 하기' 란 장애물을 피해갈 수 있습니다. :) 이를 위해서 아래의 과정을 따라 하나만 바꿔주세요.

  1. 주메뉴의 Project->Settings 를 선택하세요.
  2. 대화상자에서 "Link" 탭을 선택하세요.
  3. 콤보박스의 "Category" 에서 "Output" 을 선택하세요.
  4. "Entry-point symbol" 에디트박스에 "mainCRTStartup" 이라고 입력하세요.

이미 만든 콘솔 프로젝트를 Win32 어플리케이션 프로젝트로 만들려면 아래의 과정을 따라 설정해주면 됩니다. 콘솔에서 Win32 로 바꾸는 것은 콘솔창을 만들지 않기 위해서겠죠?

  1. 위의 과정을 따라서 entry-point symbol 을 추가합니다.
  2. "Project Options" 에디트박스에서 "subsystem:console" 을 "subsystem:windows" 로 바꿔줍니다.

위의 과정을 일일이 다 해주기 귀찮다면 소스코드의 시작부분에 아래의 코드를 입력해주세요. 위의 과정과 똑같이 프로젝트를 설정해줍니다.

#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

프로젝트를 위의 과정에 따라 올바르게 설정했다면 콘솔창은 없고 OpenGL 창만 있는 어플리케이션이 만들어집니다. 두번째 설정은 GLUT 를 어플리케이션에 링크해주는 것인데 Visual C/C++ 을 사용한다면 아래의 과정을 따라 설정하면 됩니다.

  1. 주메뉴의 Project->Settings 를 선택하세요.
  2. 대화상자에서 "Link" 탭을 선택하세요.
  3. "Object/library modules" 에디트박스에 "opengl32.lib glut32.lib glu32.lib" 을 입력합니다.

주목 : glu32.lib 과 opengl32.lib 을 추가했습니다. 이 두개의 라이브러리 파일은 OpenGL 의 표준 라이브러리입니다. GLU 는 OpenGL 이 배포하는 표준 API 입니다.

모든 설정이 끝났나요? 잘 끝냈기를 바랍니다 :) 그럼 이제 GLUT 를 이용해서 어플리케이션을 만들어봅시다. 이 강좌에서 확실하지 않거나 궁금한 점이 있으면 연락해 주세요. 성실하게 답해드릴께요. 이런 강좌는 여러분들의 참여가 아주 중요하거든요.

이 강좌가 여러분들에게 도움이 되길 바랍니다. - Antonio -

 

좋은 팁!

출처: Grafix3d.net
원문 : http://www.lighthouse3d.com/opengl/glut/index.php3?1



- OpenGL의 라이브러리와 헤더

각 윈도우 시스템마다 OpenGL 렌더링을 위해 기존 윈도우 시스템의 기능을 확장시켜 주는 라이브러리가 있다.

< 해당 시스템의 라이브러리 목록 >

X Window System         
- GLX( OpenGL Extension to the X Window System ) : GLX 루틴 앞에는 glx라는 접두사를 사용.

MS Windows 95/98/NT 
-WGL( OpenGL Interface for Windows)  : WGL 루틴앞에는 wgl 이라는 접두사를 사용.

IBM OS/2                          
-PGL ( Presentation Manager to OpenGL Interface ) : PGL 루틴앞에는 pgl 이라는 접두사를 사용.

Apple                                 
-AGL : AGL 루틴앞에는 agl 이라는 접두사를 사용.

 

<헤더>

# include 파일  ( 여기서는 윈도우 중심에서 이야기하므로 윈도우환경 기준에서 설명한다. )

 : 일반적으로 OpenGL 애플리케이션을 작성할 때 gl.h 라는 헤더파일을 추가한다.

   또한 OpenGL 애플리케이션에서 GLU를 사용하기 때문에 glu.h 라는 헤더파일도 함께 추가한다.

   그래서 일반적인 윈도우즈 프로그램의 거의 모든 OpenGL 소스파일들은 다음과 같은 문장으로 시작한다.

 

/*

      MS Windows에서는 windows.h를 먼저 작성해야 하는데, 이는 gl.h와 glu.h에서 내부적으로 사용하고 있는

      일부 매크로들이 windows.h 라는 파일에도 정의되어 있기 때문이다.

*/

#include <windows.h>

#include <gl/gl.h>

#include <gl/glu.h>

 /*

    주의점 : 프로젝트 생성시, 반드시 opengl32.lib 와 glu32.lib 라이브러리를 반드시 추가해 주어야 한다.

    추가환경 : VC .net 2003 ( 프로젝트 - 속성 - 링커 - 입력 - 추가종속성 - opengl32.lib, glu32.lib 추가 )

*/

위 그림과 같이 추가해주면 된다.
 

 

- GLUT ( OpenGL Utility Toolkit )

 : GLUT 가 사용되기 이전에는 AUX( OpenGL auxiliary library : OpenGL 보조 라이브러리 ) 가 주로 사용되었다.

   AUX 라이브러리는 서로 다른 환경에서의 OpenGL 프로그래밍을 보다 편리하게 진행하도록 하기 위해 개발된 것으로, 유닉스나 윈도우즈용

   AUX 를 통해 해당 플랫폼에 OpenGL을 활용하는 과정을 돕는 역할을 했다.

   하지만 GUI 기능이 부족했기 때문에 유용한 애플리케이션을 만드는 데는 무리가 있었다.

  이후에 AUX는 GLUT로 대체되어 다양한 플랫폼에서의 프로그래밍에 사용되기 시작했는데, GLUT는 OpenGL 유틸리티 툴킷의 약자로 ,

  SGI 의 직원이었던 Mark Kilgard 에 의해 개발되었다. GLUT는 AUX의 단점이었던 GUI 기능을 추가하여 팝업 메뉴의 사용, 다른창의 관리,

  조이스틱 지원 등의 기능을 갖추었으며, 공개되어 있지는 않지만 무료이므로 사용과 배포가 자유롭다.

  GLUT 에서는 구나 토러스, 주전자 등과 같이 복잡한 3차원 오브젝트를 생성하기 위한 루틴들을 제공하고 있으며, 이러한 루틴을 사용하면 복잡한

  그림을 쉽게 그릴 수 있다.

  GLUT가 완전한 기능을 갖춘 OpenGL 애플리케이션을 제작하기에는 적합하지 않으며, 학습용으로는 충분한 제 기능을 발휘할 것이다.

  ( OpenGL SuperBible 3rd 와 OpenGL 프로그래밍 가이드 제 4판 에서는 GLUT를 사용한다. )

/*

      GLUT 의 강점은,  윈도우 콘솔모드에서 작업을 해도 GUI 창이 하나 생성되며, 자신의 프로그래밍 환경에 맞게 설정하는 과정만 거치면

      리눅스나 매킨토시에서도 사용이 가능하다는 것이다.

*/

 

- GLUT 설치와 사용법

/*

    glut.h 에는 gl.h 와 glu.h 도 포함되어 있기 때문에, 세 개의 헤더 파일 모두에 대해 include 문장을 적어줄 필요가 없다.

    glut.h 역시 MS Windows의 경우와 마찬가지로, 운영체제에 종속적인 매크로들이 정의되어 있다.

*/
#include <windows.h>

#include <gl/glut.h>

/*

   GLUT 라이브러리를 사용하기 위해서는, glut32.dll 과 glut32.lib , glut.h 파일은 웹에서 검색하면 쉽게 구할 수 있는데,

   각각 붙여넣을 파일 디렉토리는 아래와 같다. ( VC 7.0 기준 )

   glut32.dll : C:\windows\system32 에 복사.

   glut32.lib : C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib

   glut.h     : C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\gl

   물론 프로젝트 생성시, 위 그림에서 glut32.lib 하나만 더 추가해주면 된다.

*/


출처 ★최고보단 최선을 | 일퍼센트
원본 http://blog.naver.com/lemonbar80/70019880893

'Computer Engineering > Computer Graphics' 카테고리의 다른 글

GLUT Tutorial GLUT Setting  (0) 2008.10.13

Apache and Python with ModPython #2

Posted 2008. 10. 12. 22:31 by MINOK
= Python API =
여기서부터는 문서량이 너무 많기 때문에 개괄적인 내용만 번역하겠습니다. 죄송합니다. 
복수의 인터프리터 :
mod-python을 사용할 때 파이썬은 실제로 파이썬 그 자체로 쓰여진 걸로 실행되지 않습니다. C language API 실제로는 C를 통해서 호출 되는 거거든요. Python C API는 subinterpreters를 생성하도록 제공 되어집니다. 보다 자세한 내용은  Py_NewInterpreter() 함수에 대한 문서를 통해서 알 수 있습니다. Subinterpreter는 같은 아파치 서버에서 분리된 프로그램을 동작시키는데 매우 유용합니다.  둘은 간섭을 받지 않은 상태로 동작할 수 있습니다.
서버가 시작하거나 mod-python이 초기화 될 때 main함수를 호출하게 됩니다. 그리고 main 인터프리터는 subinterpreter의 자료를 가지고 있고, 처음에는 초기화 되어 있다가 요청이 오면 생성을 합니다. 그리고 계속 재사용하는 것이죠. 메인 인터프리터의 이름은 main_interpreter 이고 다른 인터프리터는 PythonInterp* 를 통해서 제어 됩니다. 기본적인 행동은 아파치의 가상 서버 이름을
통해서 이름을 짓는 것입니다. 이 뜻은 모든 스크립트가 같은 서브 인터프리터를 통해서 실행되지만 다른 건 다르게 실행된다는 말입니다. ㅋㅋ 나도 잘 몰라요! 버철 디렉토리가 틀리면 다르게 실행된다는 말 같은데, 뭐 실제로 테스트 해보지 않았으니까.
여하튼 지금 돌고 있는 인터프리터는  req.interpreter 를 통해서 알아 볼 수 있습니다. 만약 서드파트로 만들어진 C 컴포넌트
요건 Global Interpreter Lock에 접속할 수 있는 간단한 API를 쓸 수 있는 거죠. 여하튼 이건 꼭 main_interpreter에 강제로 set 되어야 합니다. 이건 모듈이 처음 만들어진 파이썬 문맥에서 실행될 수 있고요? 안그러면 에러를 내뱉는다고

Request Handler 의 개괄 설명 :
요청에 대한 단계에서 handler는 기능을 수행합니다. 아파치 처리는 요청을 읽고 헤더를 처리하고 내용을 전달합니다. 모든 단계에서 아파치 또는 modpython에서 제공하는 모듈을 지원합니다. 예를 들어 modpython에서 사용자에 의해 쓰여진 파이썬 코드를 지원합니다. 이는 C코드로 쓰여진 핸들러와 차이점이 없습니다.

핸들러 함수는 다음의 레퍼런스 객체를 리턴해 줍니다. ( 이 메뉴얼에서는 req는 request객체로 부르겠습니다.)

- apache.OK 에러 없이 처리 되었다는 메세지
- apache.DECLINED 현재 처리되는 핸들러에 의해 처리가 되지 않아 아래 핸들러에게 다시 요구를 한다는 메세지
- apache.HTTP_ERROR HTTP_ERROR가 발생했다는 메세지

핸들러는 req.write() 함수를 사용해 클라이언트 통해서 내용을 쓸 수 있습니다. 또 req.read()를 통해서는 POST 요청을 읽을 수
있습니다.
NOTE: 아파치의 디렉토리가 prepended 된다는 데.... prepended 이 단어를 모르겠음.. 사전에 안나옴...

최소한의 핸들러 예제
from mod_python import apachedef requesthandler(req):
req.content_type = "text/plain"
req.write("Hello World!")
return apache.OK

Filter Handler 의 개괄 설명 :
필터 핸들러는 서버에서 들어오고 나가는 데이터를 교체해 주는 역할을 한다. 그 종류에는 input and output 두 종류가 있다.
현재에는 mod_python은 request_level의 필터만을 제공합니다. 이 말은 HTTP request and response의 body만을 필터링함을
뜻합니다. filter handler는 filter object를 받습니다. request object는 filter.req를 통해서 사용할 수 있습니다. 하지만 모든
읽기와 쓰기는 filter 객체의 read와 write를 통해서만 할 수 있습니다. filter는 읽기 객체가 none 객체를 반환하면 닫아야 합니다.
필터의 리턴값이 무시된다. 필터는 핸들러처럼 수행하지 않지만 filter.pass_on()을 통해서 같은 효과를 얻을 수 있습니다.

필터는 꼭 PythonInputFilter 또는 PythonOutputFilter 을 등록해야 하고, Apache Add/SetInputFilter 또는 Add/SetOutputFilter 디렉토리에 들어있어야 합니다.
다음은 outfilter의 전형적인 예입니다. 서버의 모든 .py는 CAPITALIZE 필터를 수행합니다.

PythonOutputFilter capitalize CAPITALIZE
AddOutputFilter CAPITALIZE .py

여기 capitalize.py 코드가 있습니다.

from mod_python import apache
    def outputfilter(filter):
    s = filter.read()
    while s:
        filter.write(s.upper())
        s = filter.read()
        if s is None:
        filter.close()

필터를 프로그래밍할 때는 이 필터가 몇번이고 불려질 수 있다는 점을 기억하라. 예를 들어 하나의 request는 몇번의 필터가 불리어 질 수 있다는 점이 있다. EOS( None returened from a read operation )이 오기 전까지는 계속 불려질 수 있다.

Connection Handler의 개괄 설명 :
커넥션 핸들러는 커넥션을 관리합니다. TCP 커넥션 포인트에서 즉시 시작합니다. HTTP 핸들러와는 다르게 커넥션 핸들러는
Argument를 Connection 을 받습니다. 여기 echo server 의 예가 있습니다.

아파치 서버 셋팅은 다음과 같이 합니다.:
PythonConnectionHandler echo

echo.py 코드는 다음과 같습니다.
from mod_python import apache
    def connectionhandler(conn):
    while 1:
        conn.write(conn.readline())
        return apache.OK


아파치 설명 :
mod_python에서는 아파치 내부에 대한 인터페이스를 제공합니다. 정말 많은 기능을 제공하므로 직접 문서를 읽어보세요.

유틸 / 기타 유틸리티들 :
util 모듈은 웹 개발자에게 유용한 유틸리티들을 제공합니다. 이 유틸리티들은 standard CGI에서와 같은 기능을 제공하고
이는 아파치의 CGI를 직접 호출하기 때문에 보다 더 효율적입니다.
다음과 같은 유틸리티가 있습니다.
FieldStorage Class
Field Class

쿠키 HTTP 상태 관리자 :
넷스케이프에서 표준화된 쿠키를 읽고 저장하는 기능을 합니다.
쿠키 클래스를 사용해서 HTTP State Management 기능을 수행합니다.
여기 예제가 있습니다.
from mod_python import Cookie, apache
import time
    def handler(req):
        cookie = Cookie.Cookie(’eggs’, ’spam’)
        cookie.expires = time.time() + 300
        Cookie.add_cookie(req, cookie)
        req.write(’This response contains a cookie!\n’)
        return apache.OK


세션 :
세션 모듈은 지속적인 연결을 유지할 수 있게 해줍니다.
이 세션 모듈은 BaseSession 클래스를 사용합니다. 하지만 이 클래스를 바로 사용하는 것이 아니라, DbmSessoin 또는
FileSession을 사용해서 접근합니다.
예제는 아래와 같습니다.
from mod_python import Session
    def handler(req):
        session = Session.Session(req)
        try:
            session[’hits’] += 1
        except:
            session[’hits’] = 1
            session.save()
            req.content_type = ’text/plain’
            req.write(’Hits: %d\n’ % session[’hits’])
            return apache.OK


PSP 파이선 서버 페이지 :
파이썬을 ASP나 PHP 처럼 서버사이드 스크립트로 사용할 수 있게 만들어주는 모듈입니다.

= 아파치 설정 지시문 =
아파치 핸들러에 대한 지시문을 설명합니다.
대략 4가지로 나누어집니다. 첫째, Request handler 둘째,Filter 셋째, Connection Handler 넷째, 기타들...
각각은 다음과 같은 문법으로 표현됩니다.
Syntax: Python*Handler Syntax
Context: server config, virtual host
Override: not None
Module: mod python.c

너무 많아서 자세한 사항은 지시문을 읽어보세요.

= 서버 사이드 파이썬 코드 =
파이썬 코드를 HTML에 직접 입력해서 사용할 수 있도록 만들어진 페이지입니다. SSI는 다음과 같은 문법을 갖습니다.
<!--#element attribute=value attribute=value ... -->
3.3 버전 이전 mod_python에서는 SSI를 지원하지 않습니다. 그리고 아파치는 옵션에서 IncludesNOEXEC 를 off로 만들어줘야
합니다. 그렇지 않으면 SSI는 실행 되지 않습니다.

다음은 Global Data에 대한 SSI에 대한 예제입니다.
<!--#python exec="
import cgi, time, os
    def _escape(object):
    return cgi.escape(str(object))
now = time.time()
" -->
<html>
<body>
<pre>
<!--#python eval="_escape(time.asctime(time.localtime(now)))"-->
<!--#python exec="
keys = os.environ.keys()
keys.sort()
for key in keys:
    print >> filter, _escape(key),
    print >> filter, ’=’,
    print >> filter, _escape(repr(os.environ.get(key)))
" -->
</pre>
</body>
</html>

대충 알것 같지 않은가? Global Data를 접근하기 위해서는 아파치의 multithread를 사용해야 한다고 합니다.

= 파이썬 기본 핸들러 =
개발 방법이 참 많다. 기본 핸들러는 빠른 개발을 위해 Zope에서 영감을 받아 만들어졌다.

기본 핸들러는 3가지가 있다. Publisher,PSP,CGI
우선 Publisher를 살펴보자.
아파치 셋팅은 다음과 같이 한다.
<Directory /some/path>
    SetHandler mod_python
    PythonHandler mod_python.publisher
</Directory>

코드는 다음과 같다. hello.py
""" Publisher example """
    def say(req, what="NOTHING"):
    return "I am saying %s" % what
다음의 URL로 접근하면 http://www.mysite.com/hello.py/say  ‘I am saying NOTHING’. 를 반환하고
다음의 URL로 접근하면
http://www.mysite.com/hello.py/say?what=hello‘I am saying hello’.  반환한다.
Form Data는 FieldStorage 클래스를 생성하고 이 클래스를 통해 Request 객체의 form 속성에 저장됩니다.
다음으로 PSP 핸들러를 알아보자.
Python Server Page를 만들려면 아래처럼 http.conf에 셋팅합니다.
AddHandler mod_python .psp
PythonHandler mod_python.psp

디버깅을 위해서는 아래처럼 만듭니다.
AddHandler mod_python .psp .psp_
PythonHandler mod_python.psp
PythonDebug On

언더바를 붙이는 이유는 원래의 코드를 얻을 수 있기 때문에 디버깅에 도움이 된다고 합니다.

마지막으로 CGI 핸들러를 알아보자.
mod_python에서 CGI를 다루기 위해 에뮬레이팅하는 핸들러입니다.
.htaccess에 다음의 줄을 추가시켜줍니다.
SetHandler mod_python
PythonHandler mod_python.cgihandler


= 보안 =
보안에 대한 설명은 modpython의 categorysecury를 참조하세요.

Apache and Python with ModPython #1

Posted 2008. 10. 12. 22:31 by MINOK
아파치와 모드파이썬을 통한 파이썬 설정
Mod_python Manual Release 3.3.1


written by Gregory Trubetskoy

= 소개 =

모드 파이썬은 아파치와 연결된 파이썬 CGI를 보다 빠른 수행을 할 수 있도록 도와주는 라이브러리입니다.
일반 CGI를 사용할 경우와 Modpython을 사용할 경우의 성능차이를 보면 PDF문서에는
Standard CGI : 1초당 23개의 요구를 수행
Mod_python cgihandler : 1초당 385개의 요구를 수행
Mod_python publisher : 476개의 요구를 수행
Mod_python handler : 1203개의 요구를 수행한다는 결과가 있습니다. 성능의 테스트가 된 환경에는
펜티엄 1.2기가 레드핫 리눅스 7.3을 바탕으로 했다고 하네요.
Mod_python의 유연성은 생략, 역사도 생략, 궁금하면 PDF를 보세요.

= 설치 =

요구 사항 :
파이썬 2.3.4 또는 이 상위버전, 파이썬 2.3 하위 버전에는 돌지 안돌지 모르겠다고 하네요. 아파치 2.0.54 버전에서 최적화 되어 있습니다. 다른 버전의 아파치에서도 돌아가긴 해 봤지만 릴리즈 테스트는 하지 않았다고 하네요. 그러니 최적화된 버전을 사용합시다. 리눅스의 배포판에 따라서 이미 설치 되어 있는 버전도 있다고 합니다. 레드핫이나 솔라리스 패키지에 있으니가 그냥 설치하시면 된다고 합니다. 그리고 어떤 패키지는 "development"(개발 패키지)에 분리되어 있다고 합니다. 혹시 어떤 파일이 필요한지 모르면 소스 코드를 컴파일 하라고 하네요. 정말? 또는 개발 패키지 도움말에 나오니까 읽어보라고 하네요 ^^.

컴파일 하기 :
컴파일해서 아파치에 연결하는 방법에는 정적인 방법과 동적인 (DSO) 방법이 있다고 하네요. modpython은 동적인 방법을 권장한다고 합니다. http://httpd.apache.org/docs-2.0/dso.html 동적인 방법이 좋은 이유가 설명 되어 있다고 합니다. 재 컴파일 없이 모듈을 쓸 수 있다는 장점이 있다네요. 정적인 방법은 구식이라 생략합니다. ㅎㅎ

인스톨 하기 :
인스톨은 su에 make를 통해서 하고 설정하는 방법은 우선 LoadModule에
LoadModule python_module libexec/mod_python.so
Mutex 디렉토리는 기본적으로 컴파일시에 옵션 /configure --with-mutex-dir 을 통해서 정할 수 있다.
또는 아파치 셋팅에서 PythonOption mod_python.mutex_directory "/tmp" 을 통해서도 설정할 수 있습니다.
Mutex Locks 셋팅 뮤텍스는 mod_python에서 세션을 관리하기 위해 사용 됩니다. 기본값은 8입니다.
한데 시스템마다 다르고 권장하는 최대는 32이라고 합니다. 아파치 셋팅에서 값을 변경하기 위해서는
PythonOption mod_python.mutex_locks 8 을 통해서 설정할 수 있습니다.

테스트 하기 :


  1. 아파치를 통해서 볼 수 있는 디렉토리를 확인합니다. 보통 htdocs/test 이겠죠. 아니면 localhost로 접속해 보시던가요.
  2. 그리고 다음의 셋팅을 아파치 셋팅 파일 또는 .htaccess 파일에 저장합니다.
        <Directory /some/directory/htdocs/test>
            AddHandler mod_python .py
            PythonHandler mptest
            PythonDebug On
        </Directory>

  3. 이 리다이렉트는 .py로 끝나는 URL에 대해서 연결을 합니다.
  4. 수정한 환경파일이 적용 된 것을 확인하기 위해 아파치 서버를 재부팅합니다.
  5. 그리고 폴더(/htdocs/test)에 다음과 같은 코드(mptest.py)를 저장합니다.
         from mod_python import apache
        def handler(req):
            req.content_type = 'text/plain'
            req.write("Hello World!")
            return apache.OK

  6. 그리고 URL에 mptest.py를 입력하면 'Hello World!' 라는 문자열을 볼 수 있습니다. 만약 볼 수 없다면 문제 해결 페이지를 보세요.
  7. 만약 보다 많은 handler file이 필요하다면 예를 들어 handler1.py 또는 handler2.py 등과 같은 그러면 mod_python publisher 3.1 을 살펴봅니다.
  8. 모든게 완료되었으면 튜토리얼로 갑니다!

해결 하기 :
문제가 생기면 다음과 같은 방법으로 문제를 확인합니다. ㅎㅎ
에러 메시지 확인하기.
서버 에러 로그 확인 하기.
아파치를 커맨드 라인을 통해 싱글 프로세스 모드로 실행합니다.
./httpd -X
그러면 보다 유용한 정보를 알 수 있다고 합니다.
httpd.conf 파일에 아래의 글을 넣어 테스트 핸들러를 수행 할 수 있습니다.
    <Location /mpinfo>
      SetHandler mod_python
      PythonHandler mod_python.testhandler
    </Location>

그리고 브라우저를 통해 http://localhost/mpinfo 통해 에러정보를 알아 봅니다.
이도 저도 아니면? 아파치 버전이나 파이썬 버전 설정파일 코드등을 뭐 그런거 알아보라고 합니다. 당연히!

= 튜토리얼 =
이 튜토리얼을 읽어보고 Python API도 꼭 읽어 보라고 합니다. 왜? 중요한까!
Publisher Handler를 통해 빨리 알아보기 :
이 글은 Publisher Handler가 어떻게 동작하는지 빨리 간단히 알아보자 합니다. 더 자세한 내용은 마지막에 어떻게 작동하는지 설명하겠습니다. publisher handler는 표준 mod-python 입니다. 사용하기 위해서는 아파치에 아래처럼 셋팅합니다.

  AddHandler mod_python .py
  PythonHandler mod_python.publisher
  PythonDebug On

여기서는 간단히 피드백 폼을 만들어 보겠습니다. 이름하고 이메일 물어보고 관리자에게 보내지는 그런 폼이요. HTML 파일은
아래 처럼 만들어서 서버에 저장하면 됩니다.

  <html>
      Please provide feedback below:
  <p>                          
  <form action="form.py/email" method="POST">

      Name:    <input type="text" name="name"><br>
      Email:   <input type="text" name="email"><br>
      Comment: <textarea name="comment" rows=4 cols=20></textarea><br>
      <input type="submit">

  </form>
  </html>

HTML에 action을 form.py/email로 합니다. 그리고 우리는 form.py를 만들면 됩니다.

import smtplib

WEBMASTER = "webmaster"   # webmaster e-mail
SMTP_SERVER = "localhost" # your SMTP server

def email(req, name, email, comment):

    # make sure the user provided all the parameters
    if not (name and email and comment):
        return "A required parameter is missing, \
               please go back and correct the error"

    # create the message text
    msg = """\
From: %s                                                                                                                                          
Subject: feedback
To: %s

I have the following comment:

%s

Thank You,

%s

""" % (email, WEBMASTER, comment, name)

    # send it out
    conn = smtplib.SMTP(SMTP_SERVER)
    conn.sendmail(email, [WEBMASTER], msg)
    conn.quit()

    # provide feedback to the user
    s = """\
<html>

Dear %s,<br>                                                                                                                                      
Thank You for your kind comments, we
will get back to you shortly.

</html>""" % name

    return s

자 이렇게 쓰고 전송 버튼을 누르면 Publisher handler는 form 모듈의 email 함수를 호출합니다. 그리고 form 필드의 키워드 전달자에 값을 전달합니다. 이는 req라고 불리우는 request object를 통해서 전달됩니다. 그리고 데이터는 return 을 통해서 브라우저에 되돌려 집니다. publisher handler는 전달자를 보내기에 충분히 좋다고 하네요. 이는 파이썬을 간단히 써서 프로그램을 강력하게 만들어준답니다. 하지만 이걸 쓰고 싶지 않으면 native mod_python을 써서도 동일한 작동을 하게 만들 수 있다고 합니다.
예를 들어 사용자 header를 쓰고 싶으면 req.headers_out 를 써도 되고 apache.SERVER_ERROR 를 쓸 수도 있습니다.

아파치가 Requests 핸들하는 방법 빨리 알아보기 :
mod_python의 기능을 좀 더 깊이 알아보기 위해서는 아파치 handler가 하는 일을 알아야 합니다. 정말?
아파치는 몇개의 단계를 거쳐서 처리를 합니다. 먼저 사용자를 인증하고 사용자가 파일에 접촉할 수 있는지 검증하고 그리고
파일을 읽어서 사용자에게 보냅니다. 전형적인 정적 파일의 요청은 3가지의 단계를 거칩니다. 우선 파일의 위치를 URI로 변경하고
파일을 읽은 후에 클라이언트에게 보내고, 로그를 남깁니다. 오우! 뭐 이런 단계는 아파치 설정을 어떻게 하느냐에 따라 다르겠지만
여하튼 기본적으로는 그렇다고 합니다. handler는 첫번째 단계를 처리하는 기능입니다. 각 단계를 처리하는 하나 이상의 handler가
있을 수도 있습니다. 각각의 단계는 기본적으로 아파치의 handler를 사용하고 추가적인 handler는 아파치 모듈을 통해 지원됩니다.
mod_python 처럼요. mod_python은 아파치의 사용가능한 모든 handler를 지원합니다. 물론 아파치 서버 셋팅에 따라 다르겠지만요. Python이라고 시작하고 Handler라고 끝나는 단어는 예를 들어 PythonAuthenHandler 처럼 그 단계와 연결 됩니다. 그래서
mod_python의 분배자(dispatcher)는 아파치 핸들과 파이썬 함수에게 act 를 분해합니다. 흔히 쓰이는 건 PythonHandler 겠죠.
이건 요청의 단계에 작동하고 딱히 이름이 없기 때문에 generic handler라고 합니다. 이 Handler의 아파치 기본 행동은 파일을 읽고 클라이언트가 볼 수 있게 보내주는 것 입니다. Apache Directives 를 보면 더 자세하게 나옵니다. 그럼 ^^

Mod-python이 정말 뭘하는 건가? :
자! 자! 자! 우리가 아래와 같은 아파치 셋팅을 가지고 있다고 가정합시다.
  <Directory /mywebdir>
      AddHandler mod_python .py
      PythonHandler myscript
      PythonDebug On
  </Directory>

/mywebdir 은 절대 경로라고 생각하고요.
그리고 우리는 myscript.py라는 프로그램을 가지고 있다고 합시다. myscript.py는 아래의 코드에 나옵니다.

from mod_python import apache
def handler(req):
    req.content_type = "text/plain"
    req.write("Hello World!")
    return apache.OK

그럼 우선 AddHandler부터 설명하는 이건 뭐하는 걸까요? 요건 아파치에게 .py를 확장자로 같는 파일에 대해서는 mod_python이 처리하도록 해줍니다. PythonHandler myscript 이건 파이썬에게 generic handler로 myscript.py를 처리하라는 말입니다. 그리고 PythonDebug는 사용자가 사용하다가 에러메시지를 볼 수 있도록 설정해주는 겁니다. 개발할때 매우 유용합니다.
그럼 요청이 들어오면요! 아파치는 mod_python의 요청을 담당하는 handler를 호출합니다. 그리고 어떤 handler가 담당할지 정합니다. 기억하세요. 이는 dispatcher 처럼 행동한 답니다. 우리 예제에서는 모든 handler에 대해서 (예외 generic handler) 아무런 작동도 안한답니다. 우리가 generic handler를 얻으면 mod_python은 PythonHandler myscript를 알리고 아래의 단계로 작동합니다.





  1. 작업한게 있다면, 디렉토리를 sys.path 의해 찾아집니다.

  2. myscript 안에 모듈을 로딩한다. 만약 myscript가 하위폴더에 있을 경우에는 PythonHandler subdir.myscript를 통해서 호출합니다.

  3. myscript안에 불리어질 함수를 찾습니다.

  4. 함수를 호출하고 요청 객체(request object)를 전달합니다.

  5. 이 시점에서 스크립트 안을 살펴볼까요? 볼까나?





  • from mod_python import apache
    아파치 모듈을 불러옵니다. 예외가 있기는 하지만 거의 mod_python 함수는 이 라인을 가지고 있습니다.



  • def handler(req):handler 함수 입니다. mod_python은 handler를 호출합니다. 왜나햐면 mod_python이 이 이름으로 명령을 수행하기
    때문입니다. 이건 소문자로 바뀌고 python.이라는 문자를 제거합니다. 고로 PythonHandler는 handler가 됩니다.
    만약 다른 특정한 이름을 원한다면 '::'를 씁니다. 예를 들어 handler 함수가 spam이면 PythonHandler myscript::spam
    이라고 써줍니다. 모든 함수는 최소 하나의 request object를 가져야합니다. request 객체는 현재 요청에 대한
    모든 정보를 제공합니다. 예를 들어 IP나 URI 또는 헤더정보 등등등... 그리고 request 객체를 통해 요청이
    완료 됩니다. request 객체는 있지만 response 객체는 없습니다.



  • req.content_type = "text/plain"이건 컨텐츠 정보입니다. 기본은 'text/html' 이고 우리 handler는 어떤 html 을 생성하는게 아니므로 그냥 plain
    이 더 적절합니다. 중요!!!!!!!! 이건 꼭 req.write 이전에 있어야 합니다. 만약 먼저 오게 되면 HTTP 헤더를 단순히 잃어버립니다.



  • req.write("Hello World!")
    뭐 설명이 필요한가요. Hello World를 찍겠다는 뜻입니다.



  • return apache.OK
    아파치 서버에 모든게 OK 다 라고 표시해주는 겁니다. 만약 뭔가 잘못됐으면 return apache.HTTP_INTERNAL_SERVER_ERROR
    return apache.HTTP_FORBIDDEN. 이걸 반환해 줍니다. 그럼 아파치는 로그를 남기고 사용자를 에러를 보게 됩니다.
    잠깐 헛소리: 만약 특정한 파일이 아파치에 연결되지 않았다면 그냥 아무파일이나 연결됩니다. 고로 a.py건 myscript.py건 이름은
    별로 중요하지 않습니다.


쫌 더 복잡한 이야기, 인증! :
이제 원초적인 Handler가 어떻게 작동하는지 알았습니다. 그런가? 그럼 이제 좀 더 복잡한 인증에 대해 알아보겠습니다.
인증이라! 자, 먼저 우리는 이 디렉토리에 암호를 걸기를 원합니다. 그러기 위해서는 우린 먼저 PythonAuthenHandler를 더합니다.
그럼 아래처럼 셋팅이 변경 되겠죠?
  <Directory /mywebdir>
      AddHandler mod_python .py
      PythonHandler myscript
      PythonAuthenHandler myscript
      PythonDebug On
  </Directory>
같은 스크립트가 두개의 다른 handler를 갖고 있습니다. 하지만 괜찮습니다. 이건 modpython이 다른 함수를 찾습니다.
이제 HTTP 기본인증을 하겠다는 말이죠!  오직 허락된 자만을 위해! 아래와 같습니다.
  <Directory /mywebdir>
     AddHandler mod_python .py
     PythonHandler myscript
     PythonAuthenHandler myscript
     PythonDebug On
     AuthType Basic
     AuthName "Restricted Area"
     require valid-user
  </Directory>

" AuthAuthoritative or AuthBasicAuthoritative "를 통해 아파치 인증에 기댈 수 있습니다. 날 인증 시켜줘!
이제 인증을 위한 python 코드를 짜볼까요?
from mod_python import apache

def authenhandler(req):
    pw = req.get_basic_auth_pw()
    user = req.user
    if user == "spam" and pw == "eggs":
       return apache.OK
    else:
       return apache.HTTP_UNAUTHORIZED

함수는 이제 authenhandler를 찾습니다.  하나씩 따져 볼까요?
def authenhandler(req):
함수를 정의합니다. 앞에서 얘기했던것처럼 python 뺀 이름인 authenhandler입니다. 그리고 소문자로 바꿔주고!
    pw = req.get_basic_auth_pw()
이제 암호를 얻습니다. 이건 HTTP 인증을 통해서 base64 인코딩된 값입니다. 이걸 디코딩해서 문자열로 반환해 줍니다.
이 함수는 사용자 이름을 얻기 전에 호출해 줘야 합니다.
    user = req.user
사용자 이름을 얻습니다.
    if user == "spam" and pw == "eggs":
사용자가 spam 이고 암호가 eggs면 OK 그리고 아파치의 다음 단계로 갑니다.
        return apache.OK
    else:
        return apache.HTTP_UNAUTHORIZED



인증 실패를 반환해 줍니다. 그러면 브라우저로 아이디하고 패스워드를 묻는 걸 팝업해주면 되겠죠?

당신만의 404 에러 핸들링 :
이제 당신은 아마도! 404 HTTP_NOT_FOUND를 리턴하고 싶을 지도 모릅니다. 또는 202 결과를 당신의 Handler에서
리턴하고 싶을지도... 여하튼 여기 꽁수가 하나 있습니다. 아파치가 하겠지만 당신이 원하면 프로그램적으로 에러 페이지를
대체할 수 있습니다. 그때는 req.status = apache.HTTP_NOT_FOUND 해주고 당신의 페이지를 대체하고 ok 때려주면 됩니다.
   from mod_python import apache

   def handler(req):
      if req.filename[-17:] == 'apache-error.html':
         #  make Apache report an error and render the error page
         return(apache.HTTP_NOT_FOUND)
      if req.filename[-18:] == 'handler-error.html':
         #  use our own error page
         req.status = apache.HTTP_NOT_FOUND
         pagebuffer = 'Page not here.  Page left, not know where gone.'
      else:
         #  use the contents of a file
         pagebuffer = open(req.filename, 'r').read()

      #  fall through from the latter two above
      req.write(pagebuffer)
      return(apache.OK)

만약 다른 reponse handler에서 에러메시지를 반환하고 싶을 때에는 OK 대신 apache.DONE을 꼭 반환합니다. 그렇지 않으면
subsequent handler 가 계속 돌고 있을 껍니다. DONE 메시지는 처리를 바로 끝내라는 뜻입니다. 이건 이어지는
subsequent handlers를 방지할 수 있습니다.

mime type 입니다.

MIME에서 제공하는 content-type에는 'text', 'image', 'audio', 'video', 'message', multipart', 'application'의 총 7가지가 존재하며 각 content-type마다 sub-type이 존재합니다.

Text의 sub-type으로는 'plaintext'와 'richtext'가 존재합니다.
Image의 sub-type형태로는 'gif'포맷과 'jpeg'포맷이 존재합니다.
Audio의 sub-type으로는 'basic'이 있습니다.
Video의 sub-type으로 'mpeg'이 존재합니다.

Application
액셀 화일이라든지, 파워 포인트 화일등을 표시 할수 있습니다.

질문자 께서 문의 하신내용은
Content-Type= text/plain에서 text/plain은 일반적인 평문의 글을 의미하며,html도 이에 해당 합니다.

퍼옴..^^
첫번째줄의 내용은 MIME-Type
두번째줄의 내용은 어떤 화일인지 부연 설명
세번째중의 내용은 화일의 확장자 입니다.
참고 하세요.
application/acad
AutoCAD drawing files
dwg

application/clariscad
ClarisCAD files
ccad

application/dxf
DXF (AutoCAD)
dxf

application/msaccess
Microsoft Access file
mdb

application/msword
Microsoft Word file
doc

application/octet-stream
Uninterpreted binary
bin

application/pdf
PDF (Adobe Acrobat)
pdf

application/postscript
PostScript, encapsulated PostScript,
Adobe Illustrator
ai, ps, eps

application/rtf
Rich Text Format file
rtf rtf

application/vnd.ms-excel
Microsoft Excel file
xls

application/vnd.ms-powerpoint
Microsoft PowerPoint file
ppt

application/x-cdf
Channel Definition Format file
cdf

application/x-csh
C-shell script
csh csh

application/x-dvi
TeX
dvi dvi dvi

application/x-javascript
JavaScript source file
js

application/x-latex
LaTeX source file
latex

application/x-mif
FrameMaker MIF format
mif

application/x-msexcel
Microsoft Excel file
xls

application/x-mspowerpoint
Microsoft PowerPoint file
ppt

application/x-tcl
TCL script
tcl

application/x-tex
TeX source file
tex

application/x-texinfo
Texinfo (emacs)
texinfo, texi

application/x-troff
troff file
t, tr, roff t, tr, roff

application/x-troff-man
troff with MAN macros
man

application/x-troff-me
troff with ME macros
me

application/x-troff-ms
troff with MS macros
ms

application/x-wais-source
WAIS source file
src

application/zip
ZIP archive
zip

audio/basic
Basic audio (usually m-law)
au, snd

audio/x-aiff
AIFF audio
aif, aiff, aifc

audio/x-wav
Windows WAVE audio
wav

image/gif
GIF image
gif

image/ief
Image Exchange Format file
ief

image/jpeg
JPEG image
jpeg, jpg jpe

image/tiff
TIFF image
tiff, tif

image/x-cmu-raster
CMU Raster image
ras

image/x-portable-anymap
PBM Anymap image format
pnm

image/x-portable-bitmap
PBM Bitmap image format
pbm

image/x-portable-graymap
PBM Graymap image format
pgm

image/x-portable-pixmap
PBM Pixmap image format
ppm

image/x-rgb
RGB image format
rgb

image/x-xbitmap
X Bitmap image
xbm

image/x-xpixmap
X Pixmap image
xpm

image/x-xwindowdump
X Windows Dump (xwd)
xwd

multipart/x-gzip
GNU ZIP archive
gzip

multipart/x-zip
PKZIP archive
zip

text/css
Cascading style sheet
css

text/html
HTML file
html, htm

text/plain
Plain text
txt

text/richtext
MIME Rich Text
rtx

text/tab-separated- values
Text with tab-separated values
tsv

text/xml
XML document
xml

text/x-setext
Struct-Enhanced text
etx

text/xsl
XSL style sheet
xsl

video/mpeg
MPEG video
mpeg, mpg, mpe

video/quicktime
QuickTime video
qt, mov

video/x-msvideo
Microsoft Windows video
avi

video/x-sgi-movie
SGI movie player format
movie

'Computer Engineering > DataBase' 카테고리의 다른 글

Apache and Python with ModPython #2  (0) 2008.10.12
Apache and Python with ModPython #1  (0) 2008.10.12

« PREV : 1 : 2 : 3 : NEXT »