클라이언트에서 피연산자 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' 카테고리의 다른 글

[TCP/IP] 온라인 사칙연산 서비스 구현  (0) 2013.02.09
Linux TCP/IP 소켓 프로그래밍  (0) 2013.01.27
Linux Shell 구현  (0) 2013.01.27

클라이언트에서 어떠한 문자열을 입력하게되면 서버에서 read하고 다시 클라이언트에 write하게 되어 즉, 클라이언트에서는 자신이 입력한 문자열을 다시 출력하게 되는 구조를 띄게 됩니다.


client.c



#include <stdio.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <sys/stat.h>

#include <string.h>

#include <unistd.h>

#include <stdlib.h>

#define MAXLINE 1024


int main(int argc, char **argv)

{

struct sockaddr_in serveraddr;

int server_sockfd;

int client_len;

char buf[MAXLINE];

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(3500);

client_len = sizeof(serveraddr);

if(connect(server_sockfd, (struct sockaddr *)&serveraddr, client_len) == -1)

{

perror("connect error : ");

return 1;

}

memset(buf, 0x00, MAXLINE);

read(0, buf, MAXLINE);

if(write(server_sockfd, buf, MAXLINE) <= 0)

{

perror("write error: " );

return 1;

}

memset(buf, 0x00, MAXLINE);

if(read(server_sockfd, buf, MAXLINE) <= 0)

{

perror("read error : ");

return 1;

}

close(server_sockfd);

printf("server : %s\n", buf);

return 0;

}


server.c


#include <stdio.h>

#include <sys/socket.h>

#include <stdlib.h>

#include <arpa/inet.h>

#include <sys/stat.h>

#include <unistd.h>

#include <string.h>


#define MAXBUF 1024


int main(int argc, char **argv)

{

int server_sockfd, client_sockfd;

int client_len, n;

char buf[MAXBUF];

struct sockaddr_in clientaddr, serveraddr;

if((server_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)

{

perror("socket error:");

exit(0);

}

bzero(&serveraddr, sizeof(serveraddr));

serveraddr.sin_family = AF_INET;

serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

serveraddr.sin_port = htons(atoi(argv[1]));

bind(server_sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));

listen(server_sockfd, 5);


while(1)

{

memset(buf, 0x00, MAXBUF);

client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, &client_len);

printf("New Client Connect : %s\n", inet_ntoa(clientaddr.sin_addr));

if((n = read(client_sockfd, buf, MAXBUF)) <= 0)

{

close(client_sockfd);

continue;

}

if(write(client_sockfd, buf, MAXBUF) <= 0)

{

perror("write error:");

close(client_sockfd);

}

}

close(server_sockfd);

return 0;

}



client.c


server.c


신고

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

[TCP/IP] 온라인 사칙연산 서비스 구현  (0) 2013.02.09
Linux TCP/IP 소켓 프로그래밍  (0) 2013.01.27
Linux Shell 구현  (0) 2013.01.27

fork함수와 execl함수를 이용하여 Shell 구현.

1. 사용자 명령을 읽기 위한 프롬프트 출력

2. 키보드로 명령을 받는다.

3. fork 함수로 자식 프로세스 생성. 부모 프로세스는 자식 프로세스가 종료되는 걸 기다림.

4. execl 함수로 외부 프로그램(프롬프트 실행)을 실행한다

5. 외부 프로그램 종료(자식 프로세스도 종료)

6. 부모 프로세스는 자식 프로세스가 종료된 걸 확인하고, 다시 프롬프트를 띄움.


#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <sys/wait.h>

#include <sys/types.h>


#define MAX_LINE 256

#define PROMPT "# "

#define chop(str) str[strlen(str) -1] = 0x00;


int main(int argc, char **argv)

{

char buf[MAX_LINE];

int proc_status;

pid_t pid;

printf("My Shell VEr 1.0\n");

while(1)

{

memset(buf, 0x00, MAX_LINE);

fgets(buf, MAX_LINE-1, stdin);

if(strncmp(buf, "quit\n", 5) == 0)

break;

}

chop(buf);

pid = fork(); // process copy

if(pid==0)

{

if(execl(buf, buf, NULL) == -1)

{

printf("Execl failure\n");

exit(0);

}

}

if(pid>0)

{

printf("Cld wait\n");

wait(&proc_status);

printf("Cild exit\n");

}

}

return 0;

}



myshell.c


신고

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

[TCP/IP] 온라인 사칙연산 서비스 구현  (0) 2013.02.09
Linux TCP/IP 소켓 프로그래밍  (0) 2013.01.27
Linux Shell 구현  (0) 2013.01.27

+ Recent posts

티스토리 툴바