이전... (거의 8개월전) 게임서버 프로그래밍 시간에 기말로 짜다가
( http://rosagigantea.tistory.com/276  <- 이것..)
리눅스라는 첨병과... vi의 공새로 ... 그래도 그럭저럭 짜놓은 게임서버 소스를

좀 리뉴얼 해 보았습니다.

서버 프로그램은 밑의 cmd 창

불행히도... 윈도우 비스타는 telnet 프로그램이 없기때문에...
윈도우 네트워크 프로그래밍 이란 책의 GUI 클라이언트를 좀 개량해서
(책의 소스는 보내서, 바로 받지 않으면 않되게 되어있는 에코 예제라서..)
만들었고..

그리고 역시 불행히도.. 윈도우는 epoll 이 없기 때문에... IOCP로 구조를 바꿧습니다..

음 그 외엔.... 윈도우용 my sql 을 이용해서 db 연동 까지....
이전의 C로 짠 알고리즘등을  C++의 신... STL 을 사용해서 여러가지로 알고리즘을
개량 해봤습니다...


... 그래서 되는거라곤 ...
1. 2D 가상 지형이 생성
2. 로그인 하면 DB에 저장된 정보를 토대로 현재 위치 지정됨
3. 2D 가상 지형상.. 이동 가능
4. 서로간 채팅 가능..
5. 주위 녀석들 누가 있는지 알 수 있음..
6. DB log, error 저장 등..

정도 이므로 진짜 게임 서버에는 확실히 많이 모자르네요..

그래서 이제 슬슬 클라이언트도 손을 댈래고 합니다.. >_<..
쩝.. 이국 생활 하면서.. 틈틈히 하는 열정.. 식지 않길.. orz

#include <stdio.h>
#include <errno.h>
#include <mysql.h>

MYSQL mysql;

// 쿼리 질의를 한다
void sql_qur(char *sql_query)
{
     printf("input sql query is %s\n", sql_query);
     if( mysql_real_query(&mysql, sql_query, strlen(sql_query)) )
     {
          perror( mysql_error(&mysql) );
          exit( 1 );
     }
}

// 쿼리 질의로 온 결과를 모두 출력한다.
void sql_print_result(char *result)
{
     MYSQL_RES *res;
     MYSQL_ROW row;
     MYSQL_FIELD *fld;
     int fields;

     if( !(res=mysql_store_result(&mysql)) )
     {
          perror( mysql_error(&mysql) );
          exit( 1 );
     }
 
     sprintf(result, "");

     while( (row=mysql_fetch_row(res)) )
     {
          int     i;
     
          for( i=0 ; i<mysql_num_fields(res) ; i++ )
          {
              fld = mysql_fetch_field_direct( res, i );

              if(i == 0)
                  sprintf( result, "%s%20s: %s", result, fld->name, row[i] );
              else
                  sprintf( result, "%s\n%20s: %s", result, fld->name, row[i] );

              if( !strlen(row[i]) )
              {
                  mysql_free_result(res);
                  mysql_close(&mysql);
                  exit(0);
              }
          }
          sprintf( result, "%s\n\n", result );
      }

      mysql_free_result(res);
}

// 쿼리를 받음 단, 한줄에 한개의 쿼리가 찍힌다
void sql_get_result(char *result)
{
        MYSQL_RES *res;
        MYSQL_ROW row;
        int line = 0;
 
        if( !(res=mysql_store_result(&mysql)) )
        {
                perror( mysql_error(&mysql) );
                exit( 1 );
        }
 
        sprintf(result, "");
 
        while( (row=mysql_fetch_row(res)) )
        {
                int     i;
 
                for( i=0 ; i<mysql_num_fields(res) ; i++ )
                {
                        if(i == 0 && line == 0)
                               sprintf( result, "%s", row[i] );
                        else
                               sprintf( result, "%s\n%s", result, row[i] );
 
                        if( !strlen(row[i]))
                        {
                                mysql_free_result(res);
                                mysql_close(&mysql);
                                exit(0);
                         }
                 }
                ++line;
        }
        result[strlen(result)] = '\0';
        mysql_free_result(res);
}

void main(void)
{
        char input_query[100];
        mysql_init( &mysql );

        if( !mysql_real_connect(&mysql,
           "localhost",            // host
           "user",          // user
           "pw",       // passwd
           "db_name",          // db
           3306,                   // port
           NULL,
           0) )
        {
         perror( mysql_error(&mysql) );
         exit( 1 );
        }

        // user 테이블을 출력한다.
        sql_qur("select * from user;");
        sql_print_result(&input_query);
        printf("sql result %s\n", input_query);
 
        // test01 ID에 대한 password 값을 구한다.
        sql_qur("select password from user where ID='test01';");
        sql_get_result(&input_query);
        printf("sql result %s\n", input_query);
 
        // 질의를 입력 받아서 그 결과를 계속 출력
        while(1)
        {
                printf("input sql query! : ");
                sql_qur(gets(input_query));

                sql_get_result(&input_query);
                printf("\nsql result %s\n", input_query);
        }

        mysql_close(&mysql);
}


 출처 카페 > 세은파파의 프로그래밍 하자 .. | 세은파파
원문 http://cafe.naver.com/cyberzone/172
MySQL C API

 1) my_ulonglong mysql_affected_rows(MYSQL* mysql)
        INSERT, UPDATE, DELETE 등의 query로 영향을 받은 ROW의 수를 리턴한다.

