template<class S>
class Sington
{
private:
S();
S(S&);
~S(); 
S& operator=(S&) const;
static S* pMe; 
public:
static S* getMe(){return pMe;}
static void init(){pMe = new S(); pMe = NULL;}
static void release(){if(pMe != NULL)delete pMe;} 
}; 


'Notes > Tech History' 카테고리의 다른 글

프로그래밍 언어 순위  (0) 2012.02.02
파일 입출력, 파일 포인터(FILE* fp)  (0) 2012.01.02
OpenAL의 시작  (3) 2010.12.02
TCP기반의 에코서버/클라이언트  (0) 2010.08.19
리눅스 기본 명령어  (1) 2010.08.17

Openal에 대한 정보가 너무 없네요... 특히 한국어로 된 정보는 찾기 너무 힘듬..ㅜ;;
어떻게 제가 찾은 정보라도 번역해서 포스트 해봅니다.
 
 
1. Opanal 구조

OPENAL이 초기화 될 때, 적어도 하나의 Device가 초기화 되야 하고, Device하나가 초기화 될 때, 적어도 하나의 Context가 초기화 되어야 합니다. 그리고 Context가 초기화 될 때, 하나의 Listener 객체가 생성되고, 여러개의 Source객체를 생성할 수 있게 되고, 그것에 하나 또는 추가적인 Buffer객체를 연결할 수 있습니다. 여기서 Buffer는 Context의 일부가 아니라 하나의 Device에 있는 모든 Context에 섞여 나뉘어져 있는 것입니다.



2. Device 초기화

// 초기화
Device = alcOpenDevice(NULL); // 운영체제에서 사용하고 있는 오디오 장치를 사용
if (Device)
{
    Context=alcCreateContext(Device,NULL);
    alcMakeContextCurrent(Context);
}
// Check for EAX 2.0 support
g_bEAX = alIsExtensionPresent("EAX2.0");
// Buffer객체 생성
alGetError(); // error code를 비움
alGenBuffers(NUM_BUFFERS, g_Buffers);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alGenBuffers :", error);
    return;
}
// test.wav 불러옴
loadWAVFile("test.wav",&format,&data,&size,&freq,&loop);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alutLoadWAVFile test.wav : ", error);
    alDeleteBuffers(NUM_BUFFERS, g_Buffers);
    return;
}
// test.wav 데이터를 AL Buffer 0로 복사함
alBufferData(g_Buffers[0],format,data,size,freq);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alBufferData buffer 0 : ", error);
    alDeleteBuffers(NUM_BUFFERS, g_Buffers);
    return;
}
// test.wav 내보냄
unloadWAV(format,data,size,freq);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alutUnloadWAV : ", error);
    alDeleteBuffers(NUM_BUFFERS, g_Buffers);
    return;
}
// Source객체 생성
alGenSources(1,source);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alGenSources 1 : ", error);
    return;
}
// buffer 0과 source를 연결
alSourcei(source[0], AL_BUFFER, g_Buffers[0]);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alSourcei AL_BUFFER 0 : ", error);
}
// 나가기
Context=alcGetCurrentContext();
Device=alcGetContextsDevice(Context);
alcMakeContextCurrent(NULL);
alcDestroyContext(Context);
alcCloseDevice(Device);



3. Listener 속성

ALfloat listenerPos[]={0.0,0.0,0.0};
ALfloat listenerVel[]={0.0,0.0,0.0};
ALfloat listenerOri[]={0.0,0.0,-1.0, 0.0,1.0,0.0};
// Listener의 좌표...
alListenerfv(AL_POSITION,listenerPos);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alListenerfv POSITION : ", error);
    return;
}
// Listener의  속력...
// velocity is essentially the speed of sound
alListenerfv(AL_VELOCITY,listenerVel);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alListenerfv VELOCITY : ", error);
    return;
}
// Listen의 방위...
//orientation expressed as “at” and “up” vectors
alListenerfv(AL_ORIENTATION,listenerOri);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alListenerfv ORIENTATION : ", error);
    return;
}

 속성  데이터 타입  설명
 AL_GAIN  f, fv  “master gain(patch volume)”
 소리의 크기를 설정한다.
 값은 정수여야 한다.
 AL_POSITION  fv, 3f, iv, 3i  X, Y, Z 좌표
 AL_VELOCITY  fv, 3f, iv, 3i  속도 벡터
 AL_ORIENTATION  fv, iv  orientation은 at벡터와up벡터를 표현한다.




4. Buffer의 속성

