'Computer_language'에 해당되는 글 82건

  1. 2009.01.12 각 상속 테스트
  2. 2009.01.12 Ubuntu에서, c, c++관련 컴파일러 설치 [출처] Ubuntu에서, c, c++관련 컴파일러 설치|작성자 용이
  3. 2009.01.12 나눈 값을 표현하는 방법 즉 double 크기의 표현 방법 (float 4비트 double 8비트)
  4. 2009.01.12 Select를 이용한 채팅 서버
  5. 2009.01.12 소켓 주소 구조
  6. 2009.01.12 포인터 far near huge
  7. 2009.01.12 바이트 오더(Byte Order)에 대해서...
  8. 2009.01.12 [Transformation] htons [출처] [Transformation] htons|작성자 임종배
  9. 2009.01.12 [Transformation] htonl [출처] [Transformation] htonl|작성자 임종배
  10. 2009.01.12 max, min 함수 C / C++

각 상속 테스트

|

#include < iostream >
using namespace std;


class parent
{
public :
 parent(){value = 0;}
 void methodA(){cout << "methodA call!" << endl;}
protected :
 void methodB(){cout << "methodB call!" << endl;}
private :
 int value;
};


class child1 : public parent
{
public :
 child1(){value_child1 = 1;}
 void methodC(){cout << "methodC call!" << endl; methodB();} //부모로부터 상속받았기때문에 methodB에 접근허가
protected :
 void methodD(){cout << "methodD call!" << endl;}
private :
 int value_child1;
};


class child2 : protected parent
{
public :
 child2(){value_child2 = 2;}
 void methodE(){cout << "methodE call!" << endl; methodB();} //부모로부터 상속받았기때문에 methodB에 접근허가
protected :
 void methodF(){cout << "methodF call!" << endl; }
private :
 int value_child2;
};


class child3 : private parent
{
public :
 void methodG(){cout << "methodG call!" << endl; methodB();} //부모로부터 상속받았기때문에 methodB에 접근허가
};


void main()
{
 child1 childtest;
 childtest.methodA();
 //childtest.methodB();  //에러발생 protected 멤버 접근 불가
 childtest.methodC();
  //childtest.methodD();  //에러발생 protected 멤버 접근 불가
 //cout << childtest.value << endl; //에러발생 private 멤버 접근 불가
 //cout << childtest.value_child1 << endl; //에러발생 private 멤버 접근 불가

 cout << endl;


 child2 childtest2;
  //childtest2.methodA(); //에러발생 protected로 상속받았기때문에 public 이더라도 사용할 수 없음
 //childtest2.methodB(); //에러발생 protected 멤버 접근 불가

 childtest2.methodE();
  //childtest2.methodF(); //에러발생 protected 멤버 접근 불가
 //cout << childtest2.value << endl; //에러발생 private 멤버 접근 불가

 cout << endl;


 child3 childtest3;
 childtest3.methodG();
}


실행결과

methodA call!
methodC call!
methodB call!


methodE call!
methodB call!


methodG call!
methodB call!
Press any key to continue

출처 : 직접작성 및 Teach Yourself C++ - Visual Studio.NET 2003을 기준으로 작성됨


And

Ubuntu에서, c, c++관련 컴파일러 설치 [출처] Ubuntu에서, c, c++관련 컴파일러 설치|작성자 용이

|

gcc,g++,glibc 컴파일러 설치

 

http://packages.ubuntu.com/hardy/ 에서 라이브러리 찾기

package list : http://packages.ubuntu.com/feisty/

:~$sudo apt-get install libc-dev : 컴파일러

:~$sudo apt-get install libc6-dev : glibc 설치
:~$sudo apt-get install gcc : gcc 컴파일러 설치
:~$sudo apt-get install g++ : g++ 컴파일러 설치
:~$sudo apt-get install libncurses5-dev :ncurese 설치

:~$sudo apt-get install libstdc++6
:~$sudo apt-get install build-essential : GNU C Library

:~$sudo apt-get install build-essential bin86 kernel-package

                                                   :gcc, make, g++

:~$sudo apt-get install libqt3-headers libqt3-mt-dev

                                                   :make Xconfig를 위해 필요

JDK 설치

 

:~$sudo apt-get install sun-java6-jdk

 

Eclipse 설치

:~$sudo apt-get install eclipse

:~$sudo apt-get install eclipse-cdt

 

:~$sudo apt-get install make  : make 설치


And

나눈 값을 표현하는 방법 즉 double 크기의 표현 방법 (float 4비트 double 8비트)

|
다음은 MSDN 발췌한건데 모두 double 을 표현 하는 방법입니다.

%e
Signed value having the form [ – ]d.dddd e [sign]ddd where d is a single decimal digit, dddd is one or more decimal digits, ddd is exactly three decimal digits, and sign is + or –.

