2014년 12월 8일 월요일

TCP/IP 소켓 프로그래밍 4강

본격적으로 4강에서는 TCP를 이용해서 통신해보자
먼저 TCP/IP의 구조를 알아야하게 않겠는가??
보통은 세세하게 7단계로 네트워크를 구분해 놓는다.
컴퓨터 관련 자격증에 항상 나오는 것이니(아직까지 내 경험엔..;;) 외워두자
이 책에서는

응용 -> TCP/UDP -> IP -> LINK

로 간단하게 구분해 놨다.

다음은 TCP/IP 프로토콜 탄생 배경인데.........
귀찮으니 걍 검색해서 보자.(보는 사람도 없는데 뭐 ㅡㅜ)

TCP 방식의 서버 쪽 흐름을 간략하게 보자

소켓 생성->소켓 주소할당->연결요청 대기상태->연결허용->데이터 송수신->연결종료

이 순으로 만들어 볼꺼다.
서버는 "연결요청 대기상태"가 있다. 이걸 대기 시킨다는 것은 클라이언트가 연결요청을 수락할 때까지 연결요청 자체를 기다리게 하는 곳이 있다는 것이다.
이것을 우아하게(?) 표현하면 "연결요청 대기 큐"라고 한다

소스코드를 보자.(일부분만 볼꺼다)

int main(int argc, char *argv[])
{
int serv_sock, clnt_sock;
char message[BUF_SIZE];
int str_len, i;

struct sockaddr_in serv_adr;
struct sockaddr_in clnt_adr;
socklen_t clnt_adr_sz;

if(argc!=2) {
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
//소켓생성
serv_sock=socket(PF_INET, SOCK_STREAM, 0);   
if(serv_sock==-1)
error_handling("socket() error");
//구조체 변수 초기화
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_adr.sin_port=htons(atoi(argv[1]));
     
       //소켓 주소 할당
if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
error_handling("bind() error");

         //연결요청 대기상태(5번의 클라이언트 연결 요청을 받을 수 있다)
if(listen(serv_sock, 5)==-1)
error_handling("listen() error");

clnt_adr_sz=sizeof(clnt_adr);

for(i=0; i<5; i++)
{
                 //연결허용하고 에러처리까지 한다.
clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
if(clnt_sock==-1)
error_handling("accept() error");
else
printf("Connected client %d \n", i+1);
         //데이터 송수신
while((str_len=read(clnt_sock, message, BUF_SIZE))!=0)
write(clnt_sock, message, str_len);
                //현재 접속되어 있는 클라이언트 소켓 연결 종료
close(clnt_sock);
}
        //서버측 소켓 연결 종료
close(serv_sock);
return 0;
}

눈에 확 띄게 색깔로 구분해놨다.이번에는 클라이언트 쪽 소스를 보자
int main(int argc, char *argv[])
{
int sock;
char message[BUF_SIZE];
int str_len;
struct sockaddr_in serv_adr;

if(argc!=3) {
printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
//소켓생성 , 에러처리
sock=socket(PF_INET, SOCK_STREAM, 0);   
if(sock==-1)
error_handling("socket() error");
//IP/PORT 정보 초기화
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=inet_addr(argv[1]);
serv_adr.sin_port=htons(atoi(argv[2]));
//서버로 연결요청, 에러처리
if(connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
error_handling("connect() error!");
else
puts("Connected...........");

while(1)
{
fputs("Input message(Q to quit): ", stdout);
fgets(message, BUF_SIZE, stdin);
//Q,q를 입력하면 접속이 종료된다
if(!strcmp(message,"q\n") || !strcmp(message,"Q\n"))
break;
                //서버에 송신하기
write(sock, message, strlen(message));
                //서버에 수신하기
str_len=read(sock, message, BUF_SIZE-1);
message[str_len]=0;
printf("Message from server: %s", message);
}

close(sock);
return 0;
}

역시 자세한 사항은 소스코드를 다운 받아 보고 직접 해봐야 한다
지금 설명하는 것은 전부 리눅스 기준이다.
윈도우는 19강에서나 본격적으로 할 것이다.

댓글 없음:

댓글 쓰기