계산기 서버 & 클라이언트

Benedictus Park·2022년 12월 15일
0

TCP/IP

목록 보기
9/11
post-thumbnail

세 개의 정수와 하나의 연산자가 주어지면, 세 개의 정수에 대해 연산자에 해당하는 연산을 수행하는 계산기 서버와 클라이언트를 만들어 보자.

예를 들어, 10, 20, 30을 입력하고 +를 전달하면, 10 + 20 + 30의 결과를 내놓는 서버를 만드는 것이다.

1. 클라이언트

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int main(void){
    int a, b, c, result;
    char op;
    int clnt_sock;
    struct sockaddr_in serv_addr;
    
    printf("수 세 개 입력: ");
    scanf("%d %d %d", &a, &b, &c);
    getc(stdin);
    
    do{
        printf("연산자 입력: ");
        scanf("%c", &op);
    }while(op != '-' && op != '+' && op != '*' && op !='/');
    
    // 1. 서버 주소 정보 만들기
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    inet_aton("127.0.0.1", &serv_addr.sin_addr);
    serv_addr.sin_port = htons(8888);
    
    // 2. 클라이언트 TCP 소켓 만들기
    if((clnt_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1){
        printf("socket() Err\n");
        return 0;
    }
    
    // 3. 서버와 연결!
    if(connect(clnt_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1){
        printf("connect() Err\n");
        return 0;
    }
    
    // 4. a, b, c, op를 서버로 전송!
    write(clnt_sock, &a, sizeof(a));
    write(clnt_sock, &b, sizeof(b));
    write(clnt_sock, &c, sizeof(c));
    write(clnt_sock, &op, sizeof(op));
    
    // 5. 계산 결과 받아오기
    read(clnt_sock, &result, sizeof(result));
    
    // 6. 서버로부터 받은 계산 결과 출력
    printf("%d %c %d %c %d = %d\n", a, op, b, op, c, result);
    close(clnt_sock);
}

2. 서버

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int main(void){
    int serv_sock, clnt_sock;
    struct sockaddr_in serv_addr, clnt_addr;
    socklen_t clnt_addr_size;
    int a, b, c, result = 0;
    int cur_len = 0;
    char op;
    
    // 1. 소켓 생성
    serv_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(serv_sock == -1){
        printf("socket() 오류");
        return 0;
    }
    
    // 2. 주소정보 채우기
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(8888);
    
    // 3. 바인딩
    if(bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1){
        printf("bind() 오류");
        return 0;
    };
    
    // 4. 연결 요청 대기 시작
    if(listen(serv_sock, 5) == -1){
        printf("listen() 오류");
        return 0;
    }
    
    clnt_addr_size = sizeof(clnt_addr);
    
    while(1){
        // 5. 연결요청 수락
        if((clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size)) == -1){
            printf("accept() 오류");
            return 0;
        }
        printf("연결 Accepted!\n");
        
        read(clnt_sock, &a, sizeof(a));
        read(clnt_sock, &b, sizeof(b));
        read(clnt_sock, &c, sizeof(c));
        read(clnt_sock, &op, sizeof(op));
        
        // 6. 계산
        switch(op){
            case '+':
                result = a + b + c;
                break;
            case '-':
                result = a - b - c;
                break;
            case '/':
                result = a / b / c;
                break;
            case '*':
                result = a * b * c;
                break;
        }
        
        // 7. 계산 결과 전송
        write(clnt_sock, &result, sizeof(result));
        close(clnt_sock);
    }
}

0개의 댓글