libZwSock 사용예

libZwSock 시작하기


이 자습서에서는 서버/클라이언트 간 소켓통신 연결, 메세지 송신 및 수신 기능을 구현하는 과정을 안내하여 libZwSock의 필수 사항을 소개합니다.
서버 기동/정지
#include <stdio.h> /* 표준출력 */
#include <arpa/inet.h>		/* 소켓 지원 각종 함수 */
#include "libzwSock.h"		/* libZwSock head파일 */

int main(int argc, char** argv)
{
    LibZWSock zwSock;  /* zettaWorks 소켓통신 클래스 */
    unsigned short int port = 9110; /* 접속포트 */
    unsigned int rtn = 0; /* 함수리턴값*/

    // libzwSock 초기화
    zwSock.Initialize();

    // 소켓 Create/Bind/Listen 수행
    rtn = zwSock.StartServer(port);

    if (rtn != NO_ERR) {
        switch (rtn) {
        case ERR_NOT_INITIALIZED: {
            printf("Initialization failed\n");
            break;
        }
        case ERR_CREATE_SOCKET: {
            printf("Create socket failed\n");
            break;
        }
        case ERR_BIND: {
            printf("Bind failed\n");
            break;
        }
        case ERR_LISTEN: {
            printf("Listen failed\n");
            break;
        }
        default: {}
        }

        printf("Failed to start server!\n");
        return -1;
    }

    printf("Start server!\n");

    /* 여기에 사용자 로직 기술 */

    zwSock.Stop(); /* 통신 중지 */
    return 0;
}

이 프로그램의 개요

  • 라이브러리에 사용을 위해 libzwSock.h 포함
  • 서버를 기동하려면 LibZWSock 객체를 선언하고 LibZWSock::Initialize() 메소드를 사용하여 초기화
  • LibZWSock::StartServer(포트) 메소드로 서버 기동 후 결과값 리턴 ( 내부적으로 소켓 Create/Bind/Listen 수행 )
  • LibZWSock::Stop() 로 서버 정지
클라이언트 연결 수용
// 서버Fd 를 가져온다
int server_fd = zwSock.GetFd();

// 필요한 경우 소켓 논블럭,비동기로 설정한다.
fcntl(server_fd, F_SETFL, O_RDWR | O_NONBLOCK | O_ASYNC);

int client_fd = zwSock.Accept();
if (client_fd < 0) { printf("Accept failed\n"); return -1; }

// 클라이언트 소켓정보
struct sockaddr_in* client_addr = (sockaddr_in *)zwSock.GetCltInfo();
// 클라이언트 ip 출력
printf("Client Connect : %s\n", inet_ntoa(client_addr->sin_addr));

해당 코드의 개요

    • LibZWSock::GetFd() 메소드로 서버 파일 디스크립터를 가져와 통신방식을 지정한다
    • 클라이언트 연결요청이 있는 경우 LibZWSock::Accept() 메소드로 수용
    • 필요한 경우 LibZWSock::GetCltInfo() 메소드로 클라이언트 정보를 가져온다
클라이언트와의 통신
/* 사용자지정 프로토콜 */
#define PROTOCOL_ZERO 0
#define PROTOCOL_KNOCK 1    // 똑똑
#define PROTOCOL_WHO 2      // 누구냐?
#define PROTOCOL_IAM 3      // 저는요
#define PROTOCOL_SO 4       // 그래서?
#define PROTOCOL_SPEAK 5    // 잡담
#define PROTOCOL_NOISY 6    // 시끄
#define PROTOCOL_BYE 7      // 이만가요

unsigned int rtn = 0, var_cnt = 0, var_type; /* 함수리턴값, 수신data내 변수 갯수, 변수타입*/
    
while (1) {
    // 수신대기
    if ((rtn = zwSock.RecvAwait(client_fd)) < 0)
        break;

    // 수신Data Stream 내 변수 Count
    var_cnt = zwSock.GetVarCnt();

    // 애플리케이션 프로토콜을 확인하여 대응한다
    switch (rtn) {
    case PROTOCOL_ZERO: {
        continue;
    }
    case PROTOCOL_KNOCK: {
        // 송신할 프로토콜 지정
        zwSock.SetCmd(PROTOCOL_WHO);
        // 송신
        zwSock.Send(client_fd);
        printf("RSP : PROTOCOL_WHO\n");
        continue;
    }
    case PROTOCOL_IAM: {
        // PROTOCOL_IAM 프로토콜에는 하나의 문자열이 포함돼 있다는 약속 하에
        if (var_cnt > 1) {
            msg = zwSock.GetVarString(1);
            printf("Client : %s\n", msg);
        }
        zwSock.SetCmd(PROTOCOL_SO);
        zwSock.Send(client_fd);
        printf("RSP : PROTOCOL_SO\n");
        continue;
    }
    case PROTOCOL_SPEAK: {
        if (var_cnt > 1) {
            // 변수형에 따른 수신 값을 가져온다
            for (int i = 1; i <= var_cnt; i++) {
                var_type = zwSock.GetVarType(i);
                switch (var_type) {
                case ZW_SOCK_INT: {
                    num = zwSock.GetVarInt(i);
                    printf("Client : %d\n", num);
                    break;
                }
                case ZW_SOCK_STRING: {
                    msg = zwSock.GetVarString(i);
                    printf("Client : %s\n", msg);
                    break;
                }
                default:
                    continue;
                }
            }
        }
        zwSock.SetCmd(PROTOCOL_NOISY);
        zwSock.Send(client_fd);
        printf("RSP : PROTOCOL_NOISY\n");
        continue;
    }
    case PROTOCOL_BYE: {
        if (var_cnt > 1) {
            msg = zwSock.GetVarString(1);
            printf("Client : %s\n", msg);
        }
        break;
    }
    default: {
        continue;
    }
    }

    if (rtn == PROTOCOL_BYE)
        break;
}
zwSock.Close(client_fd); /* 클라이언트 끊기 */