// Buffer의 주파수를 재 설정함.
alBufferi(g_Buffers[0], AL_FREQUENCY, iFreq);


 속성  데이터 타입  설명
 AL_ FREQUENCY  i, iv  버퍼의 주파수(단위 Hz)
 AL_ BITS  i, iv  버퍼의 깊이(bit)
 AL_ CHANNELS  i, iv  버퍼의 채널 갯수
> 1개가 유효하지만 버퍼가 재생될 때, 설정할 수 없습니다.
 AL_ SIZE  i, iv  버퍼의 사이즈(bytes)
 AL_DATA  i, iv  original location where data was copied from
generally useless, as was probably freed after buffer creation



5. Source의 속성

alGetError(); // 에러버퍼를 비움
alSourcef(source[0],AL_PITCH,1.0f);
if ((error = alGetError()) != AL_NO_ERROR)
    DisplayALError("alSourcef 0 AL_PITCH : \n", error);
alGetError(); // 에러버퍼를 비움
alSourcef(source[0],AL_GAIN,1.0f);
if ((error = alGetError()) != AL_NO_ERROR)
    DisplayALError("alSourcef 0 AL_GAIN : \n", error);
alGetError(); // 에러버퍼를 비움
alSourcefv(source[0],AL_POSITION,source0Pos);
if ((error = alGetError()) != AL_NO_ERROR)
    DisplayALError("alSourcefv 0 AL_POSITION : \n", error);
alGetError(); // 에러버퍼를 비움
alSourcefv(source[0],AL_VELOCITY,source0Vel);
if ((error = alGetError()) != AL_NO_ERROR)
    DisplayALError("alSourcefv 0 AL_VELOCITY : \n", error);
alGetError(); // 에러버퍼를 비움
alSourcei(source[0],AL_LOOPING,AL_FALSE);
if ((error = alGetError()) != AL_NO_ERROR)
    DisplayALError("alSourcei 0 AL_LOOPING true: \n", error);

 Property  Data Type  Description
 AL_PITCH  f, fv  pitch를 설정
 정수를 입력해야 한다.
 AL_GAIN  f, fv  source의 볼륨 설정
 정수만 입력해야 한다.
 AL_MAX_DISTANCE  f, fv, i, iv  소리가 들리는 범위의 최대 거리를 설정.
 AL_ROLLOFF_FACTOR  f, fv, i, iv  the rolloff rate for the source
기본값이 1.0
 AL_REFERENCE_DISTANCE  f, fv, i, iv  the distance under which the volume for the source would normally drop by half (before being influenced by rolloff factor or AL_MAX_DISTANCE)
 AL_MIN_GAIN  f, fv  이 source의 최소 볼륨을 설정
 AL_MAX_GAIN  f, fv  이 source의 최대 볼륨을 설정
 AL_CONE_OUTER_GAIN  f, fv  the gain when outside the oriented cone
 AL_CONE_INNER_ANGLE  f, fv, i, iv  the gain when inside the oriented cone
 AL_CONE_OUTER_ANGLE  f, fv, i, iv  outer angle of the sound cone, in degrees
기본값이 360
 AL_POSITION  fv, 3f  X, Y, Z 좌표
 AL_VELOCITY  fv, 3f  속도 벡터
 AL_DIRECTION  fv, 3f, iv, 3i  방향 벡터
 AL_SOURCE_RELATIVE  i, iv  determines if the positions are relative to the listener
기본값이 AL_FALSE
 AL_SOURCE_TYPE  i, iv  source 타입– AL_UNDETERMINED, AL_STATIC, 또는AL_STREAMING
 AL_LOOPING  i, iv  반복을 on (AL_TRUE) 또는 off (AL_FALSE)로 바꾼다.
 AL_BUFFER  i, iv  the ID of the attached buffer
 AL_SOURCE_STATE  i, iv  source의 속성
(AL_STOPPED, AL_PLAYING, …)
 AL_BUFFERS_QUEUED  i, iv  the number of buffers queued on this source
 AL_BUFFERS_PROCESSED  i, iv  the number of buffers in the queue that have been processed
 AL_SEC_OFFSET  f, fv, i, iv  초(second) 단위로 플레이 위치를
 AL_SAMPLE_OFFSET  f, fv, i, iv  셈플(samples) 단위로 플레이 위치를 바꾼다.
 AL_BYTE_OFFSET  f, fv, i, iv  바이트(Bytes) 단위로 플레이 위치를 바꾼다.

 

 6. 에러 핸들링