%E
double Identical to the e format except that E rather than e introduces the exponent.

%f
double Signed value having the form [ – ]dddd.dddd, where dddd is one or more decimal digits. The number of digits before the decimal point depends on the magnitude of the number, and the number of digits after the decimal point depends on the requested precision.

%g
double Signed value printed in f or e format, whichever is more compact for the given value and precision. The e format is used only when the exponent of the value is less than –4 or greater than or equal to the precision argument. Trailing zeros are truncated, and the decimal point appears only if one or more digits follow it.

%G
double Identical to the g format, except that E, rather than e, introduces the exponent (where appropriate).

출처 : MSDN


And

Select를 이용한 채팅 서버

|
select function
 
NAME
                            select
SYNOPSIS
                            #include <sys/socket.h>
                            #include <sys/time.h>
                            int select(int maxfd, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout)
RETURN
                            Return : descriptor count, 0 on timeout, -1 on error


기능 : process가 kernel에게 명령하여 다수의 event 중 하나를 기다리다 지정된 시간이 지나가거나 사건이 발생하면 process를 깨우도록 함
maxfd - 감시할 소켓의 총 갯수 +1
fd_set - 조사 대상의 descripter를 저징할 변수
struct  timeval
{
     int tv_sec;           /* second */
     int tv_usec;         /* microsecond */
};
      하나라도 준비 될 때까지 얼마나 기다려야 하는지 명시
      NULL - 영원히 기다린다.
      0 - 기다리지 않는다.

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <string.h>

