2012/12/22 - [컴퓨터/졸업과제] - [졸업과제]과제를 위한 가이드라인 세우기

자 가이드라인에 따르면 이번엔

2. Linux 응용프로그램작성

을 할 차례이다.

2.1 응용프로그램작성

일단 이게 되면 나머지는 똑같은 것을 반복한다.

흔한 소켓프로그램 작성법을 따라서, 

#include <sys/socket.h>

#include <sys/stat.h>

#include <arpa/inet.h>

#include <signal.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/wait.h>

이놈들을 include한다.

그다음

int serv_sock;

int clnt_sock;

struct sockaddr_in serv_addr;

struct sockaddr_in clnt_addr;

int sockOpt;

요 변수들을 만든다.

각각 서버소켓(listen용) 클라이언트소켓(통신용), 서버주소(자신의 주소), 클라이언트 주소(접속한 상대의 주소)를 저장하는 변수들이고,
sockOpt 이녀석은 한 포트로 여려개의 bind를 하기 위한 옵션을 주기위해 필요하다.

serv_sock=socket(PF_INET, SOCK_STREAM,0);


if(serv_sock == -1)

error_handling("socket() error");

이걸로 서버 소켓을 만든다. 소켓은 IPv4, 스트림소켓이다.(인터넷을 사용하고, 서버-클라이언트가 항상 연결되는 소켓)

memset(&serv_addr,0,sizeof(serv_addr));

serv_addr.sin_family = AF_INET;

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

serv_addr.sin_port = htons(atoi(default_PT));

sockOpt = 1;

setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &sockOpt, sizeof(sockOpt));

if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1)

{

error_handling("bind() error");

}


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

{

error_handling("listen() error");

}

일단 서버의 주소를 넣을 구조체를 비운다음에, 주소체계를 IPv4인터넷 프로토콜 방식으로 하자.
주소는 INADDR_ANY로 하여, 모든 주소에서 접속을 받기로 하고, port는 미리 지정된 포트를 사용한다.
REUSEADDR옵션을 켜서 이 포트를 다시 사용할 수 있도록 하여, bind에서 엄한 에러가 안나도록 하였다.
bind를 하고, listen을 하여, 클라이언트의 접속을 기다린다.
접속이 되면

addr_size=sizeof(clnt_addr);

clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr,&addr_size);


if(clnt_sock == -1)

{

exit(0);

}

이렇게, 접속을 수락하고, 

if((str_len=recv(clnt_sock, message, BUFSIZE, 0))>0)

{

int i;

message[str_len]=0;

if(message[0]!=0)

{

long long t = atoll(message);

char buf[MAX] = {0,};

long long k = 1;

long long i;

for(i=1; i<=t; i++) k*=i;

lltoa(k, buf);

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

if(write(clnt_sock, buf, sizeof(buf)) <= 0)

{

perror("write error : ");

exit(1);

}

else

{

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

}

}

}

puts("connect end");

close(clnt_sock);

클라이언트 소켓에서 recv로 수신한 메세지를 message변수에 저장하고 그 길이를 str_len에 저장한다.

메세지가 수신되었다면 그 문자열을 숫자로 변환하고, 그 숫자의 factorial을 구한다.

그후, 문자열로 재변환 한 뒤에, write를 하여 클라이언트에게 전송한다.

2.2 서버프로그램작성

위 프로그램을 기반으로 하여, listen이 된 경우 fork를 하여, 부모 프로세스는 다시 listen으로 돌아가고, 자식프로세스는 accept를 하여

위와 유사한 작업을 한다. 

2.3 서버프로그램과 응용프로그램 연동

서버의 자식프로세스에서, ssh를 이용하여 응용프로그램을 실행한다. 그후 서버에서 응용프로그램의 포트로 소켓을 열어 접속을 한다.

그다음 서버에게 온 입력값을 응용프로그램에 투척하고, 응용프로그램이 처리한뒤 전달된 결과값을 다시 클라이언트에게 던져준다.