2015년 5월 24일 일요일
네트워크 소켓 프로그래밍 시 INADDR_ANY의 의미
INADDR_ANY는 #define를 통해 0으로 설정되어 있습니다.
INADDR_ANY는 자동으로 이 컴퓨터에 존재하는 랜카드 중 사용가능한 랜카드의 IP주소를 사용하라는 의미입니다.
"어? 그러면 그냥 내가 가지고 있는 IP주소를 입력해도 되지 않나요?"
라고 생각하실 탠데 약간 더 중요한 의미가 하나 더 있습니다.
예를들어 내 컴퓨터는 총 2개의 랜카드가 설치되어 있고 각각의 ip주소가 아래와 같다고 가정합시다.
랜카드1 : 192.168.0.100
랜카드2 : 192.168.0.200
내 컴퓨터는 총 2개의 ip주소를 가지고 있으므로 외부에서 192.168.0.100으로 데이터를 보내건, 192.168.0.200으로 데이터를 보내건 내 컴퓨터로 오는건 똑같습니다.
하지만 프로그램은 약간 다릅니다. 내가 만든 프로그램에 ip주소를 192.168.0.100으로 등록해 뒀다면 192.168.0.200으로 들어오는 데이터는 받지 않습니다.
즉, 어차피 같은 컴퓨터임에도 불구하고 ip주소가 다르면 처리를 못한다는 의미입니다.
이때, INADDR_ANY를 사용하면 192.168.0.100으로 들어오건, 192.168.0.200으로 들어오건 모두 똑같이 처리할 수 있습니다.
만약, 내가 만드는 프로그램은 무조건 192.168.0.100으로 들어온 접속만 처리해야된다 하시면 INADDR_ANY를 사용하시면 안되고 192.168.0.100으로 명시적으로 설정해 주셔야 합니다.
vistual studio에서 컴파일 시 에러 (COFF로 변환하는 동안 오류가 발생했습니다.)
요놈인데요. 이걸 실행시키시면 왼만하면 다시 정상적으로 한글이 나옵니다. [Grind Away] vistual studio에서 컴파일 시 에러 (COFF로 변환하는 동 안 오류가…
C / C++ · 2015/05/24
LINK : fatal error LNK1123: COFF로 변환하는 동안 오류가 발생했습니다. 파일이 잘못되었거나 손상되었습니다.
또는 fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt 위와 같은 에러가 발생하는 경우 아래 2가지 방법으로 해결하실 수 있습니다.
첫번째 방법은 release 모드로 컴파일 한다.
두번째 방법은 해당 프로젝트를 우클릭해서 속성 -> 구성속성 -> 링커 -> 매니페스트 파일 -> 매니페스트 생성 (예)를 (아니오)로 바꾸세요.
#C언어 #Cpp #시스템프로그래밍 #개발자 #파일입출력
C++ 멀티 채팅 프로그램 (Multi Chatting Program)
chatting.zip(다운로드)
[Grind Away] (windows) C++ 멀티 채팅 프로그램 (Multi Chatting Program)
Network · 2015/05/24
작업하다 필요해 짧게 정리해 둔다.
윈도우즈에서 동작하는 멀티 채팅 프로그램입니다. 혹시 네트워크 프로그래밍을 공부하시는 분이나 채팅 소스가 필요하 신 분은 가져다 쓰시기 바랍니다.
학습용이라 다소 매끄럽지 못하고 문제가 발생할 수 있으니 사용처에 따라 정확하게 이해하고 사용하시기 바랍니다.
첨부된 파일 안에 server, client 모두 들어 있습니다.
visual studio 에서 작성 했으며 만약, 컴파일 시 에러가 발생하신다면 release 모드로 컴파일 하시기 바랍니다.
같은 상황에 부딪힌 분에게 도움이 되길.
#네트워크 #TCP #프로토콜 #소켓
[Grind Away] 시스템 용량 확인에 유용한 프로그램 소개 (SpaceSniffer)
팁 · 2015/05/24
제가 쓰는 노트북은 SSD 120GB가 장착되어 있습니다. 속도는 빠른데 금방 용량이 가득 차 버려서 쓸대 없는 것을 지워주 어야 하는 번거로움이 있습니다.
이럴 때 불필요하며 많은 용량을 차지하는 파일이나 폴더를 찾는게 상당히 어렵죠 이걸 쉽게 해주는 프로그램이 있습니 다.
SpaceSniffer라는 툴인데요. 사용법도 원클릭이면 가능하고, 상당히 보기 쉽게 처리해 줍니다.
위 사진은 제 노트북 C드라이브를 스캔한 사진인데요. 그림처럼 용량별 지도를 그려줍니다. 당연, 용량이 크면 면적이 더 넓게 그려주고 있어요. 폴더 같은 경우에는 해당 면적을 클릭하면 더 상세하게 해당 폴더 안의 파일들을 보여줍니다.
아래 사이트를 통해서 이 툴은 현재 무료로 다운받으실 수 있습니다.
Uderzo Software www.uderzo.it
#개발팁 #프로그래밍 #꿀팁 #개발자
지식재산능력시험(IPAT) 응시
npm, node.js, express 버전 확인 방법
[Grind Away] npm, node.js, express 버전 확인 방법
Node.JS · 2015/05/24
최근 node.js가 떠오르면서 업데이트도 많아지고 확확 바뀌더군요. 뭐좀 할라고 하면 새로운게 나오고 좋은점도 있고 불 편한 점도 있지만 기술이 바뀌는데 어쩔 수 없죠.
아는 선배가 똑같은 express를 생성 했는데 특정 코드가 어디선 되고 어디선 안되고 이런 문제들이 발생해서 찾아보니 express 버전이 서로 다르더라구요.
그래서 혹시 개발할 때는 잘 됬는데 서버에 올렸을 때 잘 안되시거나 개발환경을 바꿨을 때 제대로 동작을 안하시면 꼭 버 전부터 확인해 보세요.
node -v npm -v express -V (요곤 V가 대문자입니다.)
#NodeJS #자바스크립트 #백엔드 #개발자
2015년 5월 23일 토요일
[Grind Away] Network 입문자를 위한 책 추천
Network · 2015/05/23
저는 다양한 IT분야를 공부하면서 특히 네트워크쪽에 관심을 많이 가지고 있습니다. 아무래도 컴퓨터라던지 스마트폰이라
던지 인터넷 없이는 전부 무용지물일 만큼 네트워크가 중요하며, 실질적으로 IT라는 것은 네트워크에 기반한 기술이라고 할 만큼 네트워크 없이는 아무것도 없기 때문입니다.
하지만 현실은 주변에 IT를 공부하는 학생들만 봐도 네트워크에 관심을 갖는 사람이 별로 없더라구요... 네트워크를 공부 할 기회를 접할만한 동기도 별로 없고 왜 네트워크가 중요한지 말해주는 사람도 별로 없기 때문에 사람들이 처음 공부하는 사람들이 많이 소홀히 하지 않나 싶습니다.
또, 네트워크를 공부하고 싶은데 어떻게 시작해야되고 공부해야 되는지 몰라서 못하는 분들도 계실거예요. 그래서 이번 글 에서 네트워크 배워보고 싶은 분들을 위해 책을 추천해 드릴게요.
후니의 쉽게 쓴 시스코 네트워킹 진강훈저 아마 가장 많은 사람들이 네트워크 입문으로 선택하는 책이 아닌가 싶습니다. 이 책은 제목부터 알 수 있듯이 CISCO사의 기술과 교육커리큘럼에 기반하여 네트워크 기초 지식을 알기 쉽게 설명하고 있는 책입니다. 읽어 보시면 책을 읽는다기 보 다는 저자와 대화한다는 느낌을 받을 만큼 책을 이야기 하듯 썼다는걸 알 수 있습니다. 그렇다 보니 처음에 접할 때 네트워 크라는 것을 더 쉽고 재미있게 받아들일 수 있지 않나 싶네요. 내용도 있을 껀 다 있고 뒷부분에 가면 장비를 다루는 부분 까지도 있기 때문에 처음 접할 때 자연스럽게 네트워크에 빠져들 수 있을만한 책이라고 생각이 듭니다.
Big Network Design 이중호 저 이 책은 제가 상당히 좋아하는 책입니다. 후니책과 비슷하게 상당히 쉽게 설명해주고 있으며 나름 깊이도 있어요. 또 책 자 체가 네트워크 디자인을 주제로 다루다 보니 단순히 네트워크 기술에 대한 설명 뿐만 아니라 네트워크를 구축하고, 관리하 고, 설계하는 부분 위주로 잘 설명이 되있습니다. 기술에 대한 설명도 상세한 부분까지 설명해 주고 있어서 네트워크 중급 자 정도 된다면 이 책을 꼭 보시길 추천드립니다. 저같은 경우에는 이 책에 빼곡히 필기가 되어있을 정도로 열심히 본 책이 기도 합니다.
열혈 TCP/IP 소켓 프로그래밍 윤성우 저 이 책은 네트워크 이론이나 네트워크 기술에 대한 설명을 하는 책은 아니구요. 제목 그대로 네트워크 프로그래밍과 관련된 책입니다. 개발자는 꼭 보셔야 할 책이라고 생각합니다. 리눅스와 윈도우즈에서 네트워크 소켓을 이용한 프로그래밍과 관 련된 내용이 이해하기 쉽게 설명되어 있을 뿐더러 저자의 동영상 강의가 첨부되어 있어 더 쉽게 이해하고 따라할 수 있습 니다. 네트워크 프로그래밍에 도전하시려면 꼭 이책으로 시작하시는걸 추천드립니다.
TCP/IP 완벽 가이드 CHARLES M.KOZIEROK 저 이 책은 딱 봐도 두꺼워 보이지 않나요 실제로 엄청 두껍습니다. 왼만한 사전 저리가라인데요. 이 책은 다양한 네트워크 기술과 프로토콜을 상세하게 설명하고 있는 책입니다. 레퍼런스 형태로 사용하시는걸 추천드립니다. 왼만한 TCP/IP 대표 기술들은 전부 있기 때문에 네트워크 프로그래밍을 하거나 프로토콜과 관련해서 깊이있는 연구를 하신다면 이 책을 참고 하시길 바랍니다. 맨 처음부터 정독하셔도 좋지만 방대한 양과 상세한 기술설명 때문에 상당히 어렵습니다. 저는 특정 기 술에 대해 상세하게 알고 싶다면 이 책을 펴서 보곤 합니다.
#네트워크 #TCP #프로토콜 #소켓
2015년 5월 22일 금요일
[Grind Away] 윈도우 vista, 7, server 2008 계정 암호 복구법!
Windows · 2015/05/22
이번에 다루게될 주제는 윈도우7에서 계정의 암호를 복구하는 방법에 대해 다뤄보겠습니다.
자 윈도우7 사용하고 계신 유저분들중 어느날 갑자기 컴퓨터를 부팅해서 로그온을 하려고 했는데 아차~! 계정의 암호가 기억이 안나시는 분들 꼭 계실겁니다.
단순히 잊어버리신 경우, 부모님이 컴퓨터 사용시간을 제한하기 위해 설정한 암호(ㅎㅎ;)등등 계정의 암호를 다시 되찾아야 할때 즉, 암호를 다시 변경하거나 복구하고 싶을때가 있으실겁니다.
그런경우 이번 글을 참고하여 암호를 복구하는법을 숙지하고 계신다면 앞으로 그런문제가 발생할 경우에 당황하지 않고 암호를 복구하실 수 있습니다.
그러면 서두는 여기서 끝내고 본론으로 들어가서 한번 복구 방법에 대해 스샷과 함께 하나하나 알아보도록 하겠습니다.
※ 예제에 사용된 스크린샷은 필자가 직접 찍은 사진입니다. 필요하시면 얼마든지 퍼가셔도 좋습니다.
준비물 : 윈도우7 포맷CD(설치CD)또는 PE부팅용 CD 대상 컴퓨터 운영체제 : 윈도우7 (동일계열모두가능) 자, 시작하기에 앞서 준비물이 있습니다. 포맷CD 즉, 윈도우7 포맷(설치)할때 쓰는 CD가 필요합니다.
윈도우 상에 파일을 일부 변경해 주는 작업이 필요하므로 윈도우7포맷(설치)cd나 PE로 부팅하여 파일을 조금 변경해줄겁니다. 만약 없으시다면 아래 예제에서 관련설정시 하드디스크를 아예 통째로 뜯어서 다른 PC로 연결하여 동일하게 작업해 주셔도 상관은없습니다(좀 귀찮을뿐이죠..) 그럼 시작하도록 하겠습니다.
★ 아래와 같이 로그인 상태에서 암호를 만약 잊어버렸다면 일반적으로는 인터넷을 검색해서 안전모드로 들어가면 된다는 둥 어쩔수없다 포맷을 해야된다는둥 말이 많습니다.
만약 이런 복구방법을 모른다면 저는 아마 포맷을 하지 않았을까 싶네요 ㅎㅎ;; 이 사진에서 주목해 주실 부분이 있습니다. 사진 하단부의 왼쪽 끝에 보시면 평생살면서 한번 눌러볼까 말까할 버튼이 하 나 있습니다. 찾으셨나요?
쓸쓸하게 혼자 있는 버튼이 하나 있습니다. 평소 전혀 신경쓰지 못하고 지나친 저 버튼이 이번 암호복구의 핵심 포인트가 되는 역할을 할것입니다.
이번기회에 한번 눌러봅시다!
암호 복구와는 전혀 관련이 없는 기능들만 들어있는걸 확인하셨을겁니다.
이 버튼으로 어떻게 암호를 복구한다는 것일까요?
사실 이 버튼의 기능은 전혀 중요하지 않습니다. 왜냐면 여기있는 기능들로는 암호를 복구할 수 없기때문입니다. 그러면 이 버튼을 우리가 암호를 복구할 수 있도록 바꿔주어야 합니다.
어떻게 바꿀수 있을까요?
실제 저 버튼은 일종의 바로가기와 같은 역할을 합니다. 즉, 저 버튼을 누르면 실제 컴퓨터 상의 C:\Windows\System32\Utilman.exe 이라는 프로그램이 실행되도록 만들어져 있습니다.
즉, system32 폴더 안에 있는 Utilman.exe 라는 이름을 가진 녀석이 실행되는것이지요.
현재 우리 컴퓨터상에는 기본적으로 System32 폴더안에 Utilman.exe 라는 프로그램이 들어있고 해당 프로그램을 정상적인 컴퓨터에서 찾아들어가서 실행하면 아까 눌렀던것과 같은 창이 똑같이 뜰겁니다.
여기서 가장 중요한 핵심포인트를 알려드리겠습니다.
저 버튼을 실행할때는 마치 관리자가 실행하는것과 같은 권한으로 실행되게 됩니다. 전문적으로 말하면 윈도우의 SID 중 맨 끝 숫자코드가 500번인 권한으로 실행이 된다는 말이지요.
아 이해가 안간다~! 그러면 모르셔도 됩니다. 그냥 저 버튼을 내가 클릭하면 System32 라는 폴더 안에있는 Utilman.exe 라는 프로그램이 실행되게 되는대 그 실행을 관리자 권한으로 실행이 되게된다!
이것만 알고계시면됩니다. 마치 윈도우상에서 어떤 프로그램을 실행할때 오른쪽 클릭하고 '관리자 권한으로 실행' 버튼을 누른것과 마찬가지란 말이죠.
※그냥 실행시키는것과 관리자권한으로 실행시키는것은 사실 조금 다릅니다.
윈도우상의 모든 파일이나 폴더에는 접근 권한이라는것이 존재하게 됩니다.
일반적으로 우리가 주로 쓰는 파일들은 모두 일반사용자에게 접근권한이 주어지지만
시스템에 중요한 파일이나 폴더에는 일반 사용자가 접근시 접근을 거부하게 됩니다.
하지만 관리자 권한으로 실행시 그보다 더 권한이 많은(실질적으로 모든권한을 가진) 관리자의 권한으로 동작하게 함으로써 좀더 민감한 파일까지 건드릴 수 있게됩니다.
여기서 우리가 하고자 하는것은 계정생성,암호변경,계정삭제 등등 특수권한이 필요한 동작이므로 관리자 권한을 필요로 하게됩니다.
말이 길어졌습니다.
그러면 이제 어느정도 눈치를 채셨을겁니다. 저 버튼을 누르면 운영체제는 자동으로 C:\Windows\System32\에 위치한 Utilman.exe 라는 프로그램을 동작시키게 됩니다.
그러면 우리가 할 일은 저 위치에 있는 Utilman.exe라는 프로그램을 잠깐 옆으로 치우고 계정에 대한 설정을 건드릴 수 있는 프로그램을 이름만 살짝 Utilman.exe 라고 바꿔주고 저 위치에 놓아주면 다시 저 버튼을 누를시 우리가 원하는 프로그램이 동작하게 됩니다.
어떻게 하냐구요 아무리 발버둥을 쳐봐도 현재 창에서는 도저히 해당 폴더에 접근을 할 수가 없습니다.
그래서 미리말씀드린 준비물! 윈도우7포맷CD 혹은 PE부팅용CD를 이용하여 하드디스크가아닌 포맷화면(PE)에서 간단한 명령어를 통해 해당 파일을 수정해 보도록 하겠습니다.
먼저 컴퓨터에 윈도우설치용CD를 넣습니다(PE부팅용CD도 가능합니다) 그리고 컴퓨터를 재부팅하여 CD로 부팅해 주도록합니다.
아래와 같은 화면이 나타나시면 됩니다 .(PE를사용하시는분은 그냥PE로 부팅하시면됩니다.) 어렵게 생각하시는대 윈도우7 설치용 CD만 준비되어 있다면 그냥 포맷하듯이 CD를 넣고 CD로 부팅만 해주시면됩니다.
※ CD를 넣으시고 아무키나 누르시오... 라는 메시지가 영어로 나타나면 아무키나 누르시면 CD로 부팅이 됩니다. 만약 나타나지 않는다면 해당 메인보드의 BIOS설정에 들어가셔서 부팅순서를 변경해 주셔야합니다. 자세한 변경방법은 이번장에서는 생략하도록 하겠습니다.
위 화면까지 오셨다면 이제 Shift키와 F10버튼을 동시에 눌러줍니다.
그러면 까만 창이 하나 뜨게됩니다.(PE로 부팅하시는 분들은 cmd창을 켜주시면됩니다) 여기서 부터 직접 명령어를 입력해야 하기 때문에 어렵게 느껴지실 수 있으나 막상 알고보면 전혀 어렵지 않습니다. 처음이시라면 마치 내가 천재해커가 된것처럼 느끼시게 될 것입니다.
이 까만 창에 명령어를 내리면(현제는 CD로부팅하였기 때문에 CD안에 들어있는 시스템을 이용하여 동작하게 됩니다.) 우리가 명령하는대로 처리해줄것입니다. 현재 우리가 하고자 하는것은 실제 컴퓨터의 하드디스크에있는 C:\Windows\System32 경로안의 Utilman.exe 라는 파일을 계정정보를 변경할 수 있는 파일로 바꿔주는 작업을 해 주어야 합니다.
그렇기때문에 기존에 들어있는 Utilman.exe 라는 파일은 잠시 치워두고 계정정보를 변경할 수 있는 cmd.exe라는 프로그램으로 덮어씌어 줄겁니다.
여기서 중요한점이 하나 있습니다.
우리 컴퓨터에서는 C드라이브지만 지금은 우리가 컴퓨터로 부팅한것이 아닙니다.
CD안에 있는 임시운영체제(PE)로 부팅된 상태이기 때문에 여기서 아무리 C드라이브를 찾아봤자 C드라이브는 없을겁니다.(물론 있을수도 있지만 실제 우리가 찾는 경로와 다를 수 있습니다) 그렇기 때문에 우리가 찾는 하드디스크상의 C드라이브를 약간의 노가다(?)로 찾는 작업을 먼저 해 주어야 합니다.
찾는 방법은 이렇습니다.
무식하게 C부터해서 Z까지 다 쳐보는 겁니다.
우리는 현재 실제 컴퓨터의 하드디스크 상에있는 C드라이브를 찾아야 하기때문에 하나씩 쳐보면서 이게 긴가아닌가를 확인해봐야합니다.
이때 쓸 명령어가 dir 이라는 명령어입니다.
dir 명령어는 해당 위치에 존재하는 파일이나 폴더들의 목록을 보여줍니다.
만약 해당 드라이브에 아무것도 존재하지 않는다면 아무정보도 나타나지 않을것입니다.
우리가 찾고자 하는것은 운영체제가 설치된 C드라이브!
그러면 C드라이브는 어떻게 나타날까요?
일단 아까 위에서 우리가 들어가고자 하는 경로명을 다시보면 C:\Windows\System32 이렇게 되있습니다. 즉, C드라이브 안에 Windows라는 폴더가 존재하고 있습니다.
그렇다는건 여기서 돌아다니다가 dir명령어를 입력했을때 Windows 라는 폴더가 존재한다면 해당 드라이브가 실제 컴퓨터의 C드라이브 즉, 실제 시스템이 저장된 드라이브라고 생각하시면됩니다.
자 말이 너무 어렵다구요 그러면 그냥 아래와 같이 따라 해 주시면 됩니다.
C
dir
D
dir
E
dir
F
dir
G
dir 이런식으로 알파뱃 하나씩 넘겨가면서 다 찍어보는겁니다.(보통 C나D에서 나옵니다-0-;;) 이렇게 하시다가 dir명령어를 입력했을때 Windows 폴더가 보인다! 그러면 해당 드라이브 위치가 실제 시스템이 저장된 드라이브가 됩니다. 아래 스크린샷을 참고해주세요.
파란 네모가 쳐진부분이 제가 입력한 명령어이고 빨간 네모가 쳐진 부분이 우리가 찾고자하는 Windows폴더입니다. 저는 C드라이브에서 입력했을때 C드라이브 안에는 아무런 정보도 없었습니다.
그러면 C드라이브는 아닌게 된거고 그다음인 D드라이브로 이동했습니다.(D:) 그리고 dir을 입력하니 우리가 찾고싶어하는 Windows폴더가 보였습니다.
※ Windows폴더말고도 다른 폴더나 파일들이 존재하실 수도 있습니다. 신경쓰실 필요없이 Windows폴더가 존재하면 됩니다.
그러면 우리가 맨 위에서 찾고자하는 경로인 C:\Windows\System32 이 경로가 지금 CD로 부팅한 후에 D:\Windows\System32 이렇게 변경됬다고 생각하시면됩니다.
부팅하는 주체가 달라졌기때문에 이렇게 경로가 변한겁니다.
보통 C,D,E,F 선에서 다들 찾으실 수 있으실겁니다.
이제는 파일을 변경하는것만 남았습니다.
아래와같이 명령어를 입력해 주시면 기존에 존재하는 Utilman.exe 파일은 잠시 치워두고 cmd.exe 라는 파일이 Utilman.exe 라는 파일로 잠시 둔갑하게 됩니다.
cd Windows\System32 copy Utilman.exe Utilman.exe.1 del Utilman.exe copy cmd.exe Utilman.exe 위와같이 4줄의 명령어를 똑같이 입력해 주시기 바랍니다. 띄어쓰기 주의해 주시고요.
아래 스크린샷 참고해주세요.
위 스크린샷과 같이 진행되셨다면 정상적으로 성공하신겁니다.
만약 다른 에러가 발생하거나 실패한다면 분명 명령어를 잘못 입력하셨거나 드라이브 위치를 잘못 찾으신겁니다. 다시확인해보시고 진행하시기 바랍니다.
여기까지 다 하셨다면 이제 이 까만 창을 끄시고 윈도우 설치화면도 종료해 주시면 자동으로 컴퓨터가 재부팅됩니다.(CD는 빼셔도 좋습니다) 그리고 다시 컴퓨터가 부팅되면서 아까와 같은 로그인창이 다시 뜰것입니다.
이제 다시 좌측 하단의 버튼을 클릭하시면 이젠 좀 다른창이 뜰겁니다.
아까 본 그 까만창! 예 맞습니다. 명령어를 통해서 계정정보를 수정할 수 있습니다.
그렇기 때문에 이 명령프롬프트를 기존에 Utilman.exe로 대체하여 옮겨둔 것입니다.
여기서 또한번 명령어를 입력해 주셔야됩니다.
net user [암호를변경하고자하는계정이름] [바꾸고자하는암호] 위와같이 입력해 주시면됩니다.
만약 새로운 계정을 만들고 싶으시다면 아래와 같이 net user [새로운계정이름] [새로운계정암호] /add 이렇게 명령어를 입력해 주시면됩니다.
제가 쓰고있는 계정이름은 administrator 입니다. 아래 스크린샷을 참고해주세요
저는 net user administrator 123123 이렇게 입력했습니다.
administrator 계정의 암호를 123123으로 재설정한것과 같습니다.
그러면 이제 까만창을 닫고 새로 설정한 암호로 로그인을 시도해 봅시다.
위와같이 정상적으로 로그인이 되신걸 확인하실 수 있습니다.
이로써 이번 윈도우 계정복구 집필을 마치도록 하겠습니다.
#윈도우 #Windows #WinAPI #개발자
2015년 5월 21일 목요일
Ubuntu 64bit에서 32bit 프로그램 실행시키기
뭔가... 하고 한참 고민해본 끝에 'file' 명령어를 통해 확인해 봤더니..
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0x42279cc1c0032fe6ca98b0823767b310be3e3a8c, not stripped
바로 눈에 띄는것이 32-bit!!
설치한 Ubuntu는 64bit였습니다. 64bit에서 32bit를 돌리려 하니 서로 호환이 되지 않았던 모양입니다.
이럴 때는 아래와 같이 i386를 먼저 등록해 주세요.
sudo dpkg --add-architecture i386
확인은 아래 명령어를 통해서...
dpkg --print-architectures
dpkg --print-foreign-architectures
i386이 등록된 것을 확인하시고, 아래 명령어를 통해 32bit library를 설치해 줍니다.
sudo apt-get update
sudo apt-get -y install ia32-libs
Ubuntu Qt 설치
Qt Library
sudo apt-get install libqt4-dbg
sudo apt-get install libqt4-dev
sudo apt-get install libqt4-gui
sudo apt-get install libqt4-core
Qt Designer
sudo apt-get install qt4-designer
sudo apt-get install qt4-dev-tools
Qt Creator
sudo apt-get install qtcreator
32bit용 설치
XXX:i386
ex) apt-get install libqt4-gui:i386
QT 프로그래밍
QT는 C++기반이며 UI 어플리케이션 개발에 필요한 다양한 API를 다양한 플랫폼에서 지원한다고 하네요. 개발할 때 플랫폼에 상관없이 소스코드를 한번만 짜두면 수많은 데스크톱이나 임베디드 운영체제에 적용되어 동일한 프로그램으로 동작이 되는 강력한 장점을 가지고 있습니다.
QT는 GUI뿐만 아니라 네트워크, 그래픽, DB, OpenGL 등등 다양한 분야에 적용할 수 있는 방대한 API를 지원하며 쉽게 사용할 수 있도록 라이브러리로 제공됩니다.
기회가 되시면 한번쯤 공부해 보는것도 많은 도움이 될 것으로 생각이 들어요. 저도 지금 처음 책을 사서 공부하고 있는데 QT만의 독특한 구조덕에 애먹고 있긴 하지만 하면 할수록 재미있네요.
free시킨 포인터 변수에는 NULL로 초기화 해주자! 댕글링 포인터(Dangling Pointer)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#include <stdio.h>
#include <stdlib.h>
int main(void){
int *p = (int*)malloc(sizeof(int));
*p = 10;
printf("%d\n", *p); // 10
free(p);
*p = 20;
return 0;
}
| cs |
이상한 점이 보이는가?
free(p)를 통해 동적할당된 메모리 공간을 해제시키고 나서 *p = 20; 과 같이
없어진 공간을 또 사용하고 있다.
이와 같이 free시켜 해제된 메모리 공간을 가리키고 있는 포인터 변수를 보고
댕글링 포인터(Dangling Pointer) 라고 한다.
위와 같이 사용한다면 당장 눈에 보이는 에러가 발생하지는 않지만 프로그램이 동작하는 도중 free한 위치에 새로 동적할당이 이루어져 중요한 정보가 저장되어 버린다면 심각한 문제가 발생할 수 있다.
그렇기 때문에 위와 같은 문제를 해결하기 위해 습관적으로 free이후 해당 포인터 변수에 NULL값을 넣어주는 것이 좋다.
만약 귀찮다면 아래와 같이 매크로 함수를 작성하여 사용하는 것도 좋은 방법이다.
1
2
3
4
5
|
#define FREE(x) do { free(x); x=NULL; } while(0)
...
FREE(p);
...
| cs |
위와 같이 free후 NULL 값을 넣어주는 매크로 함수 FREE를 작성하여 사용하면 더 편리하게 댕글링 포인터를 예방할 수 있다.
(만약 위 매크로 함수에 do while문을 사용하는 이유가 궁금 하면 아래 게시글을 확인하라)
http://grindawayat.blogspot.kr/2015/05/do-while.html
여러 명령이 포함된 매크로 함수는 do while을 사용하자!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include <stdio.h>
#define SWAP(x, y, t) { \
(t) = (x); \
(x) = (y); \
(y) = (t); }
int main(void){
int a=10;
int b=20;
int tmp;
printf("a : %d\n", a); // 10
printf("b : %d\n", b); // 20
SWAP(a, b, tmp);
printf("a : %d\n", a); // 20
printf("b : %d\n", b); // 10
return 0;
}
| cs |
SWAP함수에서 총 3개의 명령문을 실행한다
(물론 ','를 이용하여 하나의 명령문으로 해결할 수도 있으며 비트연산자를 통해 한줄안에 처리할 수 있지만 예를들기 위해 3줄로 작성했다.)
물론 잘 실행 되는 것을 확인할 수 있다. 하지만 아래와 같이 코드를 작성했다면 약간 결과가 다를 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <stdio.h>
#define SWAP(x, y, t) { \
(t) = (x); \
(x) = (y); \
(y) = (t); }
int main(void){
int a=10;
int b=20;
int tmp;
if (1)
SWAP(a, b, tmp);
else
a=0;
return 0;
}
| cs |
위와 같이 코드를 짜면 에러가 발생한다.
위 코드는 예를 위해 만든 크게 의미는 없는 코드이지만 위와 같은 구조는 우리가 흔히 쓰는 방식이다.
16번째 줄에서 문제가 발생하는데 SWAP함수를 호출하면서 ';' 이 뒤에 붙었기 때문이다.
그러므로 else문이 제대로 동작하지 못한다. (if 문의 영역에서 세미콜론으로 끝나버렸기 때문)
위와 같은 문제를 해결하기 위한 방법으로 여러 줄의 매크로 함수를 작성할 때는 do while문을 쓴다.
아래 코드를 보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <stdio.h>
#define SWAP(x, y, t) do{ \
(t) = (x); \
(x) = (y); \
(y) = (t); } while(0)
int main(void){
int a=10;
int b=20;
int tmp;
if (1)
SWAP(a, b, tmp);
else
a=0;
return 0;
}
| cs |
모두 동일하지만 SWAP 함수를 선언하는 부분을 do { } while(0) 으로 싸고있다.
위 코드는 에러가 발생하지 않고 정상적으로 잘 동작할 것이다.
16번째 줄에서 SWAP를 호출하며 ';' 를 뒤에 붙였지만 do { } while(0) 뒤에 세미콜론이 붙은 형태로 치환되면서 아무런 문제없이 else문으로 넘어갈 것이다.
여러 줄을 사용하는 매크로 함수에서 중괄호를 이용하여 여러 명령문을 묶어주면 if else 문에서 위에서와 같은 문제가 발생할 수 있으므로 중괄호 대신 do while 문을 이용해서 여러 명령문을 묶어주자는 의미이다.
do while문은 반복문으로 동작하기 때문에 우리는 한번만 실행시키면 되므로 do { } while(0) 으로 작성을 해서 한번 실행하고 바로 탈출할 수 있도록 처리했다.
여러 명령어를 매크로 함수에 포함시킬 경우 꼭 do while문으로 묶어서 사용하자!
[Grind Away] 여러 명령이 포함된 매크로 함수는 do while을 사용하 자!
C · 2015/05/21
아래 코드를 보자 1 #include <stdio.h> 2 3 #define SWAP(x, y, t) { \
4 (t) = (x); \
5 (x) = (y); \
6 (y) = (t); }
7 8 int main(void){ 9 10 int a=10; 11 int b=20; 12 int tmp; 13 14 printf("a : %d\n", a); // 10 15 printf("b : %d\n", b); // 20 16 17 SWAP(a, b, tmp); 18 19 printf("a : %d\n", a); // 20 20 printf("b : %d\n", b); // 10 21 22 return 0; 23 } 24 cs SWAP함수에서 총 3개의 명령문을 실행한다
(물론 ','를 이용하여 하나의 명령문으로 해결할 수도 있으며 비트연산자를 통해 한줄안에 처리할 수 있지만 예를들기 위해 3줄로 작성했다.) 물론 잘 실행 되는 것을 확인할 수 있다. 하지만 아래와 같이 코드를 작성했다면 약간 결과가 다를 것이다.
1 2 #include <stdio.h> 3 4 #define SWAP(x, y, t) { \ 5 (t) = (x); \ 6 (x) = (y); \ 7 (y) = (t); } 8 9 int main(void){ 10 11 int a=10; 12 int b=20; 13 int tmp; 14 15 if (1) 16 SWAP(a, b, tmp); 17 else 18 a=0; 19 20 return 0; 21 } 22 cs 위와 같이 코드를 짜면 에러가 발생한다.
위 코드는 예를 위해 만든 크게 의미는 없는 코드이지만 위와 같은 구조는 우리가 흔히 쓰는 방식이다.
16번째 줄에서 문제가 발생하는데 SWAP함수를 호출하면서 ';' 이 뒤에 붙었기 때문이다.
그러므로 else문이 제대로 동작하지 못한다. (if 문의 영역에서 세미콜론으로 끝나버렸기 때문) 위와 같은 문제를 해결하기 위한 방법으로 여러 줄의 매크로 함수를 작성할 때는 do while문을 쓴다.
아래 코드를 보자 1 2 #include <stdio.h> 3 4 #define SWAP(x, y, t) do{ \ 5 (t) = (x); \ 6 (x) = (y); \ 7 (y) = (t); } while(0) 8 9 int main(void){ 10 11 int a=10; 12 int b=20; 13 int tmp; 14 15 if (1) 16 SWAP(a, b, tmp); 17 else 18 a=0; 19 20 return 0; 21 } 22 cs 모두 동일하지만 SWAP 함수를 선언하는 부분을 do { } while(0) 으로 싸고있다.
위 코드는 에러가 발생하지 않고 정상적으로 잘 동작할 것이다.
16번째 줄에서 SWAP를 호출하며 ';' 를 뒤에 붙였지만 do { } while(0) 뒤에 세미콜론이 붙은 형태로 치환되면서 아무런 문제없이 else문으로 넘어갈 것이다.
여러 줄을 사용하는 매크로 함수에서 중괄호를 이용하여 여러 명령문을 묶어주면 if else 문에서 위에서와 같은 문제가 발 생할 수 있으므로 중괄호 대신 do while 문을 이용해서 여러 명령문을 묶어주자는 의미이다.
do while문은 반복문으로 동작하기 때문에 우리는 한번만 실행시키면 되므로 do { } while(0) 으로 작성을 해서 한번 실 행하고 바로 탈출할 수 있도록 처리했다.
여러 명령어를 매크로 함수에 포함시킬 경우 꼭 do while문으로 묶어서 사용하자!
#C언어 #시스템프로그래밍 #임베디드 #개발자
[Grind Away] free시킨 포인터 변수에는 NULL로 초기화 해주자! 댕글 링 포인터(Dangling Pointer)
C · 2015/05/21
아래 코드를 보자.
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
int main(void){
5
int *p = (int*)malloc(sizeof(int));
6
7
*p = 10;
8
printf("%d\n", *p); // 10
9
10 free(p); 11 *p = 20; 12 return 0; 13 } 14 15 16 Colored by Color Scripter cs 이상한 점이 보이는가?
free(p) free(p)를 통해 동적할당된 메모리 공간을 해제시키고 나서 *p = 20; 과 같이 없어진 공간을 또 사용하고 있다.
이와 같이 free시켜 해제된 메모리 공간을 가리키고 있는 포인터 변수를 보고 댕글링 포인터(Dangling Pointer) 라고 한다.
위와 같이 사용한다면 당장 눈에 보이는 에러가 발생하지는 않지만 프로그램이 동작하는 도중 free한 위치에 새로 동적할 당이 이루어져 중요한 정보가 저장되어 버린다면 심각한 문제가 발생할 수 있다.
그렇기 때문에 위와 같은 문제를 해결하기 위해 습관적으로 free이후 해당 포인터 변수에 NULL값을 넣어주는 것이 좋다.
만약 귀찮다면 아래와 같이 매크로 함수를 작성하여 사용하는 것도 좋은 방법이다.
#define FREE(x) do { free(x); x=NULL; } while(0) 1 2 ... 3 FREE(p); 4 ... 5 Colored by Color Scripter cs 위와 같이 free후 NULL 값을 넣어주는 매크로 함수 FREE를 작성하여 사용하면 더 편리하게 댕글링 포인터를 예방할 수 있다.
(만약 위 매크로 함수에 do while문을 사용하는 이유가 궁금 하면 아래 게시글을 확인하라) 여러 명령이 포함된 매크로 함수는 do while을 사용하자!
아래 코드를 보자123456789101112131415161718192021222324#include <stdio.h> #define SWAP(x, y, t) { \ ...
blog.naver.com
#C언어 #시스템프로그래밍 #임베디드 #개발자 #포인터
c언어 헤더파일(header file) 생성 시 중복 포함을 방지 기법
1
2
3
4
|
// test.h
#include "hello.h"
...
| cs |
1
2
3
4
|
// test2.h
#include "hello.h"
...
| cs |
1
2
3
4
5
|
// main.cpp
#include "test.h"
#include "test2.h"
...
| cs |
위 코드를 보라
main.cpp에서는 test.h 와 test2.h 두 헤더를 추가하고 있다.
사용자 입장에서는 전혀 문제가 없어 보이지만 실제로 test.h 와 test2.h는 각각 동일한 헤더인
hello.h를 포함하고 있다.
이런 경우를 방지하기 위해 헤더를 만들 때 아래와 같이 선언해 주는것을 권장한다.
1
2
3
4
5
6
7
8
|
#ifndef __HELLO_H__
#define __HELLO_H__
...
#endif
| cs |
위 코드와 같이 선언해 주고 ... 부분에 헤더에 들어갈 코드를 입력하면 된다.
코드를 해석하면 먼저 ifndef 를 통해 __HELLO_H__ 가 선언되어 있는지 확인한다.
만약에 선언되어있지 않다면 아래 부분을 실행하고, 선언되어 있다면 endif부분 까지 건너뛴다.
만약 이 헤더를 중복정의 한다면, 먼저 정의된 헤더 부분에서 __HELLO_H__를 #define을 통해 선언했으므로 두번째 선언되는 헤더에서는 ifndef에 걸려 동일한 헤더가 실행되지 않게된다.
C라이브러리의 헤더를 보면 거의 모든 헤더가 위와 같은 구조로 시작하는것을 확인할 수 있다.
물론 필자도 헤더파일을 선언할 때 위 코드를 습관처럼 먼저 쓰고 시작한다. 저런 헤더파일을 작성할 때 무조건 써주는 습관을 들이면 상당히 좋다.
[Grind Away] c언어 헤더파일(header file) 생성 시 중복 포함을 방지 기법
C / C++ · 2015/05/21
C언어에서 많이 발생하는 실수 중 하나가 헤더파일을 중복으로 포함시키는 것이다.
1 // test.h 2 #include "hello.h"
3 4 ... cs 1 // test2.h 2 #include "hello.h"
3 4 ... cs 1 // main.cpp 2 #include "test.h"
3 #include "test2.h"
4 5 ... cs 위 코드를 보라
main.cpp에서는 test.h 와 test2.h 두 헤더를 추가하고 있다.
사용자 입장에서는 전혀 문제가 없어 보이지만 실제로 test.h 와 test2.h는 각각 동일한 헤더인 hello.h를 포함하고 있다.
이런 경우를 방지하기 위해 헤더를 만들 때 아래와 같이 선언해 주는것을 권장한다.
1 2 #ifndef __HELLO_H__ cs 3 #define __HELLO_H__ 4 5 ...
6 7 #endif 8 위 코드와 같이 선언해 주고 ... 부분에 헤더에 들어갈 코드를 입력하면 된다.
코드를 해석하면 먼저 ifndef 를 통해 __HELLO_H__ 가 선언되어 있는지 확인한다.
만약에 선언되어있지 않다면 아래 부분을 실행하고, 선언되어 있다면 endif부분 까지 건너뛴다.
만약 이 헤더를 중복정의 한다면, 먼저 정의된 헤더 부분에서 __HELLO_H__를 #define을 통해 선언했으므로 두번째 선 언되는 헤더에서는 ifndef에 걸려 동일한 헤더가 실행되지 않게된다.
C라이브러리의 헤더를 보면 거의 모든 헤더가 위와 같은 구조로 시작하는것을 확인할 수 있다.
물론 필자도 헤더파일을 선언할 때 위 코드를 습관처럼 먼저 쓰고 시작한다. 저런 헤더파일을 작성할 때 무조건 써주는 습 관을 들이면 상당히 좋다.
#C언어 #Cpp #시스템프로그래밍 #개발자 #파일입출력
매크로 함수보다는 인라인 함수를 활용하자!
아래와 같은 코드를 보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#include <iostream>
#define SQUARE(x) ((x) * (x))
using namespace std;
int main(void){
int result;
int a = 2;
result = SQUARE(a);
cout << result << endl; // 4
result = SQUARE(++a);
cout << result << endl; // 16
return 0;
}
| cs |
SQUARE(++a); 부분에서 우리는 a가 1이 증가되고 제곱되니 쉽게 9라는 값이 나오기를 예상할 것이다. 하지만 실제 동작은 ((++a) * (++a)) 형태로 동작하게 되어 ++연산이 두번 진행되게 된다.
이러한 코드상의 결함 뿐만 아니라 매크로 함수는 직관적이지 못하고 전처리기에서 진행되는 부분이기 때문에 컴파일시 에러가 발생하지 않을 뿐더러 더버깅이 불가능해 문제가 발생하면 찾기 상당히 어렵다.
아래는 인라인 함수를 통해 새로 구현한 코드이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <iostream>
using namespace std;
inline int SQUARE(int x){
return x*x;
}
int main(void){
int result;
int a = 2;
result = SQUARE(a);
cout << result << endl; // 4
result = SQUARE(++a);
cout << result << endl; // 9
return 0;
}
| cs |
단순히 SQUARE를 함수로 구현하고 앞에 명시적으로 inline 이라는 키워드를 추가했다.
상당히 쉽지않은가? 그냥 단순히 매크로로 구현할 함수를 일반 함수로 구현하고 앞에 inline만 추가해 주면된다. 위와 같이 코드를 짜면 매크로 함수와 같은 형태로 동작을 하지만 C언어 문법을 사용하기 때문에 디버깅이 수월하며 쉽게 에러를 찾을 수 있다. 위에서 발생하던 문제도 해결되어 9라는 값이 잘 출력된다.
[Grind Away] 매크로 함수보다는 인라인 함수를 활용하자!
C++ · 2015/05/21
C++에서는 인라인(inline) 함수를 지원한다. 기존 C언어에서 사용해오던 매크로(macro) 함수를 대체할 수 있는 문법인 데 왜냐 하면 기존의 매크로 함수가 가지고 있는 여러 문제점들이 있기 때문이다.
아래와 같은 코드를 보자 1 2 #include <iostream> 3 #define SQUARE(x) ((x) * (x)) 4 5 using namespace std; 6 7 int main(void){ 8 int result; 9 int a = 2; 10 11 result = SQUARE(a); 12 cout << result << endl; // 4 13 14 result = SQUARE(++a); 15 cout << result << endl; // 16 16 17 return 0; 18 } 19 cs SQUARE(++a); 부분에서 우리는 a가 1이 증가되고 제곱되니 쉽게 9라는 값이 나오기를 예상할 것이다. 하지만 실제 동 작은 ((++a) * (++a)) 형태로 동작하게 되어 ++연산이 두번 진행되게 된다.
이러한 코드상의 결함 뿐만 아니라 매크로 함수는 직관적이지 못하고 전처리기에서 진행되는 부분이기 때문에 컴파일시 에러가 발생하지 않을 뿐더러 더버깅이 불가능해 문제가 발생하면 찾기 상당히 어렵다.
아래는 인라인 함수를 통해 새로 구현한 코드이다.
1 2 #include <iostream> 3 4 using namespace std; 5 6 inline int SQUARE(int x){ 7 return x*x; 8 } 9 10 int main(void){ 11 int result; 12 int a = 2; 13 14 result = SQUARE(a); 15 cout << result << endl; // 4 16 17 result = SQUARE(++a); 18 cout << result << endl; // 9 19 20 return 0; 21 } 22 cs 단순히 SQUARE를 함수로 구현하고 앞에 명시적으로 inline 이라는 키워드를 추가했다.
상당히 쉽지않은가 그냥 단순히 매크로로 구현할 함수를 일반 함수로 구현하고 앞에 inline만 추가해 주면된다. 위와 같 이 코드를 짜면 매크로 함수와 같은 형태로 동작을 하지만 C언어 문법을 사용하기 때문에 디버깅이 수월하며 쉽게 에러를 찾을 수 있다. 위에서 발생하던 문제도 해결되어 9라는 값이 잘 출력된다.
#Cpp #C언어 #객체지향 #개발자
vector에서 iterator를 통한 요소 주소값 받아오기 (vector/iterator/get/element/address)
vector에 iterator를 통해 특정 요소의 주소를 찾고 싶을 때 아래와 같이 해 주시면됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#include <iostream>
#include <vector>
using namespace std;
int main(void){
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
int *find;
for (vector<int>::iterator iter = v.begin(); iter == v.end(); iter++){
if (*iter == 3){
// find = iter; error!!!
find = &*iter;
}
}
return 0;
}
| cs |

