꿈 많은 개발자가 되자! Tae-hwan

1. C언어 노트 프로그램 서버와 클라이언트 정의 본문

Programming language/C

1. C언어 노트 프로그램 서버와 클라이언트 정의

taehwan 2012.06.30 00:11
크리에이티브 커먼즈 라이선스

Creative Commons License 이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
본문

 지난 기말 과제로 작성했던 프로그램을 흔적을 남기기위해 남겨둡니다. 몇가지 제약과 문제점을 가지고 있기 때문에 완벽한 코드는 절대 아닙니다. 가장 기초적인 코드 작성을 해두었기 때문에 불필요한 부분이 많이 있을 것이라고 생각됩니다. 단순 참고용으로 활용하시고, 이상한 부분은 지적 부탁드립니다.


3가지로 분리하고, 서버와 클라이언트 정의, 서버 소스코드, 클라이언트 소스코드로 분리하여 올려둡니다.

  1. C언어 노트 프로그램 서버와 클라이언트 정의

  2. C언어 노트 프로그램 서버

      http://thdev.net/249

  3. C언어 노트프로그램 클라이언트


작성한 프로그램은?

 기말 과제로 나온건 에버노트를 참고하여 프로그램을 작성하는 문제였습니다.

 에버노트를 간단히 정리하면 클라이언트 프로그램이 존재하며, 클라이언트는 동시에 여러개의 PC에서 사용이 가능합니다. 여러개의 PC가 실시간 동기화 처리되지는 않으며, 특정 시간을 정해두고, 해당 시간이 되면 서버와 클라이언트의 동기화가 진행됩니다. 그리고 가장 기본적으로 메모 작성, 수정, 태그 기능이 있고, 1개의 노트북에는 여러개의 노트가 올 수 있고, 한명의 사용자는 여러개의 노트북을 둘 수 있습니다. 태그를 이용하여 분리하기도 하지만 해당 프로그램에는 제외했습니다.

 그렇기 때문에 사용자가 직접 동기화를 요청하거나, 시간이 되어야 동기화가 처리됩니다. 제가 작성한 노트에는 푸쉬형태의 동기화는 처리되지 않고, 새로운 파일을 생성하고, 특정 메뉴를 호출 할 경우에 서버에 전송 및 서버 DB에 저장을 하게 됩니다. 그리고 1명의 여러개의 클라이언트를 가질 수 있고, 모두 다른 세션으로 존재합니다. 사용자는 노트북을 생성하고, 새로운 노트를 수정 삭제 추가 할 수 있습니다.


서버와 클라이언트 정의

 서버가 실행되면 사용자, 노트북, 노트를 구조체화 시켜 일정 크기만큼 생성한 후 user.dat 파일을 서버 DB로 활용합니다. 구조체를 입출력하고, 서버와 클라이언트 간 데이터 전송은 모두 구조체를 사용합니다. 서버에 user.dat 파일이 없을 경우 데이터를 모두 -1로 초기화 하여 저장하고, 이미 있을 경우에는 구조체 형태로 다시 불러와 서버가 동작합니다.

 클라이언트는 처음 실행 시 서버에 로그인 ID를 주어 새로운 사용자인지 기존 사용자인지 구분이 이루어지고, 세션을 받아와 저장해 둡니다. 세션이 생성된 이후부터는 모두 ID가 아닌 세션의 형태로 데이터 처리가 이루어집니다.


서버 동작 정의

 서버는 사용자, 노트북, 노트에 대한 구조체를 각각의 구조체 크기로 잡게 됩니다. 처음 실행시 서버에서 user.dat가 있는지 없는지를 체크한 후 없을 경우 앞에서 생성한 구조체를 -1과 '0'으로 초기화 후 파일로 저장하게 됩니다. 없어서 생성했거나 이미 가지고 있을 경우에는 user.dat 파일을 불러와 구조체 형태로 서버 메모리에 탑제하고, Client가 접속 또는 요청이 있을 경우까지 대기합니다. 각 Client를 별도로 동작하기 위해서 각각 별도의 쓰레드로 동작합니다. 메모리 저장 및 파일 입출력 부분은 동시 사용의 문제를 해결하기 위해서 모두 뮤텍스로 처리하였습니다.

 서버에서 사용한 구조체