alGetError(); // Error코드를 비움
// 버퍼를 생성
alGenBuffers(NUM_BUFFERS, g_Buffers);
if ((error = alGetError()) != AL_NO_ERROR)
{
    DisplayALError("alGenBuffers :", error);
    exit(-1);
}
 Error Code  Description
 AL_NO_ERROR  에러가 발생하지 않았음.
AL_INVALID_NAME  OpenAL 함수에 잘못된 이름이(ID) 전달됨.
 AL_INVALID_ENUM  OepanAL 함수에 잘못된 enum값이 전달됨.
 AL_INVALID_VALUE  OpenAL 함수에 잘못된 매개변수를 전달됨.
 AL_INVALID_OPERATION  요청한 작업이 유효하지 않음.
 AL_OUT_OF_MEMORY  요청한 작업에 대해 사용할 메모리가 부족할 때,

OSI 7계층

응용 계층(Application Layer)
 - 응용 프로세스를 네트워크에 연결할 수 있게 해서 자료를 송수신할 수 있는 창구를 제공한다. 사용자가 이메일을 전송하거나 웹 브라우저를 통해 웹 서버에 연결하면 해당 서비스는 응용 계층에서 SMTP, POP3 HTTP등의 프로토콜을 이용해 서비스한다.

표현 계층(Presentation Layer)
 - 통신하는 컴퓨터 간의 데이터 표현의 차이를 해결하기 위해 자료의 형식을 변환해 주거나 공통의 형식을 제공해 주는 계층이다. 아스키 코드와 EBCDIC 코드의 변환, 그래픽 정보나 영상 정보를 JPEG나 MPEG 등으로 변환해서 전송하는 기능을 수행한다. 또한 네트워크 보안을 위해 자료를 암호화해서 전송하고 수신측에서는 이를 해독하는 기능도 수행한다. 효율적으로 전송하기 위해 자료를 압축하고 압축을 푸는 기능도 수행한다.

세션 계층(Session Layer)
 - 응용 계층 사이에 연결을 설정하고, 유지하고, 종료하는 기능을 수행한다. 이를 위해 전송 계층으로 전송할 자료의 순서를 결정하고, 자료의 점검이나 복구를 위해 동기 위치(Synchronization Point) 등을 지정한다.

전송 계층(Transport Layer)
 - 통신하는 컴퓨터 간에 자료를 전송하는 계층이다. 송신측에서는 전송할 데이터를 패킷으로 분할한다. 수신측에서는 분할된 패킷을 다시 조합해서 본래의 자료로 만들고 상위 계층으로 전달한다. 수신측에서는 분할된 패킷을 다시 조합해서 본래의 자료로 만들고 상위 계층으로 전달한다. 자료가 수신측에 올바르게 전송될 수 있도록 보장하는 기능도 수행한다.

네트워크 계층(Network Layer)
 - 라우팅 프로토콜을 이용해서 최적의 전송 경로를 선택하고 이를 통해 자료를 전송하도록 한다. 이를 위해 IP 주소와 같은 논리 주소 체계와, 지리적으로 떨어져 있는 네트워크상의 두 컴퓨터 사이에 최종 목적지까지 전송하기 위해 인접한 컴퓨터까지 자료를 안전하게 전송한다.

데이터 링크 계층(Data Link Layer)
 - 물리적인 전송 링크를 통해 자료를 안전하게 전송하는 계층이다. 전송 자료의 비트들을 프레임이라는 논리 단위로 구성해서 최종 목적지까지 전송하기 위해 인접한 컴퓨터까지 자료를 안전하게 전송한다.

물리 계층(Physical Layer)
 - 컴퓨터를 서로 연결하는 물리적은 링크의 활성화/비활성화, 링크 상태를 유지하기 위해 물리적인 링크의 전기적, 기계적, 규약적, 기능적 명세를 정의한다.




TCP/IP 4계층


응용 계층(Application Layer)
 - 응용 계층은  OSI 7계층에서 세션 계층, 표현계층, 응용계층에 해당한다. 텔넷, FTP, SMTP등과 같은 TCP와 UDP 기반의 응용 프로그램을 구현할 때 사용한다.

전송 계층(Transport Layer)
 - 전송 계층은 OSI 7계층에서 전송계층에 해당한다. 통신 노드 간의 연결을 제어하고, 자료의 송수신을 담당한다. 프로토콜로는 스트림(Stream) 형태의 연결형 서비스인 TCP와 데이터그램(Datagram)형태의 비연결형 서비스인 UDP가 있다.

