
'공부이야기/Network'에 해당되는 글 23건
- 2008.05.21
- 2008.05.21
- 2008.05.19
- 2008.05.16
- 2008.04.03
- 2008.04.02
- 2008.04.02
- 2008.04.02
- 2008.04.02
- 2008.04.02
네트웍에서 Nagle 알고리즘은 "가능하면 조금씩 여러번 보내지말고 한번에 많이 보내라(Effective TCP)" 라는 원칙을 기반으로 만들어진 알고리즘입니다.
WinSock 의경우 기본으로 Navle 알고리즘이 적용이 되어있습니다. 하지만 몇몇 네트웍 관련 프로그램에서는 네트웍 의 전송량이나 부하보다는 빠른 응답속도를 더 중요시 여기는 상황이 있습니다. 그러한때에는 TCP_NODELAY 라는 옵션을 사용하여 Nagle 알고리즘을 제거 할 수 있습니다.
해당 코드를 적용하는 방법은
int nValue = 1;
setsockopt( TCP_NODELAY, &nValue, sizeof(int), IPPROTO_TCP );
의 코드를 사용합니다.
아래는 100Byte 의 패킷을 5번에 걸처서 보내고 에코로 받은 결과입니다.
Nagle 알고리즘 적용 (default) : 100~150ms
Nagle 알고리즘 해제 : 1~3 ms
하지만 해당 옵션의 사용은 네트웍 부하를 극대화 시켜주면서 서버의 전체적인 성능을
무척감소하기때문에 꼭 필요한경우에만 매우 주의를 해서 사용해야 합니다.
추가로 "Effective TCP Programming" 역시 추천도서입니다. ^^
네트웍 프로그램을 향상하는 44가지 팁이라고 하는데 저의 경우
15개정도의 팁만이 쓸모가 있더군요.
[디스크 Quota]
다중 사용자를 환경으로 하는 Linux 환경에서 특정 사용자가 시스템의 모든 디스크를 독점하여 사용하게 된다면 큰일이다.
한 사용자에 의해서 독점되는 시스템 자원으로 인해서 다른 사용자는 하고자 하는 작업을 할 수가 없게 된다.
특히, 웹 호스팅을 하는 업체와 같은 경우에는 사용자에게 일정한 디스크 용량만을 사용할 수 있게 하는 기능이 필수적이라고 할 수 있다.
웹 호스팅을 하는 서버의 경우 보통 적게는 100명 많게는 200명의 사용자가 홈페이지를 운영하고 있기 때문에 제한된 자원을 모든 사용자가 사용할 수 있도록 해주어야 한다.
이러한 요구 사항을 충족하기 위해서 사용하는 기능이 디스크 Quota 기능이다. 쿼터 기능을 사용해서 관리자는 사용자마다 일정한 디스크 용량만을 사용할 수 있도록 할 수 있기 때문에 효율적으로 하드 디스크 공간을 사용할 수 있다.
그러면 Quota 기능을 어떻게 설정하고 사용하는지에 대해서 알아보도록 하자.
[ TIP : ]
Window NT 4.0의 경우에는 이 Quota 기능이 없어서 사실상 웹 호스팅을 하거나 많은 사람에게 디스크를 사용하게 한다는 것은 거의 불가능한 일이었다.
필자의 경우는 여러 사람에게 디스크 공간을 한정되게 주기 위해서 파티션을 나누어서 제공한 적이 있다.
그러나 윈도우 2000부터는 쿼터 기능이 지원되기 때문에 요즈음 윈도우 2000과 ASP를 사용해서 웹 호스팅을 하는 업체가 부쩍 늘고 있다.
[출처] 리눅스 공부 - 디스크 Quota|작성자 길당
CGI(Common Gateway Interface) 서버와 클라이언트를 연결해 주는 프로그램을 통칭하며
스크립트형 프로그래밍 언어( ASP,php,jsp,perl 등)가 cgi에 속합니다.
사전적인 설명은 아래와 같습니다.
사용자가 서버에게 웹페이지를 통한 요청이 있었을 때,
그것이 응용프로그램에 의해 처리 될 필요가 있다면
서버가 응용프로그램을 실행시키고 필요한 메시지를 받는다.
이 때 서버와 응용프로그램 사이에 데이터를 주고 받기 위한 표준화된 방법을 CGI라고 합니다.
CGI의 특징은
아무 서버에서나 사용가능하고 세션이라는 개념대신 쿠키를 사용합니다.
유닉스/리눅스 명령어 레퍼런스
파일 명령어
ls - 디렉토리 목록보기
ls -al - 숨은 파일까지 정렬된 형태로 보기
cd dir - dir 디렉토리로 이동
cd - home 디렉토리로 이동
pwd - 현재 위치한 디렉토리 보여주기
mkdir dir - dir라는 디렉토리 만들기
rm file - file을 지우기
rm -r dir - dir 디렉토리를 지우기
rm -f file - 강제로 file 삭제
rm -rf dir - dir 디렉토리와 디렉토리 아래에 있는 모든 파일 삭제
cp file1 file2 - file1을 file2라는 이름으로 복사
cp -r dir1 dir2 - dir1 디렉토리에 있는 것들을 dir2 디렉토리로 복사; dir2가 존재하지 않는다면 만듬
mv file1 file2 - file1을 file2로 이름을 바꾸거나 옮김,
file2가 디렉토리로 존재한다면 file1을 file2 디렉토리로 옮김
ln -s file link - file로 연결된 link라는 심볼릭 링크를만듬
touch file - file을 생성하거나 업데이트
cat > file - 입력을 file로 저장
more file - file의 내용을 출력
head file - file의 첫 10줄을 출력
tail file - file의 마지막 10줄을 출력
tail -f file - file에 추가되는 내용을 출력,마지막10줄부터 출력함
프로세스 관리
ps - 현재 활성화된 프로세스 보여주기
top - 실행중인 모든 프로세스 보여주기
kill pid-프로세스id pid를 종료
killall proc - proc로 시작하는 모든 프로세스 종료
bg - 정지되있거나 화면에서 안보이게 실행중인 프로세스 보여주기; 정지된 프로세스를 화면에 출력하지 않고 계속 진행하기
fg - 화면에 보이지 않게 작동하던 작업 중 최근의 것을 화면에출력하면서 작동시키기
fg n - 화면에 보이지 않게 작동하던 작업 중 n 번째 작업을 화면에 출력하면서 작동시키기
파일 퍼미션
chmod 숫자 file - file의 퍼미션값을 숫자로 바꿈. 숫자는 3자리이며 첫 번째는 소유자,두 번째는 그룹,
세 번째는 익명의권한을 더해서 나타냄.
파일 퍼미션
chmod 숫자 file - file의 퍼미션값을 숫자로 바꿈. 숫자는 3자리이며 첫 번째는 소유자,두 번째는 그룹, 세 번째는 익명의
권한을 더해서 나타냄.
SSH
ssh user@host - user로 host에 접속
ssh -p 포트넘버 user@host - host의 지정한 포트넘버에
user로 접속
ssh-copy-id user@host-사용자명,암호를 입력하지 않고
로그인 할 수 있도록 ssh key를 복사
검색
grep pattern files - file안의 pattern을 찾기
grep -r pattern dir - dir 디렉토리 안에서 재귀적으로pattern 찾기
command | grep pattern - command 명령의 출력에서pattern을 찾는다
locate file - 파일을 찾음
시스템 정보보기
date - 현재 날짜와 시각을 출력
cal - 이번달 달력을 출력
uptime - 현재 기동시간을 출력
w - 온라인인 사용자를 출력
whoami - 어느 사용자로 로그인 하였는지 출력
finger user -user에 관한 정보 출력
uname -a - 커널 정보 출력
cat /proc/cpuinfo - cpu 정보 출력
cat /proc/meminfo - 메모리 정보 출력
man command - command에 대한 매뉴얼 출력
df - 디스크 사용량 출력
du - 디렉토리 사용량 출력
free - 메모리와 스왑 정보 출력
whereis app - app를 실행가능한 위치 출력
which app - app가 기본으로 실행되는 곳을 보여줌
압축
tar cf file.tar files - files들을 포함한 file.tar를 만듬
tar xf file.tar - file.tar을 압축해제
tar czf file.tar.gz files - Gzip 압축을 사용한 압축
tar zxf file.tar.gz - Gzip을 이용해 압축해제
tar cjf file.tar.bz2 - Bzip2 압축을 사용한 압축
tar xjf file.tar.bz2 - Bzip2 압축을 사용한 압축해제
gzip file - file을 압축해서 file.gz로 이름변경
gzip -d file.gz - file.gz를 fiel로 압축해제
네트워크
ping host - host에 핑을 보내 결과 출력
whois domain - domain에 대한 whois 정보 출력
dig domain - domain에 대한 DNS 정보를 출력
dig -x host - 호스트까지의 경로를 되찾아가기
설치
소스로부터 설치
./configure
make
make install
dpkg -i pkg.deb - 패키지 설치(Debian)
rpm -Uvh pkg.rpm - 패키지 설치(RPM)
단축키
Ctrl+C - 현재 명령의 실행을 강제로 마침
Ctrl+Z-현재 명령을 멈춤,fg를 이용해서 계속해서 화면에서 보
이도록 실행하거나 bg 를 이용해서 안보인채 계속 실행
Ctrl+D-현 세션에서 로그 아웃,exit와 비슷
Ctrl+W - 현재 라인에서 한 단어 삭제
Ctrl+U - 현재 줄 전체 삭제
Ctrl+R - 최근 입력한 명령어 보여주기
!! - 마지막 명령어 반복실행
exit - 현재 세션에서 로그 아웃
cal [[month] year]
달력을 출력
date [MMDDHHmm[[yy] | ccyy]]
컴퓨터의 시간을 알 수 있음
df [-lt][-f][{}]
슈퍼블록에서 카운트하고 있는 마운트된 파일 시스템, 디렉토리에서 사용가능한
디스크블록과 freeinode수를 알려줌
du
사용자 자신의 디스크 사용 상황을 블록 단위로 출력해줌
grep [option] limited regular expression [file]
파일에서 특정한 패턴을 찾는데 사용되며, 그 패턴을 포함하고 있는 모든 행을 출력함
kill [-sihno] PID
지정한 프로세서에게 종료신호를 보내는 명령어
ps
컴퓨터 시스템에서 활동중인 프로세서의 상태를 알려주는 명령
touch [-amc][MMddhhmm[yy]]files
지정된 파일에 접근하여 최종적으로 수정된 시간을 갱신
tr [-option][string1[string2]]
표준 입력의 특정 문자들을 삭제하거나 치환하여 표준 출력으로 내보내는 명령어
tty
컴퓨터 시스템에 연결하여 사용하고 있는 터미널의 이름을 알려줌
umask [###]
파일이 만들어질 때 적용되는 파일접근 허용모드를 설정
cd
현재 디렉토리를 바꿈
ls [-option][file/directory]
디렉토리의 내용을 화면에 출력
mkdir [-m]mode[-p]<경로><디렉토리 이름>
새로운 디렉토리를 만듬
rmdir [-ps]<디렉토리이름>
지정된 디렉토리를 제거
pwd
현재의 작업디렉토리를 화면에 출력
cat
파일의 내용을 표준 출력 장치로 내보내는 명령어
cmp [-l][-s]file1 file2
두개의 파일을 비교하여 차이점을 화면에 출력
comm [-[123]]file1 file2
지정된 두개의 파일을 비교하여 공통부분을 삭제 혹은 선택할 때 사용
cp file1 [file2] target
지정된 파일을 다른 이름으로 복사
cut -clist[files]
파일의 각 행에서 선택된 필드를 절단
dd[option=value]
파일을 변환 혹은 복사
diff
지정된 두개의 파일간의 차이를 비교하여 두개의 파일이 일치되기 위해 필요한
정보를 제공
fgrep [option] string[file]
문자열에 따라 파일을 검색
find path list expression
어떤 파일이 어느 디렉토리에 있는지를 찾아줌
join [option]file1 file2
관계형 데이터베이스 조작 명령으로 지정된 파일의 관계를 결합하여 결과를
표준 출력장치로 출력
ln [-f][-n][-s]file1[file2] target
두개의 파일을 연결하여 사용
mknod name b/c major-No minor-No
특수 파일을 위한 디렉토리 항목과 이에 대응하는 i-node를 생성
mv <현재 이름> <변경될 이름>
디렉토리 또는 파일의 이름을 변경
paste file1 file2
여러 개의 파일에 있는 같은 행의 내용을 병합
pr -option files
파일을 표준출력으로 보여주고 현재의 시각, 파일명, 페이지 등을 같이 보여줌
rm [-f][i]file
파일 혹은 디렉토리를 삭제
sort [option]files
파일을 정렬 혹은 병합
tail
지정된 파일의 끝 부분을 출력
tar [-]{txruc}[vwfblm][0-7[lmh]][tapefile][blocksize]file1 file2
파일들을 자기 테이프에 저장 또는 불러오기 위한 명령어
ulimit
v 사용자 범위의 출력, 설정, 프로세서의 보통 파일 크기 범위를 출력
umask[xxx]
v 파일 생성 마스크의 설정과 출력을 위해 사용
uniq [-udc [+n][-n]][input[output]]
중복되는 행을 삭제하는 명령
wc file
텍스트 파일에 담겨져 있는 문자 수, 단어 수 및 라인 수를 화면에 출력하는 명령
bc
간단한 산술 계산을 할 수 있게 함
enable, disable
프린터의 사용을 허용 혹은 불가능하도록 설정
factor [integer]
지정된 정수를 소인수 분해하여 화면에 출력
mesg [-n][-y]
다른 사용자가 메세지를 보낼 때 수신여부를 결정
mount [-v | -p]
이미 만들어져 있는 파일 시스템을 연결하는 명령
passwd
자신의 암호를 등록하거나 변경할 때 사용
stty [-a][-g][option]
현재 단말기나 콘솔의 입/출력 선택 항목을 설정
tee [-l][-a][file]
파이프를 접속
tr [-option][string1[string2]]
표준 입력의 특정 문자들을 삭제하거나 치환하여 표준 출력으로 내보내는 명령
wall
모든 사용자에게 동일한 메세지를 전송
write user[terminal]
다른 사용자에게 1대1 메시지를 전송
chgrp group file
지정된 파일의 소유권자 그룹을 바꾸는 명령
chmod mode file
지정된 파일에 대한 사용 권한을 변경하고자 할 때 사용
chown owner file
지정된 파일에 대한 소유 권한을 변경하고자 할 때 사용
소켓 함수 호출시 동작방법을 두고서 Blocking Nonblocking이라 한다.
(1) Blocking
조건 만족이 되지 않는다면 함수는 리턴하지 않고 해당 스레드는 Wait State를 만족하게된다.
애플리케이션은 더이상 진행되지 않는다.
(2) NonBlocking
소켓 함수 호출시 조건이 만족되지 않더라도 함수가 리턴하므로 해당 쓰레드는 계속 진행이 가능해진다.
socket() 는 기본적으로 NonBlocking 모드의 함수이다.
// 블로킹 소켓 생성
SOCKET listen_socket = socket(AF_INET, SOCK_STREAM, 0);
if(listen_socket == SOCKET_ERROR) err_quit("socket()");
// NonBlocking 소켓 생성
u_long on = 1;
retval = iostlsocket(listen_sock, FIONBIO, &on);
if(retval == SOCKET_ERROR) err_quit("ioctlsocket()");
넌 블로킹 소켓에 대해 소켓 함수를 호출했을때는 조건이 만족되지 않아 작업을 완료할 수 없으면 소켓 함수는 오류를 리턴한다. 이때는 WSAGetLastError() 함수를 호출하여 반드시 오류 코드를 확인하여야한다.
넌 블로킹 소켓을 사용할 경우 대개 오류 코드는 WSAEWOULDBLOCK이 되며, 이는 조건이 만족되지 않음을 나타내므로 나중에 다시 소켓함수를 호출하면 된다.
(사용하는 곳 )
// 클라이언트와 데이터 통신에서
// 데이터 받는 부분
while(1){
retval = recv(client_sock, buf, BUFSIZE, 0);
if(retval == SOCKET_ERROR){
if(WSAGetLastError() != WSAEWOULDBLOCK){
err_display("recv()");
break;
}
}
}
NonBlocking
(장점) 소켓 함수 호출시 블록되지 않으므로 다른 작업을 진행 할 수 있다.
멀티쓰레드를 사용하지 않고도 여러 개의 소켓 입출력을 처리할 수 있다.
(단점) 소켓 함수를 호출할 때마다 WSAEWOULDBLOCK등 오류코드를 확인하고, 다시 해당함수를 호출해야 하므로 프로그램 구조가 복잡해진다.
블로킹 소켓을 사용한 경우보다 CPU이용률이 높아진다.
c에서는 구조체가 데이터만을 멤버로 가질 수 있지만 c++는 구조체에 함수를 가질 수 있습니다.
사실 class와 struct는 c++에서 거의 차이가 없습니다. 이름만 틀릴 뿐이며 동작하는 방식은 똑같습니다.
struct 역시 생성/소멸될 때 class처럼 생성자와 소멸자를 호출하게 됩니다.
유일한 차이점은 아무런 명시를 해주지 않았을 때 class는 멤버가 private 권한을 가지며 struct는 public을
가진다는 것 뿐입니다.
따라서 struct 키워드를 사용해서 정의를 해준다고 해도 생성자, 소멸자는 물론 다른 멤버 함수도 똑같이
선언할 수 있습니다.
즉, 아래의 두 정의는 완전히 똑같습니다.
struct stTest {
public:
stTest() : x(0) {}; /// contstructor
~stTest() {}; /// destructor
void stFunc() {};
private:
int x;
};
class CTest {
public:
CTest() : x(0) {};
~CTest() {};
void cFunc() {};
private:
int x;
};
하지만 아무런 권한 표시를 해주지 않을 경우 stTest의 멤버는 모두 public이 되며 CTest의 멤버는 모두 private으로
정의됩니다...
[출처] C++ 에서 class 와 struct |작성자 백귀야행
객체 지향 (Object-Oriented)
객체지향이란 용어는 Simula 67 프로그래밍 언어에서 객체(object)라는 개념을 사용한데서 유래했다.
객체는 시스템을 구성하는 실체(entity)로서 각 객체는 한 구성원의 특성과 상태변화를 구현하는 기본 단위라 할 수 있다.
객체는 소프트웨어를 구성하고 실제 소프트웨어를 작동시키는 실체들
즉, 논리와 데이타가 분리되어 있는 기존의 구조적 사고에서 과감히 탈피하여 논리와 데이타가 결합된 객체들이 시스템을 이룬다는 것이다.
객체지향이란 소프트웨어를 자료구조(data structure)와 행위(behavior)가 결합된 객체들의 구조화 된 집합으로 보는 시각이다. 소프트웨어를 구현하는 방법이라기 보다는 실세계의 문제를 보는 개념이다.
객체의 속성 (Attribute of object)
다음의 항목들은 객체가 지니는 속성을 보여준다.
Identity(식별) - 각 객체는 다른 객체로부터 분리되고 있고, 분별 가능해야 한다.
Classification(분류) - 같은 자료구조와 행위를 가진 객체들은 동일한 클래스(class)로 분류된다.
상대적으로 각 객체는 소속 클래스의 인스턴스(instance)가 된다.
같은 클래스에서 생성된 객체들은 모두 같은 연산(operation) 기능을 갖고 있으며, 자료구조가 같고 동일한 행위를 하게 된다. 자료구조는 객체들이 갖는 데이타와 속성(attribute)들의 집합입니다.
그러나 데이터와 속성의 값은 물론 다르죠
Polymorphism(다형성) - 같은 연산 기능이 부여되어도 그 기능을 수행하는 클래스에 따라 다른 행위로 나타날 수 있다.
예를 들어 '이동(move)' 이라는 기능이 '교수'라는 클래스에 적용될 때는 자택의 이사가 될 수 있으나, '승용차'라는 클래스에 적용되면 특정 목적지로 일정한 시각에 정해진 속도로 움직이는 행위가 될 수도 있다.
Inheritance(상속) - 계층(hierarchy)관계에 놓여 있는 클래스들 간에 속성이나 연산 기능들을 공유한다.
즉, 주어진 클래스에 서브클래스(subclass)가 있다면 서브클래스의 모든 객체들은 소속 클래스의 모든 속성이나 연산기능을 상속받게 된다. 따라서, 서브클래스를 정의할 때에는 수퍼클래스(super class) 로부터 상속받는 내역들을 중복하여 정의할 필요가 없게 된다.
객체 지향의 기본 원리 (basic principles of object-oriented)
객체 지향 기술은 객체의 identity, classification, polymorphism, inheritance를 유지하기 위하여 다음과 같은 설계의 원칙을 중요시 한다.
data abstraction : 자료 객체(data entity)들의 중요한 특성을 모형화한다. 이 모형이 객체의 속성이 된다.
encapsulation : 객체의 내부적인 사항과 객체들간의 외부적인 사항들을 분리시킨다. 이렇게 캡슐화된 객체의 행위는 외부에서 볼 때는 구체적인 아닌 추상적인 것이 되므로 정보 은닉(information hiding) 개념이 존중된다. 주어진 클래스의 특정 연산 기능은 메소드(method)라고 한다. 캡슐화는 무슨 메소드로 구현되었는가에 구애받지 않고 추상적으로 정의된 연산 기능을 통해 객체가 사용되고 시스템의 상태(state)를 변화시키도록 해준다.
combining data and behavior : 특정한 연산 기능을 수행시킬 때 단순히 메세지만 전송하면 된다.
sharing : 자료 구조및 행위의 공유화(sharing)는 계층 관계에 놓여 있는 클래스들 간의 상속성(inheritance)으로 가능하다.
상속성은 설계 및 코드의 재사용(reuse)을 도와주는 중요한 개념이다.
서브클래스가 수퍼클래스의 변수와 메소드들을 상속받을 때 필요에 따라 정의가 구체화(specification)되며, 상대적으로 상위층의 클래스 일수록 일반화(generalization) 된다고 말한다.
객체지향 개발 단계
일반적으로 널리 사용되고 있는 분석, 설계, 구현 단계로 분리한다.
1. 객체지향 분석(object-oriented anaysis : OOA)
문제를 정의하고 이 정의로부터 모형(model)들을 제작하여 실세계(real-world)의 중요한 특성들을 보여주는 단계이다. 다음과 같은 모형 들이 만들어 질 수 있다.
객체 모형(object model) : 객체들과 그 특성을 식별하여 객체들의 정적 구조(static structure)와 그들간의 관계(interface)를 보여주는 객체 다이어그램(object diagram)을 작성한다.
동적 모형(dynamic model) : 시간 흐름에 따른 시스템의 변화를 보여주는 상태 다이아그램(state diagram)을 작성한다. 실시간(real-time) 시스템에서는 반드시 필요하다.
기능 모형(fuction model) : 시스템 내에서 데이타 값이 변하는 과정을 보여주는 것으로 잘 알려진 자료 흐름도(DFD)가 사용된다.
2. 객체지향 설계(object-oriented design : OOD)
객체지향 설계는 시스템 설계와 객체 설계로 크게 나뉘어진다.
시스템 설계(system design) : 시스템의 구조를 서브시스템으로 분해한다. 이 과정중에서 성능 최적 방안, 문제 해결 전략, 자원 분배 등이 확정된다.
객체 설계(object design) : 구현에 필요한 상세한 내역을 설계 모형으로 제작하고 상세화된다. 구체적인 자료구조와 알고리즘 들이 정의된다.
3. 객체지향 구현(object-oriented programming : OOP)
설계 모형을 특정 프로그램 언어로 번역하는 작업이다. 객체, 클래스, 상속의 개념을 다 포용하는 객체지향 언어(object-oriented programming language : C++, Smalltalk 등)가 가장 좋지만 객체의 개념만 인정하고 클래스, 상속 등은 고려하지 않은 객체기반 언어(object-oriented based programming language : Ada 등)도 좋다.
또한, 일반적인 구조적 프로그래밍 언어(structured programming language : C, Pascal 등)도 객체지향 개발에 활용될 수 있는가 하면 객체 지향 데이타베이스 관리시스템(OODBMS)이 개발의 도구로 이용될 수도 있다.
객체지향의 초기개념은 프로그래밍 언어로부터 시작됐으나, 이젠 실세계를 바라보는 새로운 시각으로 그 중요성이 변화하고 있으며, 개발언어에 너무 종속될 필요는 없다.
객체 지향 프로그래밍 개념
객체 지향의 개념을 상세하고 좀 더 직접 느낄 수 있는 수준으로 다루도록 하겠습니다.
객체 지향 기술에서 가장 근본이 되는 개념은 주어진 문제를 이해하고 관찰하는 시각에 있다. 즉, 주어진 문제 영역을 그 안에 존재하며 관련된 여러 개의 객체들이 서로 정보를 주고 받는다고 보는 시각이다. 이것은 우리가 프로그래밍을 하는 것을 제하더라도, 일상 생활에서 어떤 문제에 대해 생각하고 이해하며 관찰하는 방법과 동일하다.
소프트웨어에 대한 종전의 시각은 "하나의 프로그램은 필요한 데이타 구조와 이 데이터구조 위에 수행되는 함수들의 집합"이다.
PROGRAM = DATA STRUCTURE + FUNCTION
이러한 방식의 큰 문제는 연관이 많은 데이터와 함수들도 별도의 독립된 것처럼 코드상에 정의, 취급하는 것이다. 즉, 데이터 부분은 주로 전역 변수(global variable)들의 정의 부분에 포함되어 있고, 이 데이타 부분과 연관된 함수들은 다른 함수들과 함께 정의되어 있어 이들간의 연관관계를 잘 표현하지 못하고 있다.
반면에 객체지향적인 시각은 "하나의 객체지향 프로그램은 여러개의 객체(object)들로 구성이 되며 각각의 객체들은 위에서 언급한 데이터 구조 부분과 관련된 함수들을 동시에 포함하고 있다"는 것이다.
OBJECT = DATA STRUCTURE + FUNCTION
PROGRAM = { OBJECT }
1. 객체 (object)
객체란 필요한 데이타 구조와 그 위에서 수행되는 함수들을 가진 하나의 소프트웨어 모듈이다.
즉, 각 객체의 데이타구조는 상태(state)가 되는 것이다.
예로서, 객체는 단순한 하나의 변수,
int x;
라고 정의된 "x"와는 다르다.
"x"는 하나의 정수를 정의하는 장소만을 제공할 뿐, 어떤 기능을 수행할 수 있는 능력은 없다.
반면에, 객체는 이러한 "x"와 같은 변수들을 가지고 있으면서, 이들 변수를 위에 작동하는 기능들을 함께 지니고 있다. 다음은 C++를 가지고 스크린상에 점을 정의하는 객체의 표현이다.
clss POINT
{
int xPos;
int yPos;
ColorType clr;
public :
...
void move(int x, int y);
void setcolor(ColorType z);
...
}
위에서 보듯이 객체는 단순한 변수만 가지는 것이 아니라, 그 객체가 할 수 있는 일들을 함께 정의한다. 즉, 이것이 캡슐화(encapsulation)의 개념이다.
2. 캡슐화 (encapsulation)
일반적으로 우리 생활에서 어떤 정보와 어떤 종류의 작업은 개념적으로 서로 연관되어 있음을 많이 접한다. 이러한 연관된 정보와 작업 또는 기능을 하나로 묶는 것은 자연스런 과정이다. 예를 들어 대학교의 인사관리에서는 학생들의 이름, 주소, 학번, 전공 들의 정보를 유지하며 학생들에 관해 가능한 작업인 평점 계산, 주소변경, 과목신청 들의 기능들을 생각할 수 있다. 이러한 정보와 정보 처리에 필요한 작업, 즉 기능들은 모두 학생에 관한 것이므로 학생이라는 테두리로 묶어두는 것이 자연스러운 것이다. 이렇게 연관된 사항들을 하나로 묶는 것을 캡슐화(encapsulation)라고 한다.
프로그램상에서의 캡슐화의 의미는 프로그램 분석자나 설계자가 주어진 문제를 데이타와 함수들의 세부사항들은 개발의 차후단계에서 정의하고, 객체라는 덩어리 단위로 문제에 대해 생각하게 하는 추상화의 수단을 제공하는 데 있다.
3. 정보 은폐 (infomation hiding)
정보 은폐란 캡슐속에 쌓여진 항목에 대한 정보를 외부에 감추는 것을 의미한다. 즉, 처리하려는 데이타 구조와 함수에 사용된 알고리즘 들을 외부에서 직접 접근하지 못하도록 하고 캡슐 내부의 함수들만이 접근하게 된다. 객체지향에 관한 서적이나 논문에서 이 두가지 개념이 중요시 소개되는 것은 바로 객체라는 것이 캡슐화와 정보 은폐의 원리를 실제의 프로그래밍 언어에서 실현한 것이기때문이다.
객체와 객체 사이의 정보 교환은 외부에 공개하고자 하는 일련의 정보를 public interface로 정의해 외부에 객체들이 이 Interface를 통해서 그 객체와 정보를 교환하도록 한다. 즉, 한 객체의 Public Interface를 그 객체가 "무슨 일을 할 수 있다. 혹은 이 정보는 공개할 수 있다."라고 외부에 선언하는 것이다.
이 Public Interface는 언어에 따라 표현 양식이 다른데, C++에서는 "public"이란 특별 구문을 두어 "public"란에 들어간 항목들만 외부에 공개된다. Effel이란 언어에서는 "export"라는 란에 지정된 항목들만 외부에 공개된다. 앞에서 정의한 POINT라는 객체 정의를 보면 move와 setcolor의 함수들이 외부에서 관찰될 수 있는 public interface임을 알 수 있다. 여기서 한가지 유의할 점은 move와 setcolor라는 함수들이 외부에 보여져 불리워질 수 있는 함수들이라는 것이며 각 함수가 가지고 있는 코드나 알고리즘까지 보여지는 것은 아니라는 것이다. 한 함수가 외부에 보여지는 부분을 signature라고 하며 하나의 signature는 함수의 이름, 입력 매개변수(input parameter)와 출력 매개변수(output parameter)로 구성되어 있다.
위에서 살펴볼 캡슐화와 정보 은폐의 이점은 우선 객체 내부의 은폐된 데이타 구조가 변하더라도 주변 객체들에게 영향을 주지 않는다는 것이다. 예로서, 어떤 변수의 구조를 배열(array)구조에서 리스트(list) 구조로 바꾸더라도 프로그램의 다른 부분에 전혀 영향을 미치지 않는다. 또한 어떤 함수에 사용된 알고리즘을 바꾸더라도 signature만 바꾸지 않으면 외부 객체들에게 영향을 주지 않는다. 예를 들어, sorting 함수의 경우 처음 사용된 sequence sorting 알고리즘에서 quick sorting 알고리즘으로 바뀔때 외부에 어떤 영향도 주지 않는다. 이러한 장점을 유지보수 용이성(maintainability) 혹은 확장성(extendability)이라 한다.
4. 메세지 (message)
객체지향 프로그램에서는 마치 데이타 통신에서와 같이 정보를 메시지라는 덩어리는 서로 주고 받으며, 이 메세지 교환이 객체들 사이에 정보를 주고 받는 유일한 수단이다. 따라서, 하나의 객체지향 프로그램은 메세지 교환을 하며 통신하는 여러개의 객체들로 이루어진다고 정의할 수 있다.
하나의 메세지는 메세지를 받을 수신 객체(receive object)가 누구인가를 명시하며, 그 수신 객체가 수행해야 할 함수의 이름을 지정하고 그 함수를 실행시 요구되는 인자들(arguments)을 포함하고 있다. 실제로 메세지를 보내는 구문은 언어에 따라서 다소 차이가 있지만, 대체로 다음과 같은 것이 메세지의 일반적인 형태이다.
<수신 객체> <- <함수이름> <필요한 인자들>
예를 들어, 한 '점'이라는 객체에 C++에서는 다음과 같이 메세지를 보낸다.
myPoint.move(10, 15)
여기서 "myPoint"는 한 점을 나타내는 객체이며 다음 부호 "."는 "move"라는 메세지가 "myPoint"라는 객체에게로 전해진다는 메세지 전달의 표현이다. 괄호 안의 숫자들은 인자들이다.
5. 클래스(class)
우리의 일상생활을 보면, 대부분의 사물에 종류나 유형이 있음을 알 수 있다. 예를 들면, 자동차가 무수히 많지만 승용차, 화물차, 버스 들으로 그 종류를 나눌 수 있고, 또 자동차를 모델별로 분류할 수도 있다. 이 때 각 사물이 어떤 유형에 속하는데 이러한 사고 방식을 객체지향에서는 직접 표현할 수 있게 해준다. 즉, 각 객체에는 어떤 종류나 유형이 있는데 각각의 자동차는 별개의 객체지만 여러개의 유사한 자동차들이 하나의 자동차 유형에 속한다. 이러한 객체의 유형을 객체의 타입(object type) 혹은 객체클래스(object class)라 한다. 그리고 한 클래스에 속하는 각각의 객체를 그 클래스의 인스턴스(instance) 혹은 그냥 객체라 한다.
이러한 클래스를 C++로 정의해 보면 다음과 같다.
class Employee
{
char *name;
positionType position;
int salary;
phoneNumberType phoneNumber;
...
public
promote(...
increaseSalary(...
changePhoneNumber(...
...
}
이 클래스 정의에 따르면, Employee 클래스에 속하는 모든 객체들, 즉 모든 직원들은 이름(name), 직위(position), 월급(salary), 전화번호(phone number)등의 변수들을 가지며 진급(promote), 월급인상(increaseSalary), 전화 번호 변경(changePhoneNumber)등의 함수들을 수행시킬 수가 있다.
따라서, 클래스란 각각의 객체들이 가져야 할 속성을 정의하고 있는 본형(template)이며 프로그램 수행시에는 이들 클래스에 근거해서 각각의 객체, 즉 인스턴스를 생성시켜 동작하게 한다. 예를 들어 직원(employee) 클래스에서 "astre"라는 인스턴스를 만들때 C++에서는 다음과 같이 표현한다.
employee astre();
혹은
employee *astre = new employee();
6. 속성 상속(inheritance)
속성 상속이라는 개념 역시 우리의 일상 생활에서 흔히 사용하는 개념을 프로그램으로 표현하기 위한 편리한 수단이다. 어떤 객체의 종류, 즉 클래스는 좀 더 세분화하여 분류할 수가 있는데 이렇게 세분화된 종류나 유형을 subtype 혹은 subclass라고 한다.
객체지향 프로그래밍에서 "속성 상속"은 새로운 클래스를 정의할 때 모든 것은 처음부터 다 정의하는 것이 아니라 이미 존재하는 유사한 클래스를 바탕으로 하여 필요한 속성만 추가하여 정의하는 경제적인 방법을 의미한다. 이 때 새로이 생기는 클래스를 subclass라 하고 그 바탕이 되는 클래스를 superclass라 한다. 이렇게 하면 클래스들 사이에서 공통으로 가지는 특성, 즉 데이타 구조나 함수들은 중복하여 정의하는 일을 줄일 수 있을 뿐 아니라, 특성을 수정하거나 추가시에 superclass의 정의만 고치면 그 subclass들도 변경된 속성을 자동적으로 상속받게 되므로 매우 편리하다.
7. 복수 속성 상속(Mutiple Inheritance)
일반적으로 하나의 subclass는 하나의 superclass를 가지나 문제에 따라서는 복수의 superclass들을 필요로 하는 경우가 있다. 이런 상속 관계를 복수 속성 상속(Multiple inheritance)이라 하는데 일부의 객체 지향 언어에서만 지원되고 있다. 이것은 실제의 문제를 분석하고 모델링 하는데 더욱 편리함을 준다.
8. 추상 클래스(Abstract Class)
클래스 중에는 인스턴스(instance)를 만들어 낼 목적이 아니라 subclass들의 공통된 특성을 추출하여 묘사하기 위한 클래스가 있는데, 이를 추상 클래스(Abstract class, Virtual class)라 한다. 변수들을 정의하고 함수중 일부는 완전히 구현하지 않고, Signature만을 정의한 것들이 있다. 이들을 추상 함수(Abstract function)라 부르며, 이들은 후에 subclass를 정의할 때에 그 클래스의 목적에 맞게 완전히 구현된다. 이 때 추상 클래스의 한 subclass가 상속받은 모든 추상 함수들을 완전히 구현했을 때, 이를 완전 클래스(Concrete class)라고 부른다. 이 완전 클래스는 인스턴스를 만들어 낼 수 있다.
추상 클래스의 예로서 프린터 소프트웨어를 생각해 보자. 우선 모든 종류의 프린터들이 공통으로 가지는 특성을 정의한 추상 클래스 "Printer"가 있다고 한다면, 여기에는 프린터의 상태를 나타내는 변수, 프린터의 속도 등의 변수가 있으며 함수로는 프린팅을 수행하는 Print 등을 생각할 수 있다. 그러나 프린터마다(Dot matrix printer, Laser printer, Ink jet printer) 프린팅 하는 방법이 다르므로 이 추상 클래스 안에서는 Print라는 함수를 완전히 구현할 수 없다. 다만, 여기에는 Print 추상 함수의 Signature만 가지고 있으며, 실제의 구현은 여러 subclass에서 각 프린터 종류에 알맞게 하면 된다.
"Printer"라는 클래스는 추상 클래스로서 실존의 어떤 프린터 기능을 가지고 있지 않고, dot matrix printer나 laser printer 등의 완전 클래스들 간의 공통된 특성만 지정하고 있으므로, 그 인스턴스를 만드는 것은 무의미하다. 추상 클래스는 점진적 개발 방법(Incremental Development)에 유용하게 사용될 수 있으며, 공통 속성(attribute)의 추출 및 정의에 유용하므로 문제를 모델링하는데 편리함을 더해준다.
9. 다형성(Polymorphism)
객체 지향 프로그램의 중요한 특징으로 하나의 함수 이름이나 심볼이 여러 목적으로 사용될 수 있는 다형성(Polymorphism)을 들 수 있다. 객체 지향에서의 다형성이란, 복수의 클래스가 하나의 메세지에 대해 각 클래스가 가지고 있는 고유한 방법으로 응답할 수 있는 능력을 말한다. 즉, 별개로 정의된 클래스들이 ㅌ은 이름의 함수를 별도로 가지고 있어 하나의 메세지에 대해 각기 다른 방법으로 그 메세지를 수행할 수 있는 것을 의미한다. 예를 들어, 여러 가지 화일(file)들을 프린트 하는 함수를 생각해 보자. 화일에는 간단한 텍스트 화일(text file), 문서 편집기로 만든 포멧 화일(format file), 그래픽을 포함하는 화일(file with graphics) 등 여러 가지가 있다. 이들 각각의 화일들은 프린트 하는 방법이 모두 다르다, 객체 지향에서는 아래처럼 각 종류의 화일을 별도의 클래스로 정의하고, 각각의 화일 종류별로 Print라는 함수를 화일의 형태에 맞게 구현한다.
Text file -> Print();
Formatted file -> Print();
File with graphics -> Print();
이렇게 생성된 화일 객체들은 모두 Print라는 메세지를 이해하며, 각 화일의 종류에 알맞게 프린트 할 수 있다. 이렇듯 다형성은 같은 이름의 함수를 여러 클래스가 각 클래스에 알맞게 달리 정의하고 같은 이름의 메세지에 응답할 수 있게 해준다.
객체지향 프로그래밍의 장점
생산성 향상(Improvement of productivity)
객체지향 기술에서 추구하는 궁극적인 목표는 잘 설계된 클래스들, 즉 하드웨어의 IC처럼 소프트웨어 라이브러리(library)를 재사용하는 것이다. 종전의 개발 방법과는 달리 객체(object)는 IC처럼 독립적이어서 이를 재사용함으로 생산성(productivity)이 증가하게 된다. 어느 한 보고서에 의하면 객체지향 소프트웨어 개발에 기존 클래스의 재사용률이 80%에 이른다고 한다.
자연적인 모델링(Natural modeling)
객체, 클래스, 속성 상속 및 다형성(polymorphism) 등은 우리의 일상생활에서 보통 사람들이 대하고 생각하는 방식을 그대로 프로그램 언어로 표현할 수 있게 해준다.
재사용(Reuse)
객체지향 프로그래밍은 코드의 재사용을 극대화한다. 한 프로그램 내에서 subclass들이 superclass의 속성을 표현한 코드를 재사용하며, 새로운 프로그램 개발시 기존 프로그램이 갖고 있는 클래스 상속 구조에서 많은 클래스들을 소프트웨어 IC로 재사용할 수 있다.
유지보수(maintenance)의 용이성
객체지향 프로그램은 기존의 기능을 수정하거나 새로운 기능을 추가하기가 용이하다. 기존 기능을 수정시 함수를 새롭게 바꾸더라도 캡슐화와 그 함수의 세부정보가 은폐되어 있어 주변에 미치는 영향을 최소화 한다. 새로운 객체의 종류를 추가시에는 속성 상속을 통하여 기존의 기능을 활용하고 존재하지 않은 새로운 속성만 추가하면 되므로, 매우 경제적이다.
이외에도 점진적(incremantal) 프로그램 개발의 용이성, 요구사항(requirement) 변화에 대해 안정된 프로그램 구조 등의 장점들을 들수 있다.
객체지향 프로그래밍의 단점
객체지향 프로그램의 유일한 단점으로 실행시의 속도(runtime efficiency)가 떨어진다고 알려져 왔다. Smalltalk이나 C++ 등의 객체지향 언어로 만들어진 응용 프로그램은 Fortran이나 C 등의 재래식 언어로 만들어진 프로그램에 비해 실행 속도가 늦다는 말을 흔히 듣게 된다. 이것은 유연성(flexibiblity)와 효율성(efficiency)의 trade-off 관계에 기인한다.
객체지향 프로그램은 객체라는 단위를 컴퓨터의 기억장치에 어떤 형태로든 표현해야 하고, 객체간의 정보교환이 모두 메시지 교환을 통해 일어나므로 재래식 프로그램보다 실행시스템에 많은 부하(overhead)가 생기게 된다. 하지만, 이러한 운용시 호율성 문제는 효율성이 뛰어난 새로운 언어들의 탄생으로 이제 거의 문제가 되지 않는다. 특히, 기존의 언어 C나 Pascal 등을 확장한 C++나 Object Pascal 등은 기존 언어의 효율성과 객체지향의 장점들을 모두 제공한다.
- 메시지
사용자 정의 메시지로 정보 교환
장점 단순하다..
단점 미리정의해야한다.. 8바이트까지만 전송한다.
그래서.. WM_CopyData가 있다.. 이것은 핸들과 구조체의 포인터를 넣어서 전송한다.
포인터이기때문에 구조체나 배열도 보낼 수 있다.
장점 편리하다.
단점 효율이 좋지 못하다는...
- 아톰
기초적인 ipc통신 방법으로 시스템이 유지하는 문자열 테이블에 문자열을 보관해 놓으다는...
최대 255까지만.
- 메일슬롯
최대 64k까지
그러나 단방향
- 파이프
주로 연속적인 바이트 스트림을 전송할때 사용한다.
이름 있나 없나 두개
없음 단반향이고 로컬전용이다
이름 있다
있음 엔티에서만 사용가능하다.
이름때문에 핸들이 필요없다