2) void mysql_close(MYSQL* mysql) 서버와의 연결을 종료한다.

3) void mysql_data_seek(MYSQL_RES* result, unsigned int offset)
        result에서 임의의 ROW에 접근을 하도록 하는 함수이다. offset이 row의 번호를
        나타낸다. 0이면 처음 ROW, mysql_num_rows( result ) - 1 은 마지막 row를 나타낸다.

4) unsigned int mysql_errno(MYSQL* mysql) 
    가장 최근에 mysql에 일어난 에러의 번호를 리턴한다.

5) char* mysql_error(MYSQL* mysql) 가장 최근에 일어난 에러 메시지를 리턴한다.

6) MYSQL_FIELD* mysql_fetch_field(MYSQL_RES* result)
        한번 호출할 때마다 한 나의 필드에 대한 정보를 리턴한다.

7) MYSQL_FIELDS* mysql_fetch_fields(MYSQL_RES* result)
        배열 형대로 result의 필드에 대한 정보를 한꺼번에 리턴한다.

8) MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL* mysql, MYSQL_FIELD_OFFSET offset)
        임의의 필드에 접근을 하도록 한다.

9) MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES* result)
        현재 필드의 offset을 리턴한다.

10) void mysql_free_result(MYSQL_RES* result)
        result에 할당된 메모리를 해제한다.

11) MYSQL* mysql_init(MYSQL* mysql)
        mysql 객체를 초기화 한다. 인자가 NULL이면 새로운 MYSQL 객체를 생성하고, 초기화 하여 리턴한다.

12) MYSQL_RES* mysql_list_dbs(MYSQL* mysql, const char* wild)
        현재 서버에 있는 데이타베이스의 목록을 리턴한다. wild는 MySQL에서
        사용할 수 있는 정규식을 나타낸다.    
        result = mysql_list_dbs( &mysql,"%" )
        는 모든 데이타베이스를 리턴하는 예이다.(%는 '모든'을 나타낸다)

13) MYSQL_RES* mysql_list_tables(MYSQL* mysql, const char* wild)
        현재 데이타베이스에 있는 테이블들의 목록을 리턴한다.

14) unsigned int mysql_num_fields(MYSQL_RES*result) 혹은
    unsigned int mysql_num_fields(MYSQL* mysql)
 
    필드의 수를 리턴한다.

15) my_ulonglong mysql_num_rows(MYSQL_RES* result)
        result에 총 몇 개의 ROW가 있는지 리턴한다. query 수행 후
        mysql_store_result()를 호출하였을 경우에만 사용할 수 있고,  
        mysql_use_result()는 사용할 수 없다.

16) int mysql_ping(MYSQL* mysql) 
        서버에 연결 중인지를 리턴한다. 연결이 끊어 졌을 경우, 다시
        연결을 시도한다. 서버와 연결을 한 후 오랫동안 가만히 있으면
        서버가 연결을 끊어버리는데, 이런 경우에 사용한다.

17) int mysql_query(MYSQL* mysql, const char* query)
        query가 포인트 하는 쿼리를 수행한다. query의 끝은 NULL 문자이다.
        성공적으로 query를 수행하였으면 0을 리턴한다.