해당 코드의 개요

    • LibZWSock::RecvAwait() 메소드로 Data를 수신
    • 클라이언트와 약속된 프로토콜별 처리
    • 수신Data Stream 내 변수형에 따라 지정된 메소드로 값을 가져온다
    • 통신 종료후 클라이언트와의 접속 끊기
클라이언트 시작
#include <stdio.h> /* 표준출력 */
#include "libzwSock.h"		/* libZwSock head파일 */

int main(int argc, char** argv)
{
    LibZWSock zwSock;  /* zettaWorks 소켓통신 클래스 */
    const char* ip = "127.0.0.1"; /* 접속ip */
    unsigned short int port = 9110; /* 접속포트 */
    unsigned int rtn = 0; /* 함수리턴값*/
    int fd = 0; // 파일 디스크립터

    // libzwSock 초기화
    zwSock.Initialize();

    // 소켓 Create/Connect 수행
    rtn = zwSock.StartClient(ip, port);

    if (rtn != NO_ERR) {
        switch (rtn) {
        case ERR_NOT_INITIALIZED: {
            printf("Initialization failed\n");
            break;
        }
        case ERR_CREATE_SOCKET: {
            printf("Create socket failed\n");
            break;
        }
        case ERR_CONNECT: {
            printf("Connect failed\n");
            break;
        }
        default: {}
        }

        printf("Failed to start client!\n");
        return -1;
    }

    printf("Connect success!\n");
    // Fd 를 가져온다
    fd = zwSock.GetFd();

    // 필요한 경우 소켓 논블럭,비동기로 설정한다.
    fcntl(server_fd, F_SETFL, O_RDWR | O_NONBLOCK | O_ASYNC);

    /* 여기에 사용자 로직 기술 */

    zwSock.Stop(); /* 통신 중지 */
    return 0;
}

이 프로그램의 개요

  • 라이브러리에 사용을 위해 libzwSock.h 포함
  • 클라이언트를 시작하려면 LibZWSock 객체를 선언하고 LibZWSock::Initialize() 메소드를 사용하여 초기화
  • LibZWSock::StartClient(주소, 포트) 메소드로 서버 연결 후 결과값 리턴 ( 내부적으로 소켓 Create/Connect 수행 )
  • LibZWSock::GetFd() 메소드로 클라이언트 파일 디스크립터를 가져와 통신방식을 지정한다
  • LibZWSock::Stop() 로 연결 종료
서버와의 통신
/* 사용자지정 프로토콜 */
#define PROTOCOL_ZERO 0
#define PROTOCOL_KNOCK 1    // 똑똑
#define PROTOCOL_WHO 2      // 누구냐?
#define PROTOCOL_IAM 3      // 저는요
#define PROTOCOL_SO 4       // 그래서?
#define PROTOCOL_SPEAK 5    // 잡담
#define PROTOCOL_NOISY 6    // 시끄
#define PROTOCOL_BYE 7      // 이만가요

unsigned int rtn = 0, var_cnt = 0, var_type; /* 함수리턴값, 수신data내 변수 갯수, 변수타입*/
int num; // 송신 정수값

// 송신할 프로토콜 지정
zwSock.SetCmd(PROTOCOL_KNOCK);
// 송신
rtn = zwSock.Send(fd); 

printf("REQ : PROTOCOL_KNOCK\n");

while (1) {
    // 수신대기
    if ((rtn = zwSock.RecvAwait(fd)) < 0)
        break;

    // 수신Data Stream 내 변수 Count
    var_cnt = zwSock.GetVarCnt();

    // 애틀리케이션 프로토콜을 확인하여 대응한다
    switch (rtn) {
    case PROTOCOL_ZERO: {
        continue;
    }
    case PROTOCOL_WHO: {
        printf("REQ : PROTOCOL_IAM\n");
        // 송신할 프로토콜 지정
        zwSock.SetCmd(PROTOCOL_IAM);
        const char* msg = "My name is steelwater.";
        printf("Me : %s\n", msg);
        // 송신 문자열 추가
        zwSock.AddDataString(msg);
        zwSock.Send(fd);
        continue;
    }
    case PROTOCOL_SO: {
        printf("REQ : PROTOCOL_SPEAK\n");
        zwSock.SetCmd(PROTOCOL_SPEAK);
        zwSock.AddDataString("I am");
        num = 10;
        // 송신할 정수 추가
        zwSock.AddDataInt(num);
        // 갯수에 상관없이 Data 임의 추가
        zwSock.AddDataString("years old.");
        zwSock.AddDataString("nice to meet you");
        zwSock.AddDataString("how old are you?");
        printf("I am %d years old.\nnice to meet you\nhow old are you?\n", num);
        num = 12;
        zwSock.AddDataInt(num);
        zwSock.AddDataString("?");
        printf("%d ?\n", num);
        zwSock.Send(fd);
        continue;
    }
    case PROTOCOL_NOISY: {
        printf("REQ : PROTOCOL_BYE\n");
        zwSock.SetCmd(PROTOCOL_BYE);
        const char* msg = "Ok bye!";
        printf("Me : %s\n", msg);
        zwSock.AddDataString(msg);
        zwSock.Send(fd);

        break;
    }
    default: {
        continue;
    }
    }

    if (rtn == PROTOCOL_NOISY)
        break;
}

해당 코드의 개요

    • LibZWSock::SetCmd() 메소드로 프로토콜 지정
    • 서버와 약속된 프로토콜별 처리
    • 지정된 메소드로 송신할 임의의 Data를 추가한다
error: Content is protected !!
위로 스크롤