인터넷 계층(Internet Layer)
 - 인터넷 계층은 OSI 7계층에서 네트워크 계층에 해당한다. 통신 노드간의 IP패킷을 전송하는 기능과 라우팅 기능을 담당한다. 프로토콜로는 IP, ICMP, ARP, RARP가 있다. IP는 데이터그램 방식의 비연결형 서비스만을 제공한다.

네트워크 액세스 계층(Network Access Layer)
 - 네트워크 액세스 계층은 OSI 7계층에서 물리 계층과 데이터링크계층에 해당한다. LAN, X25, 패킷망, 위성 통신, 다이얼업 모뎀 등에 사용된다. 특히 이더넷에서는 CSMA/CD MAC 프로토콜을 사용하며 IEEE 802.3 MAC 표준으로 규정되어 있다.




//TCP기반의 에코서버
//made by chessire

#include<iostream>
#include<winsock2.h>

#pragma comment(lib, "ws2_32.lib")

void Error(char* szMessage);

void main()
{
 SOCKET s;     // 서버 소켓 디스크립터
 SOCKET cs;
 SOCKADDR_IN server;   // 소켓 구조체
 SOCKADDR_IN client;   // 소켓 구조체
 WSADATA wsaData;   // 스타트업 구조체

 int size = sizeof(client);
 char value[256];   //수신을 위한 정수값

 WSAStartup(MAKEWORD(2,2), &wsaData);

 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  //TCP기반의 서버 생성(IPv4)

 if( s == INVALID_SOCKET )
 {
  Error("socket");
  return;
 }

 server.sin_family = AF_INET;     // AF_INET 체계임을 명시
 server.sin_port = htons(10000);     // 10000번 포트를 사용
 server.sin_addr.S_un.S_addr = htonl(ADDR_ANY); // 자동 네트워크 카드 설정

 if(bind(s, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
 {
  closesocket(s);
  Error("bind");
  return;
 }

 if( listen(s,SOMAXCONN) != 0 )
 {
  closesocket(s);
  Error("listen");
  return;
 }

 printf("클라이언트로부터 접속을 기다리고 있습니다...\n");

 cs = accept(s, (sockaddr*)&client, &size);
//한명의 클라이언트만 접속을 받는다.

 if( cs == INVALID_SOCKET)
 {
  closesocket(s);
  Error("accept");
  return;
 }

 printf("클라이언트가 접속되었습니다.\n");
 printf("IP = %s, PORT = %d\n",
  inet_ntoa(client.sin_addr), ntohs(client.sin_port) );

 while(1)
 {
  int num = recv(cs, value, 256,0);        //클라이언트에게 메시지를 받는다.
  if(num == 0 || num == SOCKET_ERROR) //에러 확인
   break;
  printf("%s 수신\n",value);
  int num2 = send(cs, value, 256,0);     //그것을 다시 돌려준다.
 }

 closesocket(cs);
 closesocket(s);
 WSACleanup();
}

void Error(char* szMessage)
{
 printf("Error:[%d] %s \n", WSAGetLastError(), szMessage);
 WSACleanup();
 exit(0);
}


//TCP기반의 네트워크
//made by chessire

#include<iostream>
#include<winsock2.h>

#pragma comment(lib, "ws2_32.lib")

void Error(char* szMessage);

void main()
{
 SOCKET s;
 WSADATA wsaData;
 SOCKADDR_IN server;
 char value[256];
 ::ZeroMemory(value, sizeof(char)*256);

 WSAStartup(MAKEWORD(2,2), &wsaData);
 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

 if(s == INVALID_SOCKET)
 {
  Error("socket");
  return;
 }

 server.sin_family = AF_INET;
 server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
 server.sin_port = htons(10000);

 if( connect(s, (sockaddr*)&server, sizeof(server)) != 0 )
 {
  closesocket(s);
  Error("connect");
  return;
 }
 printf("127.0.0.1의 10000번 포트에 접속을 성공.\n");

 while(1)
 {
  char value2[256];
  printf("할말 입력(q is quit) : ");
  scanf("%s",value);
  if(!strcmp(value,"q") || !strcmp(value,"Q"))
   break;
  send(s, value,256,0);
  if(recv(s, value2,256,0) == 0)
   break;
  printf("%s\n",value);
 }
 puts("Received file data");
 send(s,"Thank you", 10, 0);
 closesocket(s);
 WSACleanup();
}

void Error(char* szMessage)
{
 printf("Error:[%d] %s\n", WSAGetLastError(), szMessage);
 WSACleanup();
 exit(0);
}

'Notes > Tech History' 카테고리의 다른 글

싱글턴 클래스  (0) 2011.10.17
OpenAL의 시작  (3) 2010.12.02
리눅스 기본 명령어  (1) 2010.08.17
소켓의 프로토콜 (socket함수를 파헤쳐보자)  (0) 2010.08.16
윈도우 기반의 소켓관련 함수  (0) 2010.08.14

ls - 도스의 "dir"과 같은 역할, 해당 디렉토리에 있는 파일의 목록을 나열한다.

cd - 작업 디렉토리를 이동한다.

pwd - 현재 작업 디렉토리의 전체 경로를 출력한다.

rm - 파일이나 디렉토리를 삭제한다. 해당 파일이나 데릭토리에 삭제 권한이 있어야 한다.

cp - 파일이나 디렉토리를 복사한다. 새로 복사한 파일은 사용자의 소유가 된다.

touch - 크기가 0인 새 파일을 생성하거나 이미 존재하는 파일인 경우 수정시간을 현재시각으로 변경한다.

mv - 파일과 디렉토리의 이름을 변경하거나 위치 이동 시 사용한다.

mkdir - 새로운 디렉토리를 생성한다. 생성된 디렉토리는 명령어를 수행한 사용자의 소유가 된다.

rmdir - 디렉토리를 삭제한다. 해당 디렉토리의 삭제 권한이 있어야 하며, 파일이 들어 있으면 안된다. 파일이 들어있는 디렉토리를 삭제하려면 "rm -r"을 사용해야 한다.

cat - 텍스트로 작성된 파일을 화면에 출력한다. 파일의 내용을 간단히 확인하기 위해서 주로 사용한다.

head - 텍스트로 작성된 파일의 앞 10행을 출력한다.

tail - 텍스트로 작성된 파일의 뒤 10행을 출력한다.

more - 텍스트로 작성된 파일을 화면에 페이지 단위로 출력한다.
        - Spacebar는 다음페이지, b는 앞페이지, q는 종료이다.

less - more와 용도가 비슷하지만 기능이 더 확장된 명령이다. more의 키 및 화살표, Page Up, Page Down도 작동한다.(vi의 기능이 일부 추가되었다고 보면된다.)

file - File이 어떤 종류의 파일인지 표시해 준다.

clear - 명령창을 깨끗하게 지워준다.





인터넷 주소(Internet Adress)
 - IPv4(Internet Protocol version 4) : 4바이트 주소체계(1234.1234.1234.1234)
 - IPv6(Internet Protocol version 6) : 16바이트 주소체계(1234.1234.1234.1234.1234.1234.1234.1234)
                                                         : IPv4의 IP주소가 모두 고갈될 것을 염려하여 만들었다.


IPv4기반의 주소표현을 위한 구조체
struct sockaddr_in
{
  sa_family_t      sin_family;    // 주소체계(Adress Family)
  uint16_t           sin_port;      // 16비트 TCP/UDP PORT번호
  struct in_addr  sin_addr;     // 32비트 IP주소
  char               sin_zero[8] // 사용되지 않음
};

struct in_addr
{
  in_addr_t  s_addr; //32비트 IPv4 인터넷 주소
};

 - 구조체 분석
멤버 변수
  sin_family
->프로토콜체계마다 적용하는 주소체계가 다르다. 예를 들어서 IPv4에서는 4바이트 주소체계를 사용하고 IPv6에서는 16비트 주소체계를 사용해야 한다.
->AF_INET    : IPv4 인터넷 프로토콜에 적용하는 주소체계(AF = Adress Family)
->AF_INET6   : IPv6 인터넷 프로토콜에 적용하는 주소체계
->AF_LOCAL : 로컬 통신을 위한 유닉스 프로토콜의 주소체계
  sin_port
->소켓의 구분에 활용되는 것이 바로 Port번호이다. IP만 있다면 목적지 컴퓨터로 데이터를 전송할 순 있어도 해당 응용프로그램까지 전송할 수는 없지 않은가?
->16비트의 PORT번호를 저장하는 변수이다. 단, '네트워크 바이트 순서'로 저장해야 한다(이것은 아래에 추가 설명을 해놓을 것입니다.),
  sin_addr
-> 32비트 IP주소를 저장한다. 이것 역시 '네트워크 바이트 순서'로 저장해야 한다.
  sin_zero
-> 단순히 구조체 sockaddr_in와 크기를 맞추기 위해 존재하는 변수이다. 반드시 0으로 초기화해주어야 한다.


struct sockaddr
{
  sa_family_t  sin_family;      // 주소체계(Address Family)
  char           sa_data[14];  // 주소정보
};
멤버변수
  sa_data[14]
->IP주소와 PORT번호를 담고 있어야 하고, 남은 부분은 0으로 채울것을 bind함수는 요구하고 있다. 그렇기 때문에 sockaddr_in이라는 구조체가 필요한 것이다.



네트워크 바이트 순서와 인터넷 주소 변환
CPU에 따라서 4바이트 메모리 공간에 정수 1을 저장하는 방식이 달라진다.
00000000 00000000 00000000 00000001   -> 빅엔디안    : 상위 바이트의 값을 작은 번지수에 저장하는 방식
00000001 00000000 00000000 00000000   -> 리틀엔디안 : 상위 바이트의 값을 큰 번지수에 저장하는 방식

0x12345678이라는 데이터를 전송할 경우
빅엔디안 ------------------------------------> 리틀 엔디안
   송신       0x78  ->  0x56  ->  0x34  ->  0x12            수신
0x12345678                                                        0x78563412

그래서 결국 빅엔디안 방식으로 통일하기로 약속을 하였다.


바이트 순서의 변환
 - unsigned short htons(unsigned short);
 - unsigned short ntohs(unsigned short);
 - unsigned long htonl(unsigned long);
 - unsigned long ntohl(unsigned long);
 여기서 h는 호스트(host)바이트 순서를 의미하고, n은 네트워크(network)바이트 순서를 의미한다.
 그리고 s는 short형을 의미하고, l은 long형을 의미한다.(to는 영어 to를 뜻함)
 그렇다면 이것을 가지고 위의 함수들을 해석하면 이렇게 된다.

 - unsigned short htons(unsigned short); short형 데이터를 호스트바이트 순서에서 네트워크바이트 순서로 변환해라.
 - unsigned short ntohs(unsigned short); short형 데이터를 네트워크바이트 순서에서 호스트바이트 순서로 변환해라.
 - unsigned long htonl(unsigned long); long형 데이터를 호스트바이트 순서에서 네트워크바이트 순서로 변환해라.
 - unsigned long ntohl(unsigned long); long형 데이터를 네트워크바이트 순서에서 호스트바이트 순서로 변환해라.



 sockaddr_in server;
 memset(&server,0,sizeof(server));
 server.sin_family = AF_INET;
 server.sin_port = htons(10000);
 server.sin_addr.S_un.S_addr = htonl(ADDR_ANY);
 bind(m_hServer, (sockaddr*)&server, sizeof(server));

 sockaddr_in client;
 memset(&client,0,sizeof(client));
 client.sin_addr.s_addr = inet_addr(IP);
 client.sin_family = AF_INET;
 client.sin_port = htons(Port);
 connect(m_hClient, (sockaddr*)&client, sizeof(client));

여태까지 배운것들이 이 12줄을 위해 배운거랍니다. 하하하;;;

프로토콜이란?
 - 멀리 떨어져 있는 두 사람이 대화를 주고받기 위해서는 나름의 대화방법을 결정해야 하는데, 여기서 결정하는 대화방법을 프로토콜이라고 한다. 즉, '컴퓨터 상호간의 통신에 필요한 규약.'이라고 할 수 있다.


SOCKET socket(int af, int type, int protocol);
 - af(linux에선 domain) : 소켓이 사용할 프로토콜 체계(Protocol Family) 정보 전달.
 - type                        : 소켓의 데이터 전송방식에 대한 정보 전달.
 - protocol                  : 두 컴퓨터간 통신에 사용되는 프로토콜 정보 전달.


프로토콜 체계(첫 번째 인자값)
 - PF_INET       : IPv4 인터넷 프로토콜 체계
 - PF_INET6     : IPv6 인터넷 프로토콜 체계
 - PF_LOCAL   : 로컬 통신을 위한 UNIX 프로토콜 체계
 - PF_PACKET : Low Level 소켓을 위한 프로토콜 체계
 - PF_IPX         : IPX 노벨 프로토콜 체계


소켓의 타입(두 번째 인자값)
 - SOCK_STREAM(연결지향형 소켓)
      - 특징 : 중간에 데이터가 소멸되지 않고 목적지로 전송된다.
                : 전송 순서대로 데이터가 수신된다.
                : 전송되는 데이터의 경계(Boundary)가 존재하지 않는다.
      - 신뢰성 있는 순차적인 바이트 기반의 연결지향 데이터 전송 방식의 소켓

 - SOCK_DRAM(비 연결지향형 소켓) : 
      - 특징 : 전송된 데이터는 손실의 우려가 있고, 파손의 우려가 있다.
                : 전송되는 데이터의 경계(Boundary)가 존재한다.
                : 한번에 전송할 수 있는 데이터의 크기가 제한된다.
      - 신뢰성과 순차적 데이터 전송을 보장하지 않는 고속의 데이터 전송을 목표로 하는 소켓


프로토콜(세 번째 인자값)
 솔직히 첫번째와 두번째 인자값만으로도 충분히 우리가 원하는 유형의 소켓을 만들 수 있다. 그렇기 때문에 이 인자값에 0을 넣어주어도 상관이 없다. 하지만 한 가지 예외가 생긴다. 그 예외가 바로 하나의 프로토콜 체계 안에 데이터의 전송방식이 동일한 프로토콜이 둘 이상 존재하는 경우가 생길지도 모른다는 것이다. 그것을 구분해 주는 것이 바로 아래의 인자값들이다.
 - IPPROTO_TCP : 연결지향형 데이터 소켓.
 - IPPROTO_UDP : 비연결지향형 데이터 소켓.




#include<winsock2.h>
#pragma comment(lib, "ws2_32.lib")

SOCKET socket(int af, int type, int protocol);
 - 소켓을 생성해주는 함수.
매개변수
af          : 소켓이 사용할 프로토콜 체계(Protocol Familiy)정보 전달.
type       : 소켓의 데이터 전송방식에 대한 정보 전달.
proTocol : 두 컴퓨터 간 통신에 사용되는 프로토콜 정보 전달.
반환값
 - 성공 시 소켓 핸들, 실패 시 INVALID_SOCKET 반환


int bind(SOCKET s, const struct sockaddr *name, int namelen);
 - IP주소와 PORT번호 할당을 목적으로 하는 함수.
매개변수
s           : IP주소와 PORT번호를 할당받을 소켓을 전달.
name     :
namelen : name의 크기를 전달.
반환값
 - 성공 시 소켓 핸들, 실패 시 INVALID_SOCKET 반환


int listen(SOCKET s, int backlog);
 - 클라이언트 프로그램의 연결 요청을 받아들일 수 있는 상태가 되게 해주는 함수
매개변수
s          : 서버 소켓을 전달.
backlog : 연결을 기다리는 소켓들의 최대 크기를 전달.(보통은 SOMAXCONN를 넣어주네요.)
반환값
 - 성공 시 0, 실패 시 SOCKET_ERROR반환


SOCKET accept(SOCKET s, struct sockaddr *addr, int *addrlen);
 - 클라이언트 프로그램에서의 연결요청을 수락해주는 함수
매개변수
s          : 서버소켓 전달.
addr     : 서버의 자세한 설정을 전달.
addrlen : addr의 크기를 전달.
반환값
 - 성공 시 소켓 핸들, 실패시 INVALID_SOCKET 반환


int connect(SOCKET s, const struct sockaddr* name, int namelen);
 - 클라이언트가 서버에게 연결을 요청하는 함수.
매개변수
s           : 연결할 소켓 전달.
name     : 클라이언트의 자세한 설정을 전달.
namelen : name의 크기를 전달.
반환값
 - 성공 시 0, 실패 시 SOCKET_ERROR 반환


int closesocket(SOCKET s);
 - 소켓을 종료하는 함수.
매개변수
s : 종료하고 싶은 소켓 전달.
반환값
 - 성공 시 0, 실패 시 SOCKET_ERROR 반환

페도라 리눅스를 방금 막 설치한 유저라면 아마 GUI에서 작업중이실겁니다.
하지만 VMWare를 사용하다보니 GUI환경이라 그런지 Linux가 조금 느린것 같네 싶은 사람들에게 추천하는 CUI환경으로 바꾸는 방법입니다.




아래는 보이는 사진은 터미널 프롬프트를 킨 페도라 리눅스 화면입니다. 아직 GUI환경이지요.





su - root는 관리자권한으로 로그인 하는 것입니다. password는 자신이 등록한 password입니다.





Password를 입력하면 아래와같이 [root@localhost ~]라고 나와있고, 옆에 명령어를 입력할 수 있게 되어있습니다.





그 명령어 창에 vi /etc/inittab을 입력해주세요.
vi는 파일편집기 같은 것입니다.
/etc/inittab은 디렉토리구요.





그러면 이런 신기한 글들이 마구 뜰겁니다.
거기서 키보드의 i를 누르시면...
아래 그림의 맨 아래를 보시면 -- INSERT --라고 바뀔것입니다.
파일을 수정하겠다는 뜻입니다.





아래의 그림처럼  맨 아래의 id:5:initdefault:라는 부분을 id:3:initdefault:로 바꿔주세요.그리고 ESC를 사뿐히 눌러줍니다.





--INSERT--사라진거 보이시죠?






이제 그 창에 :wq를 입력하고 Enter를 눌러주세요.
w는 write의 약자로써 저장을 하겠다는 뜻이고,
q는 quit의 약자로써 종료를 하겠다는 뜻입니다.
즉, '저장하고 종료하겠다'라는 뜻입니다.
참고로 !를 붙여주면 무조건 하겠다는 뜻으로 오류도 무시한다는 뜻입니다. :q! 무조건 종료해라.





그러면 아래처럼 깔끔하게 원래 창으로 돌아옵니다!!
거기서 reboot명령어를 써서 재부팅~!@





하면 아래 도스창같은 창이 뜹니다. 옛날의 CUI죠...
localhost login에 호스트 명을 입력해주시고,





Password는 아시겠죠? 말그대로 비밀번호입니다.





그러면 아무것도 없이 터미널 프롬프트에서만 보던 것이 뜹니다.
이렇게 해놓으면 멋은 없지만..(ㅜ;;) 하면 훨씬 빨라집니다!!




mysql은 질의어인 sql(Structured Query Langauge)을 다루는 프로그램이고,
gcc는 리눅스기반의 c컴파일러입니다.

yum명령어
 - yum이란 온라인 저장소에서 업데이트 된 패키지들을 검사하고, 다운로드하여 설치까지 처리해주는 텍스트 기반의 업데이트 명령어입니다. 다운받아 설치해주는 툴이라고 요약할수 있습니다.

사용법
패키지 찾기
 # yum list available         설치가 가능한 패키지 목폭
 # yum list installed          이미 설치된 list 패키지 목록
 # yum list extras             일반 저장소에서 설치되지 않는 패키지 목록
 # yum list *vorbis*          'vorbis'타이틀이 있는 패키지 목록
 # yum list updates          업데이트 가능한 패키지 목록
 # yum info wordpress     wordpress패키지에 대한 설명
 # yum info word*            word로 시작되는 패키지 설명
 # yum search mp3          mp3문자열을 포함한 패키지의 검색
 # yum whatprovides ??    파일 또는 다른 형태의 패키지를 검색
패키지 설치
 # yum install XFCE                XFCE 패키지 다운로드 인스톨
 # yum groundinstall XFCE      XFCE 데스크톱 패키지의 전체 세트를 다운로드 인스톨
패키지 업데이트
 # yum check-update                 업데이트가 준비된 모든 패키지를 리스트한다.
 # yum list update openoffice*     openoffice*이름으로 이용 가능한 업데이트를 찾는다.
 # yum update openoffice*          모든 openoffice 패키지를 업데이트 한다.
 # yum update                           업데이트가 준비된 모든 패키지를 업데이트한다.
 # yum groupupdate XFCE          파일명 그룹의 모든 패키지를 업데이트한다.
패키지 제거하기
 # yum remove beagle                beagle 패키지를 제거한다.
 # yum remove xscreen*             xscreen으로 시작되고 있는 패키지를 제거한다.
 # yum groupremove 파일명         XFCE 그룹에서 모든 패키지를 제거한다.
패키지 지우기
 # yum clean packages              cache에서 패키지를 지운다.
 # yum clean metadata               cach에서 metadata를 지운다.
 # yum clean headers                cach에서 header를 지운다.
 # yum clean all                        cach에서 metadata, header, package를 지운다.

mysql설치
터미널 프롬프트 창에
# yum install mysql-server
# yum install mysql
# yum install mysql-devel
이렇게 입력 하면 됩니다.

gcc설치
터미널 프롬프트 창에
$ yum install gcc
이렇게 입력하면 됩니다.

설치 도중 Is this OK?(y/N)라고 질문하는데
y라고 답해주면 인스톨이 시작됩니다.

참고
rpm명령어
 - rpm이란 로컬 시스템(하드디스크 또는 CD/DVD)으로부터 이용할 수 있는 RPM 패키지를 설치 하기 위해 사용하는 명령어 입니다.

사람들은 주로 yum을 즐겨쓴답니다.