hahahia

[TCP/IP] 온라인 사칙연산 서비스 구현 본문

Linux/Linux Programming

[TCP/IP] 온라인 사칙연산 서비스 구현

hahahia 2013. 2. 9. 13:39

클라이언트에서 피연산자 2개와 연산자 1개를 입력받으면 서버에서 연산을 하여 다시 클라이언트에게 결과값을 보여주는 프로그램을 만들어보았습니다.(리눅스 환경)


/* server */


#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <sys/stat.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <sys/time.h>


#define PORT 3600


struct cal_data{ // 주고받을 데이터 구조체 정의

int left_num;

int right_num;

char op;

int result;

short int error;

};


int main(int argc, char **argv)

{

struct sockaddr_in client_addr, sock_addr;

int listen_sockfd, client_sockfd;

int addr_len;

struct cal_data rdata;

int left_num, right_num;

short int cal_result;


if((listen_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

perror("error");

return 1;

}

memset((void *)&sock_addr, 0x00, sizeof(sock_addr));

sock_addr.sin_family = AF_INET;

sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);

sock_addr.sin_port = htons(PORT);

if(bind(listen_sockfd, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) == -1)

{

perror("error");

return 1;

}

if(listen(listen_sockfd, 5) == -1)

{

perror("error");

return 1;

}

while(1)

{

addr_len = sizeof(client_addr);

client_sockfd = accept(listen_sockfd, (struct sockaddr *)&client_addr, &addr_len);

if(client_sockfd == -1)

{

perror("error");

return 1;

}

read(client_sockfd, (void *)&rdata, sizeof(rdata)); // 소켓에서 데이터를 읽어옴

rdata.error = 0;

left_num = ntohl(rdata.left_num); // 네트워크 바이트 순서 변환

right_num = htonl(rdata.right_num);

switch(rdata.op) // 연산 수행

{

case '+':

cal_result = left_num + right_num;

break;

case '-':

cal_result = left_num - right_num;

break;

case '*':

cal_result = left_num * right_num;

break;

case '/':

if(right_num == 0)

{

rdata.error = 2;

break;

}

cal_result = left_num / right_num;

break;

default:

rdata.error = 1;

}

rdata.result = htonl(cal_result); // 결과 값을 네트워크 바이트 순서에 맞춤.

rdata.error = htons(rdata.error);

write(client_sockfd, (void *)&rdata, sizeof(rdata)); // 전송~

close(client_sockfd);

}

close(listen_sockfd);

return 0;

}



/* client */

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <stdio.h>

#define PORT 3600
#define IP '127.0.0.1'

struct cal_data{
int left_num;
int right_num;
char op;
int result;
short int error;
};

int main(int argc, char **argv)
{
struct sockaddr_in serveraddr;
int server_sockfd;
int client_len;
char buffer[256];
int len;
struct cal_data sdata;

len = sizeof(sdata);
memset(&sdata, 0x00, len); // 구조체를 초기화
sdata.left_num = atoi(argv[1]); // 구조체에 인자로 입력받은 값을 채운다.
sdata.right_num = atoi(argv[2]);
sdata.op = argv[3][0];

if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("error");
return 1;
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serveraddr.sin_port = htons(3600);
client_len = sizeof(serveraddr);
if(connect(server_sockfd, (struct sockaddr *)&serveraddr, client_len) == -1)
{
perror("connect error");
return 1;
}
sdata.left_num = htonl(sdata.left_num);
sdata.right_num = htonl(sdata.right_num);
if(send(server_sockfd, (void *)&sdata, len, 0) <= 0) // 구조체 서버 전송
{
perror("write error");
return 1;
}
if(recv(server_sockfd, (void *)&sdata, len, 0) <= 0) // 결과값 읽어옴.
{
perror("read error");
return 1;
}
printf("%d %c %d = %d\n", ntohl(sdata.left_num), sdata.op, ntohl(sdata.right_num), ntohl(sdata.result));
close(server_sockfd);
return 0;
}


먼저 cal_server를 켠 뒤 cal_client를 argv인자로 입력받아 실행시키면 결과값이 출력되는 것을 보실 수 있습니다.


cal_client.c


cal_server.c



'Linux > Linux Programming' 카테고리의 다른 글

Linux TCP/IP 소켓 프로그래밍  (0) 2013.01.27
Linux Shell 구현  (0) 2013.01.27
Comments