typedef struct { int userID; char ID[12]; int createTime; int updateTime; }userinfo; typedef struct { int notebooksID; int userID; char notebookTitle[32]; int createTime; int updateTime; }notebooks; typedef struct { int noteID; int userID; int notebooksID; char noteContent[1024]; }notes;

 위와 같은 구조체를 작성하고, userinfo에 대한 구조체는 30개, notebooks에 대한 구조체 30개, notes에 대한 구조체 100개를 작성하여 서버 DB로 활용한다. 이렇게 작성할경우 사용자는 최대 30명, 30명이 가질 수 있는 notebooks는 최대 30개이며 100개의 노트만을 가질 수 있는 문제가 발생한다. 해결 하기 위해서는 사용자 별로 별도의 notebooks와 note를 생성해야 하지만 해당 코드에는 그렇게 처리하지 않았다.


간단히 작성한 서버 구성도


클라이언트 동작 정의

 클라이언트는 시작과 동시에 서버로 접속을 해야 합니다. 서버에 접속하기 위해서는 ID를 통해 서버로 접속하고, 서버에서 새로운 ID인지 기존 ID인지 구분하여 세션을 제공합니다. 받아온 세션을 이용하여 클라이언트는 새로운 노트북 작성, 노트북 삭제의 기능을 가지며, 새로운 노트의 추가, 삭제, 추가기능을 가지게 됩니다. 해당 작업들은 모두 실시간으로 서버와 동기화 되어 항상 최신의 데이터들로 유지되게 됩니다.

 클라이언트는 여러개가 동시에 접속이 가능하며 동일한 사용자라면 항상 최신의 데이터를 가지게 됩니다.


해당 프로그램의 문제점

 위와 같이 작성하였을 경우에 제약점이 많이 발생합니다. 서버에서는 처음부터 최대한 받을 수 있는 사용자 수, 노트북 수, 노트 수가 모두 고정이 되게 됩니다. 그렇기에 데이터가 해당 수가 넘어가게 되면 오류가 발생하여 더이상 사용 할 수 없습니다. 텍스트는 따로 처리하지 않아기에 1024 byte를 넘길 경우에는 손실되는 문제가 있습니다. 해당 문제는 1024byte를 기준으로 짤라서 저장하면 되지만 해당 코드에는 그 문제를 해결하지 않았습니다.


노트 프로그램 실행 화면

 실행화면은 깔끔하게 정리하지 않아 했갈릴 수 있을 것 같습니다.

 제가 실행한 순서는 서버를 동작하고, 클라이언트는 총 3개를 열었습니다. 클라이언트 1은 newUser 라는 아이디를 사용하였고, 새로운 노트와 노트북을 작성하였고, 클라이언트 2는 newUser로 서버에 접속하고, 클라이언트 1이 생성한 노트북 한개를 삭제하였습니다. 그리고 클라이언트 3은 앞에 2개의 클라이언트와 상관없는 새로운 사용자로 접속하였습니다.


서버 프로그램 실행

 실행 명령 ./server 포트번호

 실행 명령 ./server 7000


클라이언트 1번

 클라이언트 1번은 newUser라는 이름으로 접속하였고, 새로운 노트북 1개와 새로운 노트 2개를 추가하였습니다. 새로운 노트는 2개의 노트북에 각각 생성하였습니다.


클라이언트 2번

 클라이언트 2번은 클라이언트 1번과 동일한 newUser라는 아이디로 접속하였습니다. 그렇기 때문에 클라이언트 1번과 모두 동일한 데이터를 가지고 있습니다.


클라이언트 3번

 클라이언트 3번은 new라는 새로운 사용자로 접속하였습니다. Notebooks의 Notebooks NO을 보면 300으로 나오게 됩니다. 이는 하나의 구조체로 처리하였기에 발생하는 문제입니다.


다시 클라이언트 1번

 클라이언트 2번에서 노트북을 삭제한 이후이기 때문에 클라이언트 1번은 새로운 데이터를 요청하면 최신의 데이터가 아래와 같이 불러와지게 됩니다.



저작자 표시
신고
개인 광고 영역
2 Comments
  • 2013.04.08 16:00 비밀댓글입니다
  • taehwan 2013.04.09 00:37 신고 스마트폰에서 스마트폰을 원격한다라... 통신방법이전에 해결해야 할것이 있는데 화면을 가져와야한다면 화면을 가져오는 방법이 필요하고. 그렇지 않고 단순히 마우스처럼 컨트롤 하는것처럼한다면 .. 단순 통신 방법이 필요하겠죠.
    별다른 통신 방법은 없구요. 1:1로 Tcp/udp 통신을 하면 되겠죠.

    가장 중요한건..... 그렇게 써야하는 이유가 있을까란 생각을........
댓글쓰기 폼