18) MYSQL* mysql_real_connect(MYSQL* mysql, const char* host, const char* user,
const char* passwd, const char* db, uint port, const char* unix_socket,
unit client_flag )
 
         host와의 연결을 시도한다.

19) int mysql_real_query(MYSQL* mysql, const char* query, unsigned int length)
         mysql_query()처럼 query를 수행하나, query의 끝이 legnth인 것이 다르다.

20) MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES* result) 
        현재 ROW의 offset을 리턴한다.

21) int mysql_select_db(MYSQL* mysql, const char* db)
        사용하고자 하는 database를 변경한다. mysql_query()를 이용하여 "use db이름"
        의 query를 수행해도 같은 결과를 얻는다.

22) int mysql_shutdown(MYSQL* mysql)
        서버를 종료시킨다. 현재 사용자에게 shutdown 권한이 있어야 한다.

23) MYSQL_RES* mysql_store_result(MYSQL* mysql)
        query의 수행 결과를 서버로부터 한 번에 모두 받아 온다.

24) MYSQL_RES* mysql_use_result(MYSQL* mysql)
        query의 수행 결과를 서버로부터 한 개의 ROW 씩 받아 온다.
   


간단한 예   
   
***********************************************************
1: #include <stdio.h>
2: #include <mysql.h>
3: #include <errno.h>
4:
5: void main(void)
6: {
7: MYSQL mysql ;
8: MYSQL_RES* res ;
9: MYSQL_ROW row ;
10: int fields ;
11:
12: mysql_init(&mysql) ;
13:
14: if(!mysql_real_connect(&mysql, NULL, "사용자","암호", "test" ,3306, (char *)NULL, 0))
15: {
16:     printf("%s\n",mysql_error(&mysql));
17:     exit(1) ;
18: }
19:
20: if(mysql_query(&mysql, "USE super") )
     // mysql_query()는 query 수행시에 에러가 나게 되면
     // 0이 아닌 값을 리턴한다.
     {
          printf("%s\n", mysql_error(&mysql) ;
          exit(1) ;
     }
21: if(mysql_query(&mysql, "SELECT * FROM dome") )
     {
          printf("%s\n", mysql_error(&mysql) ;
          exit(1) ;
     }
22:
23: res = mysql_store_result( &mysql ) ;
24: fields = mysql_num_fields(res) ;
25:
26: while( ( row = mysql_fetch_row( res ) ))
27: {
28:      for( cnt = 0 ; cnt < fields ; ++cnt)
29:      printf("%12s ", row[cnt]) ;
30:
31:      printf("\n") ;
32: }
33:
34: mysql_free_result( res ) ;
35: mysql_close(&mysql) ;
36: }

*****************************************************
출처 |
원문 http://blog.naver.com/babygom/40014020439

1. Mysql 다운로드& 설치
   http://dev.mysql.com/downloads/ 으로 가서 윈도우용 버전으로 다운을 받고 설치

2. Visual Studio에서 Include, Lib 폴더 설정
    Tools -> option -> directory 에 헤더파일 / 라이브러리 폴더 설정
     헤더 파일 폴더는 Mysql설치된폴더Include
     라이브러리 파일 폴더는 Mysql설치된폴더LibDebug
                                      Mysql설치된폴더LibOpt

3. 프로젝트 셋팅
   위 상태에서 Mysql C API 를 쓰면 컴파일 에러가 발생한다.
   소켓 lib 가 설정되지 않았기 때문이다.
   project --> settings --> [link] 에 ws2_32.lib 추가.
 
   이 상태에서는 컴파일까지는 되지만, 링킹 과정에서 unresolved external symbol 가 발생한다.
   project --> settings --> [link] 에 libmySQL.lib 추가.

4. 지정된 경로에 libmySQL.DLL 파일이 없다는 에러가 발생할시에는..
   Mysql 의 lib 폴더에서 libmySQL.DLL파일을 프로젝트 폴더로 복사한다.


출처: http://www.codedream.net/blog/?no=45

.2003 까지 된다..
제길.. 2005는 왜안되~~~~!
이것땜에 이번 중간고사 평점 2는 깍였을꺼야!! orz

>_<

+ Recent posts