#define MAXLINE 512
#define MAX_SOCK 64
char *escapechar = "exit";
int maxfdp1;
int num_chat = 0;                                                                               /* 채팅 참가자 수 */
int client_s[MAX_SOCK];
/* 채팅 탈퇴 처리 */
void removeClient(int i)                                                                        /* i번째 참가자 탈퇴 */
{
 close(client_s[i]);                                                                         /* 해당 소켓 닫기 */
 if(i !=num_chat -1)
  client_s[i] = client_s[num_chat -1];                                                    /*  i번째 참가자와 맨 마지말 참가장의 위치 switch*/
 num_chat --;                                                                               /* 채팅 참가자 수 1명 줄이기 */
 printf("채팅 참가자 1명 탈퇴. 현재 참가자 수 = %d\n",num_chat);
}
/* client_s[]내의 최대 소켓번호 얻기 (k는 초기치)*/
int getmax(int k)
{
 int max = k;
 int r;
 for(r = 0; r < num_chat ; r++)                                                              /* 채팅 참가자 수만큼 소켓 배열 탐색 */
  if(client_s[r] > max)
   max = client_s[r];
 return max;
}
int main(int argc, char *argv[])
{
 char rline[MAXLINE], my_msg[MAXLINE];                                                       /* buffer 생성 */
 char *start = "Connetctd to chat_server\n";                                                 /* 최초 연결시 보내는 메세지 */
 int i,j,n;
 int s, client_fd, clilen;
 fd_set read_fds;
 struct sockaddr_in client_addr, server_addr;                                                /* 소켓주소 구조체 선언 */
 if(argc != 2)                                                                               /* 포트번호를 입력 안했을 경우 */
 {
  printf("사용법 : %s port\n", argv[0]);
  exit(0);
 }
 /* 초기소켓 생성 */
 if((s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
 {
  printf("Server: Can't open stream socket.");
  exit(0);
 }
 /* server_addr 구조체의 내용 세팅 */
 bzero((char *)&server_addr,sizeof(server_addr));                                           /*초기화(0으로 채운다) */
 server_addr.sin_family = AF_INET;
 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 server_addr.sin_port = htons(atoi(argv[1]));
 if(bind(s,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0 )                        /* bind() */
 {
  printf("Server: Can't bind local address.\n");
  exit(0);
 }
 /*클라이언트로부터 연결요청을 기다림 */
 listen(s,5);                                                                                /* listen 접속 대기 (큐 크기 5) */
 maxfdp1 = s + 1;                                                                           /* 최대 소켓번호 +1 */
 while(1)
 {
  FD_ZERO(&read_fds);                                                                     /* fd_set  초기화(0으로 세팅)  */
  FD_SET(s,&read_fds);                                                                    /* 소켓에 해당하는 file discripter를 1로 세팅*/
  for(i=0; i<num_chat; i++)                                                               /* "" */
   FD_SET(client_s[i], &read_fds);
  maxfdp1 = getmax(s) +1;                                                                 /* maxfdp1 재 계산 */

  if(select(maxfdp1,&read_fds, (fd_set  *)0, (fd_set *) 0, (struct timeval *) 0) < 0)     /* select setting */
  {
   printf("select error =< 0 \n");
   exit(0);
  }
  if(FD_ISSET(s, &read_fds))                                                              /* read_fds 중 s에 해당하는 비트가 세팅되있다면 */
  {                                                                                       /* == 연결요청이 있다면 */
   clilen = sizeof(client_addr);
   client_fd = accept(s, (struct sockaddr *)&client_addr, &clilen);                    /*  accept() */
   if(client_fd == -1)
   {
    printf("accept error \n");
    exit(0);
   }
   /* 채팅 클라이언트 목록에 추가 */
   client_s[num_chat] = client_fd;
   num_chat++;                                                                         /* 채팅 참가자수 1 증가 */
  send(client_fd,start,strlen(start),0);                                              /* "Connetctd to chat_server" 를 접속한 클라이언트에 보냄  */
   printf("%d번째 사용자 추가,\n",num_chat);
  }
  /*클라이언트가 보낸 메시지를 모든 클라이언트에게 방송 */
  for(i = 0; i<num_chat; i++)                                                             /* 모든 클라이언트 검색 */
  {
  memset(rline,'\0',MAXLINE);                                                         /* buffer 초기화 */
   if(FD_ISSET(client_s[i],&read_fds))                                                 /* read 해당 소켓에서 read 할 것이 있는지 확인 */
  {
    if((n = recv(client_s[i],rline,MAXLINE, 0 )) <= 0)
    {
    removeClient(i);
     continue;
    }
    /* 종료문자 처리 */
    if(strstr(rline,escapechar) != NULL)                                            /*"exit"가 입력되면 종료시키기 */
    {
     removeClient(i);
     continue;
    }
    /* 모든 채팅 참가자에게 메시지 방송 */
    rline[n] = '\0';
    for(j = 0; j < num_chat; j++)
     send(client_s[j],rline,n,0);
    printf("%s\n",rline);
   }
  }
 }
 return 0;
}

And

소켓 주소 구조

|

소켓 주소 구조

<netinet/in.h>
 
 struct socketaddr_in
{
    uint8_t               sin_len;                    /* length of structure(16) */
    sa_family_t        sin_family;                 /* AF_INET */
    in_port_t            sin_port;                   /* 16 bit TCP or UDP port number */
                                                          /* network byte ordered */
    struct in_addr    sin_addr;                  /* 32-bit IPv4 address */
                                                          /* network byte ordered */
    char                 sin_zero[8];              /* unused */
};

struct in_addr
{
    uint32_t             s_addr;                    
}  



 * 4.3BSD-RENO 에서 필요한 데이터형, POSIX에서는 꼭 필요한 것이 아니다.
 * sin_zero 원소는 사용되지 않지만 항상 0으로 설정
 * 이 구조체 전체가 교환되지는 않는다.

일반적인 소켓 주소 구조체
<sys/socker.h>

struct sockaddr
{
    unit_8_t     sa_len;
    sa_family_t    sa_family;
    char    sa_data[14];
}

 * 소켓 함수의 인자로 전달할 때 참조하는 구조로써 공통된 모양이다.
 * 응용 프로그램 관점에서 보면 유일한 용도는 프로토콜에 따른 구조로 변형하는 것.

And

포인터 far near huge

|
결국 16비트때 사용하던 포인터 인데..
현재의 32 환경에서는 그냥 일반 포인터와 같은 의미 입니다.
자세히 아실 필요 없을 거에요.
컴퓨터 구조섭을 좀 들으셨으면 이해에 도움이 될라나...
쉽게 말해.. 구닥다리 입니다. 16비트 시절용.


[far 포인터 변수와 near 포인터 변수, 그리고 huge 포인터 변수]

IBM-PC의 주소는 2가지가 존재하는데, 우선 가장 많이 사용되는 near 포인터의 경우에는 오프셋 값만 주소로 갖게 된다. 이 경우 세그먼트 주소는 고정되어 있음을 의미한다. 따라서 near 포인터 변수의 크기는 16비트가 되며 현재 고정된 세그먼트 주소로부터 64K 바이트 이내의 값만 주소로 갖게 된다. 반면에 far 포인터 변수는 세그먼트 주소와 오프셋을 각각 16비트씩 값으로 갖는다. 따라서 far 포인터 변수는 32비트의 크기를 갖게 되며 주기억 장치의 어느 곳이나 주소를 값으로 가질 수 있다. huge 포인터는 far 포인터와 유사하나 오프셋의 값이 항상 0에서 15사이의 값을 갖도록 만든 것이 다르다. 이 주소를 사용하면 주기억 장치의 한 장소 중에서 주소가 딱 하나로 결정되는 장점이 있다.
포인터를 far 또는 near, huge로 선언하고자 할 때에는 다음과 같이 변수 이름과 데이터 유형 사이에 키워드를 집어 넣으면 된다.

int near *ip; /* 포인터 앞에 아무것도 없을 경우에는 사용하는 */
char far *cp; /* 메모리 모델에 의해 near, far, huge 등이 결정된다 */
float huge *fp;
And

바이트 오더(Byte Order)에 대해서...

|

걸리버 여행기에서 소인국 이야기가 나옵니다. 소인국은 그곳에서 2개의 나라로 나누어서 서로 시기하고 싸우고 있다. 소인국 사람들이 계란을 깰 때 큰 쪽(둥근 쪽)을 깨느냐 작은 쪽(뾰족한 쪽)을 깨느냐를 가지고 패가 갈려서 싸웠다죠. 큰 쪽이 big end, 작은 쪽이 little end, 큰 쪽을 깨는 사람들을 big endian, 그 반대쪽을 깨는 사람들을 little endian이라고 부른 것이 엔디안의 기원이라고 합니다.

 컴퓨터에 있는 바이트 오더에 little endian & big endian을 정리해 볼려고 합니다.

(솔직히 저는 little endian만 고려하고 프로그램을 개발했습니다. 즉, Intel CPU만 고려했지요ㅠ,.ㅜ)


  1. Intel 시스템의 경우

  a = 0x1000
   +----------+----------+----------+----------+
   | 00000001 | 00000000 | 00000000 | 00000000 |  a
   +----------+----------+----------+----------+

  *(char *)&a 의 값은 0x1000 번지의 1byte를 읽어들이게 되어서 1의 값이 됩니다.


  2. IBM PC 계열(Power PC)

  a = 0x1000
   +----------+----------+----------+----------+
   | 00000000 | 00000000 | 00000000 | 00000001 |  a
   +----------+----------+----------+----------+

  *(char *)&a 의 값은 0x1000 번지의 1byte를 읽어들이게 되어서 0의 값이 됩니다.


즉, Low level 프로그램을 개발하거나 또는 이 기종 컴퓨터로 네트워크를 통해서 데이타를 보낼때는 미리 알고 있어야 합니다. 미리 알아낸 바이트 오더를 이용해서 다른 기종간의 통신을 할 때에 바이트 오더의 순서를 바꾸어서 보내주어야 합니다.


아래 코드는 컴퓨터에서 바이트 오더를 간단하게 알아내는 방법입니다.


BOOL IsLittleEndian()

{

    BOOL bRet = TRUE;
    int a = 1;

    if( *(char *)&a == 1 )

    {

        bRet = TRUE;

        printf("Little endian.\n");

     }
    else

    {

        bRet = FALSE;

        printf("Big endian.\n");

     }

    return bRet;
}


마지막으로 바이트 오더 순서를 바꾸어 주는 함수를 정리해 보았습니다.

포인터에 관한 내용은 아니지만 바이트 오더의 순서를 바꾸어 주는 함수들이 있습니다.

  • htons(), htonl()

    htons는 Host to network short 의 줄임말입니다. Host 시스템에서 Network로 short 형 데이터를 보낼 때 바이트 오더를 바꾸어주는 함수입니다.

    htonl은 Host to network long 의 줄임말로 long 형 데이터의 바이트 오더를 바꾸어주는 함수입니다.

  • ntohs(), ntohl()

    ntohs는 Network to host short 의 줄임말로 Network에서 Host로 short형 데이터의 바이트 오더를 바꾸어주는 함수입니다.

    ntohl은 Network to host long의 줄임말로 long 형 데이터의 바이트 오더를 바꾸어주는 함수입니다.

위의 함수들은 소켓을 통해 다른 기종간에 데이터를 전송하거나 또는 받아들여서 자신의 바이트 오더에 맞게 변환해 줄 때 사용하는 함수입니다.


결론 : 이기종 컴퓨터와 네트워크 통신하기 전에 Little endian 인지 Big endian 인지를 알아내서 서로의 바이트 오더 정보를 교환한 다음에 그 바이트 오더에 맞추어서 데이터를 통신하게 되면 정확한 데이터를 송수신해야 한다.


출처 : 다년간의 프로그램밍 삽질(경험) 및 구글 사마

 from : http://blog.naver.com/process3?Redirect=Log&logNo=20029237790


And

[Transformation] htons [출처] [Transformation] htons|작성자 임종배

| 2009. 1. 12. 00:43
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

[Transformation] htonl [출처] [Transformation] htonl|작성자 임종배

| 2009. 1. 12. 00:42
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

max, min 함수 C / C++

| 2009. 1. 12. 00:42
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
prev | 1 | ··· | 4 | 5 | 6 | 7 | 8 | 9 | next