물론 고수님들에겐 쉬운 문제지만 다음 구조체에서 char data[1]의 역할이 무엇인지 생각 해봅시다. 모르시는 분들은 최소 1분 정도 생각을 해봅시다. 그래도 잘 모르겠으면 약간의 힌트: 난생 처음 이런 구조체를 보면 data[1] 변수가 도대체 어떤 의미인지 감을 잡기 힘들다. 왜 이런 변수가 쓰이는지는 직접 예제 코드를 보는 것이 가장 좋을 것 같다. 한 마디로 char data[1]의 의미는 길이가 정해지지 않은 데이터를 담기 위한 일종의 더미 변수라고 보면 된다. 예에서도 있듯이 이런 코딩 테크닉은 어떤 데이터의 헤더를 표현할 때 많이 등장한다. 메모리 덩어리를 할당 받고 그것을 이 헤더 타입으로 캐스팅을 하면 앞 부분은 헤더가 놓이고 바로 뒤에 갖고 싶은 가변 길이 데이터를 쉽게 이을 수 있다. 윈도우 프로그래밍을 해보신 분이라면 아마 이런 것을 자주 봤을 것이다. 예를 들면: RGN이라는 그래픽에서 그리는 영역을 지정하는 클리핑 객체를 담는 자료구조다. RGNDATA에 채워질 데이터가 몇 개나 올지 알 수 없으므로 이렇게 하였다. 또, 대표적인 비트맵 파일 관련 구조체도 빼놓을 수 없다. 배열 크기가 여기는 [1]인데 [0]으로 둬도 사실 문제 없다. 그리고 소켓 프로그래밍할 때 보게 되는 hostent에도 이제는 과거 호환성 때문에만 남았지만 크기가 0인 배열을 볼 수 있다. 그런데 보통 크기 0인 배열을 선언하면 컴파일러가 워닝을 띄운다. 그래서 C99 표준에는 flexible array member라고 해서 맨 마지막 구조체 변수의 선언이 char data[] 처럼 될 수 있도록 하기도 한다. 그렇다면 왜 이렇게 했을까? 보다 직관적으로 코드를 만든다면 아래처럼 쓸 수도 있다. typedef struct tagHEADER { 그러나 이 접근은 단점이 있다. 위에서 예를 들었듯이 이 자료구조를 파일에 쓴다고 하면 헤더 부분 따로 그리고 data 영역을 따로 두 번에 걸쳐 파일 쓰기를 해야 한다. 결국 이 말은 이 자료구조에 접근하려면 헤더 한번, 실제 한번, 즉 두 번의 참조가 필요하다는 이야기다. 여기서 쪼잔하게 따지면 위 코드는 데이터 참조의 지역성(locality)이 줄어들어 캐시 미스를 한번 더 유발할 수 있는 단점도 있다. 요즘 프로세서들 캐시가 수 메가 바이트니 이 정도 괜찮다라는 생각을 함부로 하지 말자. 정말 성능이 중요한 프로그램은 이런 사소한 지역성 차이에서 오는 차이를 결코 무시할 수 없다. 비슷한 예로 “구조체의 배열(Array of Structure)” 이냐 “배열의 구조체(Structure of Array)”라는 문제도 있다 (우리말과 영어의 어순이 반대라 이거 이름이 참 헷갈린다). 간단한 예를 보면.. 구조체의 배열(Array of Structure, AoS): 배열의 구조체(Structure of Array, SoA): 각각 상황에 따라 적절히 선택해서 골라야 한다. 사소해 보이지만 경우에 따라 큰 성능 차이가 나타날 수 있다. AoS 같은 접근은 루프 한 순회에서 모든 원소들이 접근될 때 유리하다. vector[i]을 읽으면 일단 i번 째 x, y, z는 모두 캐시에 올라오기 때문이다. 반면 원소는 3개인데 루프에서 고작 x원소만 접근 된다면? 이 vector 배열이 매우 크다면 손실은 심각하다. 그럴 때는 SoA 구조가 바람직하다. 그 외에도 사소한 영향을 더 생각할 수 있지만 생각보다 글이 길어져서 이쯤에서 그만.. 한줄요약: char data[1]; 같은 것이 보여도 쫄지 맙시다.typedef struct tagWHATTHE {
int data1;
int data2;
char data[1];
} WHATTHE;
typedef struct tagWHATTHE {
int size;
int type;
char data[1];
} WHATTHE;
char data[1]의 역할은
typedef struct tagHEADER {
int size;
int type;
char data[1];
} HEADER;
// int data_length, int* data;
HEADER* hd = (HEADER*)malloc(sizeof(HEADER) + data_length);
hd->size = sizeof(HEADER) + data_length;
hd->type = 0;
memcpy(hd->data, data, data_length);
fwrite(hd, 1, hd->size, file_handle);typedef struct _RGNDATAHEADER {
DWORD dwSize;
DWORD iType;
DWORD nCount;
DWORD nRgnSize;
RECT rcBound;
} RGNDATAHEADER;
typedef struct _RGNDATA {
RGNDATAHEADER rdh;
char Buffer[1];
} RGNDATA; typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO; 도대체 왜?
int size;
int type;
char* data;
} HEADER;
HEADER* hd = (HEADER*)malloc(sizeof(HEADER));
hd->size = 1024;
hd->type = 0;
hd->data = (char*)malloc(hd.size);
...struct {
double x;
double y;
double z;
} vector[4];struct {
double x[4];
double y[4];
double z[4];
} vector_set;
Trace
- [펌] 배열 [0] [1]의 의미... char data[0] 2011.01.27
- [펌] wget을 이용한 웹 긁어오기 2011.01.21
- 크리티컬 섹션, 뮤텍스, 세마포어 2011.01.19
- RJ(Registered Jack) 2011.01.17
- RAW 소켓 2011.01.17
- ARP (Address Resolution Protocol) 2011.01.14
- Out of Order / InOrder (아톰) 2011.01.14
- 리눅스 utf-8 캐랙터셋 변경 2011.01.11
- find 명령어 2011.01.11
- sizeof 연산자 2011.01.10 3
[펌] 배열 [0] [1]의 의미... char data[0]
[펌] wget을 이용한 웹 긁어오기
팁이라기 보다는 문제 제기에 가깝습니다. ==================== 출처 http://phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=62537&page=1 http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=62631&page=1
리눅스에서 wget의 용도는 참 다양합니다.
다른 홈페이지의 뭔가를 가져오고(때로는 긁어오고...) 제 경우는 내부에서 php를 실행할때로 자주 사용합니다.
근데 man wget 하고 여러 옵션을 구경하다가
-r
--recursive
라는 놈이 있어서 한번 실행을 해봤습니다.
아예 홈페이지의 내용을 디렉토리채 긁어오는군요.
테스트해보시려면
wget http://www.phpschool.com -r 해보십시요.
www.php.school.com 이라는 폴더가 하나 생기고 그 하위 폴더들이 주루룩 나오는군요.
디렉토리 스트럭처가 적나라하게 보입니다.
banner community guild index.html survey
biznbaza company html_sub index.php title_image
class gnuboard4 images menu_images ttrend
물론 php 소스가 아니고 출력된 html의 형태로 저장되기는 하지만 기타 css, js, 이미지등등은 그대로 가져오는군요.
저만 모르고 있었던 것인가요?
뒷북이라면 죄송합니다만....
여기서 하나...
남의 홈페이지 긁어오는 데는 그만이지만
반대로 누군가 내 홈페이지를 긁어가는 것은 기분이 엄청 나쁠 것같습니다.
해서~~
아무리 생각해봐도 wget을 막기는 막아야할 것같습니다만..
이놈이
-U agent-string
--user-agent=agent-string
옵션까지 무장을 하고 있어서 agent로 차단하는 것은 불가능해보입니다.
혹씨나해서 살펴보니 robots.txt가 먹히는군요.
User-agent:*
Disallow:/
하니까 못 긁어가네요.
더좋은 방법이 있는지 모르겠습니만...
참고하시기를...
크리티컬 섹션, 뮤텍스, 세마포어
관련된 이론 분야 : 운영체제론 크리티컬 섹션(임계구역) / 뮤텍스(상호배제) / 세마포어 이것들은 한양대 컴공과 3학년 1학기 과정에 있었던 운영체제론의 핵심적인 내용이었습니다. 허신 교수님의 운영체제론 수업을 들었었는데 이론의 맥을 잘 짚어주셨던 기억이 나네요. 열심히(?) 공부해서 시험도 보고 성적도 좋았지만 막상 그 개념들을 실제로 적용해볼 기회가 없으니 개념이 좀 두리뭉실해서 한 번 정리해 보았습니다. 제가 이해한 내용을 복습하기 위해 정리한 것이라서 틀릴 수도 있으니 많은 성원 바랍니다 (뭔 소리야 ㅋㅋ) 모두 동기화 오브젝트에 관련된 이론인데... 이 이야기를 할 때면 어김없이 나오는게 호프집 화장실에서 똥싸는 이야기더군요 - _ -;; 오늘의 수업은 이름하여... 미쉘린의 호프집 화장실 이론 1. 크리티컬 섹션 (임계구역), Critical Section 호프집에 화장실이 있습니다. 이 화장실에는 변기가 하나밖에 없습니다. 그래서 한 번에 한 사람씩 들어가야 되지욤... (화장실 안에 서서 기다리면서 누가 똥싸고 오줌싸는걸 지켜볼 수는 없는 노릇) 이 변기가 크리티컬 섹션입니다. 프로그래밍할 때에는 주로 CS (Critical Section)라고 언급됩니다. MFC 에는 크리티컬 섹션에 대한 클래스가 정의되어 있어서 다음과 같이 사용할 수 있습니다. CCriticalSection RestRoom; RestRoom.Lock(); 용변보기 RestRoom.Unlock(); Lock() 과 Unlock() 사이의 구간이 크리티컬 섹션입니다. 스레드에서 이렇게 정의한 부분은 한 번에 하나의 스레드만 접근할 수 있습니다. (스레드에 대한 이야기는 제 지난 컴퓨터 이론 포스트를 참고하시기를...) 호프집에 동수, 일구, 빠박이가 있습니다. 셋이서 신나게 술을 마십니다. 어느순간 세사람 모두 오줌이 마렵습니다. 동수일행 프로세스 CCriticalSection RestRoom; // 전역변수 동수 스레드 { 일구, 빠박이랑 술마시기 if ( 오줌마렵다 ) { RestRoom.Lock(); 용변보기 RestRoom.Unlock(); } } 일구 스레드 { 동수, 빠박이랑 술마시기 if ( 오줌마렵다 ) { RestRoom.Lock(); 용변보기 RestRoom.Unlock(); } } 빠박이 스레드 { 동수, 일구랑 술마시기 if ( 오줌마렵다 ) RestRoom.Lock(); 용변보기 RestRoom.Unlock(); } } 지난 포스트에 하나의 주 프로세스가 여러 개의 스레드를 생성하여 CPU 상에서 여러 개의 스레드가 돌아간다는 이야기를 했습니다. 동수, 일구, 빠박이는 모두 각각의 독립적인 스레드입니다. 프로그램이 종료할 때까지 (호프집에서 나갈 때까지) 항상 CPU 상에서 돌아가고 있지요. 술마시다가 어느순간 세 사람 모두 오줌이 마렵습니다. 동수가 먼저 화장실로 냅다 달립니다. 동수 : 일구야 ~ 형 먼저 갈께 ㅜ0ㅜ 일구 : 아 ㅅㅂ~~~ 빠박이 : 가지마 ~~~~~ 동수가 먼저 가서 용변을 봅니다. 화장실은 한 사람 밖에 들어갈 수 없기 때문에 동수가 화장실에 들어가는 순간 RestRoom.Lock() 이 됩니다. RestRoom.Lock() 걸리면 다른 스레드는 RestRoom.Lock() 구간에 서서 Unlock() 이 될 때까지 무작정 기다립니다. ... 일구랑 빠박이는 화장실 문앞에 서서 기다립니다. 동수가 용변보고 나오면 RestRoom.Unlock() 이 됩니다. 그럼 이제 일구랑 빠박이중 누군가 먼저 들어간 사람이 RestRoom.Lock() 을 다시 호출하겠지요. 요 화장실 RestRoom Lock() ~ Unlock() 구간이 바로 CS ..... 크리티컬 섹션 입니다. 2. 뮤텍스, Mutex 뮤텍스의 용도는 기본적으로 CS 와 같습니다. 간단하게... 어렵지 않게... 헷갈리지 않게... 차이점만 짚어봅시다. CS 는 단일 프로세스의 스레드에 대해서만 동작합니다. 반면에, 뮤텍스는 여러 프로세스의 스레드에 대해서도 동작합니다. 동수 일행이 호프집에 들어오는 순간 3 개의 스레드가 생성됩니다. (동수 / 일구 / 빠박이 스레드) 엇 ?? 근데 또 다른 일행이 호프집에 들어왔습니다. 봉팔 일행입니다. (봉팔 / 상팔 / 영팔 ) - 이름만 다를 뿐 동수 일행과 똑같은 프로세스 입니다. (메모리상에 똑같은 프로그램의 프로세스 2 개가 올라왔다고 생각하면 됩니다. 두 번 실행됐다는 말) 얘들이 들어오면서 또 3 개의 스레드가 생성됩니다. 메모리상에는 6 개의 스레드가 돌아가고 있습니다. 이제... ( 동수 / 일구 / 빠박이 ) // ( 봉팔 / 상팔 / 영팔 ) 각각의 스레드가 동시에 화장실에 가지 못하도록 해야 합니다. 이 때, 뮤텍스를 사용합니다. CS 를 사용하게 되면 중복된 리소스 점유가 발생할 수 있기 때문입니다. 위 코드를 보면 RestRoom 은 동수 일행 프로세스의 전역 변수로 선언되어 있습니다. 그래서 동수 일행끼리는 "동수가 화장실에 갔으니까 일구랑 빠박이는 화장실에 갈 수 없다" 는 사실을 전역변수 CCriticalSection RestRoom 을 통해 명시적으로 알 수 있습니다. 하지만 봉팔 일행은 동수 일행의 RestRoom 과는 또다른 그들만의 RestRoom 을 가지고 있으므로 동수 일행중 누군가가 화장실에 있는지 여부는 판단할 수 없습니다. 그래서... "지금 화장실에 아무도 없으니까 누구든지 가도 된다" 는 결정을 내립니다. 봉팔이가 화장실로 달려가는 순간 화장실 문이 열리고 동수가 용변보는 모습을 발견합니다 !! 봉팔 : (엇.......!! 아무도 없는줄 알았는데 누가 있잖아 !!) 결국 봉팔이는 용변을 못 보고 예기치못한 사태에 멈춰 서 있게 됩니다. (실제로 이런식으로 프로그래밍을 하면 런타임 오류가 나지 않을까 생각되네요... 실제로 안해봐서 생각만...;;) 3. 세마포어, Semaphore 복잡하니 쉽게 갑시다... 세마포어는 CS, 뮤텍스가 가지는 특징에 하나를 더 가집니다. 세마포어는 특정 영역의 코드를 실행하는 스레드의 최대 개수를 설정할 수 있습니다. 지금은 1인용 화장실을 언급하였지만... 만약 호프집에서 화장실을 증축하여... 4인용 화장실이 되었다면... 이제 4명까지 화장실에 들어갈 수 있습니다. 이런 카운터를 세마포어로 구현할 수 있고 4인용 화장실 CSemaphore semaphore(0, 4); 첫번째 매개변수 : 리소스 카운터의 초기값 두번째 매개변수 : 리소스 카운터의 최대값 다시 돌아가서... 1인용 화징실에 열쇠라는 개념을 도입하여... 1인용 화장실 CSemaphore key(0, 1); 이런식으로도 활용이 가능합니다. 음... 여기에 또 문제가 생기는데 만약 누군가 1인용 화장실의 열쇠(세마포어)를 가지고 도망가버리면 아무도 화장실에 들어갈 수 없는 문제가 생깁니다. 이건 데드락이라고 하는건데... 오늘은 여기까지 ! 다음 기회에 ~~~~~~~~~ p.s : 제 생각을 정리한 내용이니 틀린 내용이 있을 수 있습니다 ;;;;;; 출 처 : http://blog.naver.com/thx4alice?Redirect=Log&logNo=110022369987 [출처] 크리티컬 섹션, 뮤텍스, 세마포어|작성자 미쉘린
RJ(Registered Jack)
- RJ는 FCC(미국 연방 통신 위원회)에 등록된 전화 접속 인터페이스들로서, 리셉터클(암 커넥터)과 플러그(수 커넥터)를 말한다. - 이것들은 AT&T의 USOC의 일부였던 인터페이스들에서 파생되었으며, RJ-11(전화), RJ-45(네트워크 통신)이 대표적이다. RJ-11 - 주변에 쉽게 있지만 관심없으면 볼 수 없는 전화에 이용되는 잭이다. - 컴퓨터를 모뎀으로 통신하였을 당시에는 RJ-11잭을 사용하였다. - 6개의 도선을 가지고 있으나, 4개만이 사용되며, 평범한 전화선을 사용하며 가정이나 사무실에서 쓰인다. - 전화회사의 교환기에 접속되어 있는 외부의 연선에 연결된다. - 4개의 선은 적색, 녹색, 흑색, 백색이다. RJ-45 - 평범한 전화선을 통해 디지털 전송을 하기 위한 단일회선 잭이다. - 8개의 핀을 가지며, 표준규격에 따라 회선의 사용 수가 다르다. - Ethernet(10BaseT), Token Ring 등 대부분 4개의 회선을 사용한다. - UTP Cat.3 100Mbps로 전송하는 IEEE802.3u표준규격(100BaseVG[Voice Grade])에서는 8개의 회선을 사용한다. - 100BaseT는 10BaseT처럼 4개의 회선을 사용하나, Cable Spec이 Cat.5 이여만 한다. 출 처 : http://blog.naver.com/demonicws?Redirect=Log&logNo=40117315270 [출처] RJ(Registered Jack)|작성자 Stein
RAW 소켓
RAW소켓 RAW소켓은 '가공하지 않은 소켓' 이다 일반적인 소켓 함수는 네트워크를 통해 데이터를 주고 받을때 헤더정보를 붙이거나 떼어내는 등의 가공을한다 그 이유는 주고받는 데이터가 중요한것이지 헤더정보는 별로 중요하지 않기 때문이다 이런 헤더를 때고 붙이고 하는 부분은 운영체제의 프로토콜 스택 내에서 자동으로 일어난다 따라서 프로그래머는 헤더를 접할 기회가 없다 그렇지만 경우에 따라서는 이런 헤더를 직접 제어해야 될 필요가 있다 예를 들어, 새로운 프로토콜을 만든다든지, 헤더의 정보를 이용한 보안프로그램 등을 만들때이다 RAW소켓은 이러한 헤더 정보들에 대한 가공을 하지 않고, 프로그래머가 직접 제어할 수 있게 한다
일반적인 소켓의 흐름도
RAW소켓의 데이터 흐름도
RAW소켓을 사용하면 이렇게 IP헤더와 TCP헤더를 직접 제어할 수 있다
위의 데이터 흐름도에서 TCP헤더와 IP헤더가 붙었지만 꼭 IP헤더와 TCP헤더일 필요는 없다
즉, 네트워크 계층 헤더와 전송 계층 헤더 중 어떤 종류가 와도 상관없다
RAW소켓에서는 IP헤더와 TCP헤더 모두 사용자 데이터로 취급하기 때문이다
따라서 RAW소켓으로 TCP데이터를 전송하고 싶다면 IP헤더와 TCP헤더를 보내고자 하는 데이터 앞부분에 직접 만들어 주어야 한다
출처 : http://blog.naver.com/icecds?Redirect=Log&logNo=40054056259
ARP (Address Resolution Protocol)
ARP(Address Resolution Protocol)
- IP네트워킹에서 IP주소를 대응하는 물리(MAC주소)로 변환하여 주는 프로세스
A (192.168.10.1) : B컴퓨터의 IP는 알고 있으나 MAC주소는 모름 B (192.168.10.2) : A컴퓨터의 ARP요청을 받고 응답을 보냄 |
- ARP를 이용하여 B의 MAC주소를 알아낼 수 있는데 원리는 전체 브로드캐스트를 날려 응답을 받음으로서
알아내는 방식이다.
- TCP/IP제조사들이 ARP캐시에 대하여 타이머를 지정하는 이유 : IP가 변경될 수 있기 때문
- 요청하는 컴퓨터의 경우 900초, 응답하는 컴퓨터의 경우의 타이머는 600초이다.
- ARP 패딩 : 이더넷 기반의 ARP요청과 응답은 종종 최소 46바이트의 사용자 데이터 크기조건을 만족시키지
못하는데, 이에따라 발생 할 수 있는 패킷의 손실을 방지하기 위해 바이트를 추가하여 데이터 길이를 늘림
ARP 하드웨어 유형(2Bytes)
- 네트워크의 물리계층에 사용된 하드웨어 종류
0000 FF FF FF FF FF FF 00 00 - C0 93 19 00 08 06 00 01
0010 08 00 06 04 00 01 00 00 - C0 93 17 00 C0 99 B9 64
0020 FF FF FF FF FF FF C0 99 - B9 32 00 00 55 00 00 DC
0030 00 6C 00 D6 00 00 00 A3 - 00 00 00 41
ARP 프로토콜 유형(2Bytes)
- 네트워크에서 사용된 네트워크 프로토콜 주소의 종류
0000 FF FF FF FF FF FF 00 00 - C0 93 19 00 08 06 00 01
0010 08 00 06 04 00 01 00 00 - C0 93 17 00 C0 99 B9 64
0020 FF FF FF FF FF FF C0 99 - B9 32 00 00 55 00 00 DC
0030 00 6C 00 D6 00 00 00 A3 - 00 00 00 41
ARP 하드웨어 길이(1Byte)
- 하드웨어 주소에 사용되는 바이트 수(MAC주소의 바이트 수)
0000 FF FF FF FF FF FF 00 00 - C0 93 19 00 08 06 00 01
0010 08 00 06 04 00 01 00 00 - C0 93 17 00 C0 99 B9 64
0020 FF FF FF FF FF FF C0 99 - B9 32 00 00 55 00 00 DC
0030 00 6C 00 D6 00 00 00 A3 - 00 00 00 41
ARP 프로토콜 길이(1Byte)
- ARP의 발신지와 목적지 두 곳의 프로토콜 주소의 길이를 표시
0000 FF FF FF FF FF FF 00 00 - C0 93 19 00 08 06 00 01
0010 08 00 06 04 00 01 00 00 - C0 93 17 00 C0 99 B9 64
0020 FF FF FF FF FF FF C0 99 - B9 32 00 00 55 00 00 DC
0030 00 6C 00 D6 00 00 00 A3 - 00 00 00 41
ARP 오퍼레이션(2Bytes)
- ARP가 현재 하고 있는 작업이 무엇인지 표시
- 16진수 00 01은 ARP요청(request), 00 02는 ARP응답(reply)를 의미
0000 FF FF FF FF FF FF 00 00 - C0 93 19 00 08 06 00 01
0010 08 00 06 04 00 01 00 00 - C0 93 17 00 C0 99 B9 64
0020 FF FF FF FF FF FF C0 99 - B9 32 00 00 55 00 00 DC
0030 00 6C 00 D6 00 00 00 A3 - 00 00 00 41
ARP 발신지 하드웨어 주소(6Bytes)
0000 FF FF FF FF FF FF 00 00 - C0 93 19 00 08 06 00 01
0010 08 00 06 04 00 01 00 00 - C0 93 17 00 C0 99 B9 64
0020 FF FF FF FF FF FF C0 99 - B9 32 00 00 55 00 00 DC
0030 00 6C 00 D6 00 00 00 A3 - 00 00 00 41
ARP 발신지 프로토콜 주소(6Bytes)
0000 FF FF FF FF FF FF 00 00 - C0 93 19 00 08 06 00 01
0010 08 00 06 04 00 01 00 00 - C0 93 17 00 C0 99 B9 64
0020 FF FF FF FF FF FF C0 99 - B9 32 00 00 55 00 00 DC
0030 00 6C 00 D6 00 00 00 A3 - 00 00 00 41
ARP 목적지 하드웨어 주소(6Bytes)
0000 FF FF FF FF FF FF 00 00 - C0 93 19 00 08 06 00 01
0010 08 00 06 04 00 01 00 00 - C0 93 17 00 C0 99 B9 64
0020 FF FF FF FF FF FF C0 99 - B9 32 00 00 55 00 00 DC
0030 00 6C 00 D6 00 00 00 A3 - 00 00 00 41
ARP 목적지 프로토콜 주소(6Bytes)
0000 FF FF FF FF FF FF 00 00 - C0 93 19 00 08 06 00 01
0010 08 00 06 04 00 01 00 00 - C0 93 17 00 C0 99 B9 64
0020 FF FF FF FF FF FF C0 99 - B9 32 00 00 55 00 00 DC
0030 00 6C 00 D6 00 00 00 A3 - 00 00 00 41
출 처 : http://blog.naver.com/demonicws?Redirect=Log&logNo=40106034319
[출처] ARP(Address Resolution Protocol)|작성자 Stein
Out of Order / InOrder (아톰)
흔히 넷북을 쓰는 사람들의 소감평 중 하나는 '넷북은 느리다' 입니다. 그것도 가끔 잘 나가다가 이해와 용서를 구하기 힘들정도로. ㄱ-; 오늘 순차실행 듀얼이슈작동방식을 탐구하다 원하는건 못건졌지만 엔하위키에서 우연히 이런 대목을 봤습니다. http://mirror.enha.kr/wiki/%EC%9D%B8%ED%85%94%20%EC%95%84%ED%86%B0%20%EC%8B%9C%EB%A6%AC%EC%A6%88 아톰이 일반 CPU에 비해 느린건 사실이지만 이론벤치마크성능에서 완전체 콘로 시리즈와 비교해도 동클럭 평균 절반의 성능을 보입니다. 더 느려질 때도 있지만 왠만해서 절반의 범위를 유지하는 벤치성능. 훨씬 더 구시대의 유물인 펜티엄2은 비순차실행방식이란 장점이 있지만 뒤떨어진 분기예측, 느린외장캐시, SSE 명령셋조차 없는 기본적인 구조로 왠만해서는 좋게봐줘야 동급클럭 아톰정도의 평가를 받고 있습니다. 어째서 아득하게 먼 클럭차이가 있음에도 이론성능과는 별도로 순차실행 프로세서는 이런 체감성능 저평가를 받게되는 것일까요? 우연히 떠오른 비교대상이 있다면 그것은 게임입니다. 아래와 같은 그림으로 그 예를 찾아볼 수 있습니다. 게임의 체감성능을 좌우하는 것은 프레임 유지율 입니다. 아무리 높은 평균프레임을 가져도 특정상황에서 무척 느린 최소프레임을 가지면 멈추거나 끊겨보인 것 처럼 느끼게되고 느리다고 평가하게 되지요. 순차실행(InOrder)도 마찬가지입니다. 비순차실행(OutofOrder)와는 다르게 매우 무겁고 느린명령어를 처리하게되면 파이프라인을 따라 뒤따라오던 모든 명령어도 멈추게됩니다. [A]와 비슷한 예로 64비트 정수나눗셈이 걸린다면 1~2클럭안에 처리할 수 있는 다른 [B,C,D] 같은 덧셈,뺄셈,로드,스토어,분기,시프트의 대부분의 명령어들이 수십, 많게는 수백클럭씩 지연되어집니다. 순차실행CPU가 비순차에 비해 2~3배 빠르다고 해도, 최악으로 꼬이는 경우에 100배 가까이 느려질 수도 있는게 순차실행구조입니다. 과학연산, 그리드컴퓨팅 용도에 보탠다던지 하는 PC끼리 짜고치는 활동이라면 몰라도 사람이 쓰기엔 무척 환경 정신건강에 악영향을 끼치게 만들 수도 있는게 이 순차구조인 셈이지요. ㄱ- 싱글코어니 듀얼코어니의 차원을 넘어 한 쓰레드에 얼마나 순간적으로 발목을 잡느냐를 말합니다. 성능 외에도 단일프로그램의 불규칙한 처리흐름을 고르게 해주는게 비순차의 역할인 것입니다. 결론은 '성능을 떠나서 인오더는 아웃오브오더의 상대가 될 수 없다' 입니다. 아톰과 비아나노를 비교대상으로 삼을 수도 있고, 곧 나올 밥캣을 대상으로 삼을 수도 있습니다. 심지어 휴대폰 임베디드에서 아웃오브오더를 택한 Cortex-A시리즈에게도 굴욕을 당할 소지가 잇습니다. 인텔이 차세대 넷북CPU에는 비순차실행구조를 도입할거라고 하니 그 때까지 지켜봐야겠습니다.
마지막문단을 보면 때때로 특정 어플리케이션에선 펜티엄2 300mhz보다 느린 경우도 발생한다는 부분,
머릿속에서 곰곰히 스케치하다가
리눅스 utf-8 캐랙터셋 변경
UTF-8 캐릭터셋으로 변경하기위한 방법은 여러가지 작업을 거쳐야하는 까다로운 작업이다. #!/bin/bash
새로운 사이트를 구축하는데는 별다른 어려움이 없지만
기존사이트를 이전하기 위해서는 알게 모르게 많은 수작업이
들어간다.
만일 HTML 파일내용을 EUC-KR에서 UTF-8로 변경해야 할
경우라면 다음과 같은 명령을 사용한다.
iconv -c -f euc-kr -t utf-8 a.html > a.html.utf8
iconv 명령은 여러개의 파일을 동시에 변환할 수 가 없다. 따라서
여러개의 파일 혹은 디렉토리상의 HTMl을 변경하고자 할때는
다음과 같이 크립트를 작성하여 변환을 해야 한다.
for DIR in `find . -type f `
do
echo "$DIR done............................"
iconv -c -f euc-kr -t utf-8 $DIR > aa
rm -f $DIR ; mv aa $DIR
done
iconv옵션중에 "-c"를 붙여주는 이유는 간혹 잘못입력된 한글 혹은
특수문자의 경우 UTF-8 변환이 되지 않는다. 이와같은 경우로
파일이 삭제되는 경우를 방지하기 위해 -c를 주면 변환할 수 없는
파일이 있더라도 강제로 변환하기 위함이다.
위처럼 파일의 내용을 변경했으면 meta 태그를 변경하는
과정이 필요하다. 아무리 실제 파일 내용이 UTF-8일지라도
이걸 표현하는 Explorer 나 Firefox에서는 태그가 제대로
표현되어 있지 않으면 UTF-8로 표현되지 못한다.
따라서 다음과 같은 명령으로 meta의 character-set을 변경해야
한다.
find . -name '*.html' -exec perl -pi -e 's/euc-kr/utf-8/g' {} \;
다음으로 간혹 개념없는 유저들이 올리는 한글이름으로 된
파일을 UTF-8파일명으로 변경해야 한다. iconv는 파일의
실제 내용을 utf-8로 변경했을뿐 파일명은 다른 문제라서
다음과 같은 명령으로 파일명을 변경해야 한다.
convmv -r -f euc-kr -t utf-8 --notest *
convmv의 경우 리눅스상의 기본 명령어가 아니므로 www.rpmfind.net 등에서 rpm을 검색하여 설치해야 한다.
주의사항 : UTF-8로 변경하는 작업은 생각만큼 쉬운 작업이
아니다. 지금 완전히 정착된 것도 아니고 해서 변환에 신중신중을
기해야 한다.
출처 : http://blog.naver.com/ssik425?Redirect=Log&logNo=10088230675
[출처] [UTF8] 리눅스 convmv를 이용한 UTF-8 캐릿터셋으로 변경|작성자 씩
find 명령어
사용형식 [찾을 디렉토리경로] [찾기옵션] [찾은후행할 작업] option [찾을 디렉토리경로] . : 현재 디렉토리 이하를 검색대상으로 한다. / : 루트디렉토리(파일시스템전체) 이하를 대상으로 한다. ~ID : 지정된 ID의 홈디렉토리이하를 대상으로한다. [찾기옵션] -empty : 비어있는 파일을 찾는다. -uid UID : 지정된 UID를 갖는 파일을 찾는다. -gid GID : 지정된 GID를 갖는 파일을 찾는다. -group 그룹명 : 지정된 group을 갖는 파일을 찾는다. -name : 지정된 형식의 패턴을 가지는 파일을 찾는다. -newer : 지정된 파일 이후에 생성된 파일을 찾는다. -perm : 지정된 퍼미션을 가진 파일을 찾는다. -used 일자수 : 최근 n일 이후에 변경된 파일을 찾는다. -user : 지정된 파일을 소유하고 있는 소유자의 모든 파일을 찾는다. [찾은후 수행할 작업] -print : 찾은 내용을 보여준다. -exec "수행명령어" : 검색된 파일을 대상으로 :수행명령어"를 실행한다. [예제] 특정 사용자의 ID 소유로된 모든 파일 찾기. [os] find / -user khi083 -print 현재 디렉토리 이하부터 test 파일명을 찾아 보여준다. [os] find . -name test -print khi083 사용자의 홈디렉토리에서 test 파일명을 찾아 보여준다. [os] find ~khi083 -name test -print 특정 파일을 찾은 후 자동 삭제방법. [os] find ~khi083 -name test -exec rm -f {} \; 지정한 소유자의 모든 파일을 찾아서 확인하기. [os] find / -user khi083 -exec ls -l {} \; 특정용량 이상되는 파일들 모두찾기. [os] find /usr/ -size +10000k -exec ls -l {} \; -- 약 10MB이상 특정 퍼미션을 가지고 있는 파일들을 모두 찾기 [os] find / -perm 4755 -exec ls -l {} \; 존재하는 모든 링크파일 찾기 [os] find / -type l -exec ls -l {} \; 디렉토리 이하에서 "doc" 라는 문자를 포함하고 있는 파일을 찾아서 파일의 위치와 파일명, 포함된 행을 출력한다. [os] find /etc type f -exec egrep -i "doc" /dev/null {} \; -------------------------------------- 보안 관련된 find -------------------------------------- 지정된 일자 이후에 변경된 모든 파일 찾기(서버점검시에 서버해킹으로 인하여 변경된 파일을 찾을 경우) [os] find / -used 2 -exec ls -l {} \; -- used 뒤에 나오는 숫자는 "일" 즉, 24시간 단위. 지정된 파일보다 이후에 생성된 파일 찾기(해킹된 파일이나 백도어 파일을 찾은 후에 그 파일과 함께 시스템에 생성된 파일찾기) [os] find / -newer /root/file1.txt -exec ls -l {}; -- used 뒤에 나오는 숫자는 "일" 즉, 24시간 단위. root소유의 SetUID 파일 찾기 [os] find / -user root -perm -4000 -print 서버내부에서 .bash_history 파일을 모두 찾아서 확인하기(root소유의 .bash_history파일이 용량이 0이라면 이는 매우 심각한 경우로서 거의 99%이상은 해킹되었다고 보셔도 무방하다.) [os] find / -name .bash_history -exec ls -l {} \; 소유자가 없는 파일 또는 소유그룹이 없는 무적파일 찾기 [os] find / -nouser -o -nogroup -print -- -o옵션은 "OR"를 의미한다 출 처 : http://blog.naver.com/nixblade?Redirect=Log&logNo=10092313804
sizeof 연산자
sizeof 요넘이 자료형의 크기를 얻기위해 쓰이죠. sizeof(int); 하면 int형이 몇바이트인지도 알 수 있고. int i; sizeof(i); 하면 변수 i가 몇바이트인지 알 수 있죠. char arr[24]; sizeof(arr); 배열의 크기도 구할 수 있습니다. --------------------------------------------------------- 이러한 크기들은 어떻게 구하는 걸까요? CPU가 계산해서 크기를 구하는게 아닌 컴파일러가 컴파일할때 크기를 인식해서 상수로 바꿉니다. char arr[24]; printf("%d", sizeof(arr) ); 여기서 sizeof(i)를 처리할 때... 컴파일러는 위의 배열을 선언한 부분을 참조합니다. 그리고 arr은 24바이트구나~~ 하면서 printf("%d", sizeof(arr) ); -> printf("%d", 24); 이렇게 바꿉니다. ---------------------------------------------------------- sizeof 는 컴파일러가 처리한다는 것을 알았으니 1개를 알려주면 10개를 안다는 분들은 감이 오실겁니다. CPU가 32비트든, 64비트든, 운영체제가 32비트든 64비트든 간에 컴파일러가 32비트 컴파일러면 sizeof(int)는 모두 4로 처리된다는 겁니다. 32비트 CPU쓰고 32비트 운영체제를 쓴다 할지라도 16비트 컴파일러를 사용하면 sizeof(int)는 2가 됩니다. ------------------------------------------------------------- sizeof가 컴파일 될때 처리된다는 것을 알았으니 여기서 또 한가지를 알 수 있지요. c언어로 표현하면 int *p; p = malloc(16); printf("%d", sizeof(p) ); 일때, sizeof(p)는 어떻게 될까요? 정답은 16이 아닌 4 입니다.(32비트 컴파일러 기준) p가 선언된 부분 int *p; 를 보고. 포인터는 4바이트니까 sizeof(p) -> 4 이렇게 한겁니다. --------------------------------------------------------------------------- malloc(16)을 보면 16이라는 것을 알수 있는데, 컴파일러는 왜 4라고 처리하는가? char arr[24]; printf("%d", sizeof(arr) ); 배열 일때는 할당된 크기를 sizeof 값으로 처리했으면서. malloc은 c언어 문법장치가 아닌, c언어 함수 입니다. 무슨말인가 하면, p = malloc(16);을 컴파일러 입장에서 보면. "malloc 함수에 인자로 16을 주고, 리턴값을 p에 넣는다." 일 뿐이지 컴파일러에게 그 이상의 의미는 없습니다. 반면에 sizeof()는 함수가 아닌, c언어 문법장치 입니다. 그러므로 sizeof(p)가 "sizeof 함수에 p를 인자로 넣는다"가 아닌, "p의 바이트크기 상수값"을 의미하게 되는거지요. 배열일 때는, c언어 문법장치인 char arr[24]; 을 고려해서 sizof값을 정하는 것이고 포인터일 때는 c언어 문법장치인 int *p; 를 고려해서 sizof 값을 정하는 것입니다. --------------------------------------------------- malloc 함수, 즉. 동적할당된 크기를 sizeof에 반영하지 않는 또다른 이유를 알아봅시다. int *p; int i; scanf("%d", &i) p = malloc(i); printf("%d", sizeof(p) ); 코드가 이러할때 sizeof(p)는 어떤 값을 가져야 할까요? 전에 말했듯이 sizeof는 c언어 문법장치이며, 함수도 아닙니다. 즉, 컴파일 될때 그 값이 결정되서 상수값으로 치환되어 컴파일 됩니다. 만약, malloc 으로 동적할당한 값을 sizeof 값으로 하려 한다면 컴파일 할때는 i의 값을 알수 없으므로 sizeof를 처리하는게 불가능 합니다. 이러한 이유도 있습니다. 출 처 : http://cafe.naver.com/haebop.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=5173