6장 비연결형 지향 프로토콜 Database Lab 강 우 석
목 차 통신 방법 데이터그램의 입력/출력 실행 UDP 데이터그램 서버 작성 UDP 데이터그램 클라이언트 작성 데이터그램 클라이언트와 서버 테스트
통신 방법 목차 통신 방법 비연결형의 장점 비연결형의 단점
통신 방법 [계속] 통신 방법 연결형 방법 비연결형 방법 Client Server Client Server 연결 설정 요구 연결 설정 승인 데이터 전송 Client Server Client Server 데이터 전송
통신 방법 [계속] Client Server 연결형 Socket() Socket() bind() connect() 연결요청 Listen() accept() recv() send() 데이터 송수신 send() recv() 종료 close()
통신 방법 [계속] Client Server 비연결형 Socket() Socket() bind() sendto() recvfrom() 데이터 송수신 recvfrom() sendto() 종료 close()
통신 방법 [계속] 장점 간단함 유연함 능률적 신속함 브로드캐스트
통신 방법 [계속] 단점 신뢰성이 떨어짐 다수의 데이터그램의 연속성이 없음 메시지 크기 제한
데이터그램의 입력/출력 실행 목차 sendto(2) 함수 소개 recvfrom(2) 함수 소개
데이터그램의 입력/출력 실행 [계속] 관련 함수 소켓의 입출력 부분 데이터그램 전송시 Read(2) Write(2) Sendto() Recvfrom()
데이터그램의 입력/출력 실행 [계속] Sendto() 역할 구조 데이터그램 기록 수신자의 목적 주소 명시 #include <sys/types.h> #include <sys/socket.h> Int sendto( int s, Const void *msg, Int len, Unsigned flags, Const struct sockaddr *to, Int tolen);
데이터그램의 입력/출력 실행 [계속] flag 인수 값 Flag 16 진수 의 미 0x0000 MSG_OOB 0x0001 의 미 0x0000 정상-특정 옵션 없음 MSG_OOB 0x0001 밴드 외의 데이터 처리 MSG_DONTROUTE 0x0004 라우팅 무시[직접 인터페이스 사용] MSG_DONTWAIT 0x0040 블록 아님[ 기록 대기 ] MSG_NOSIGNAL 0x4000 다른 종점이 접속해지 되었을때 sigpipe 상승
데이터그램의 입력/출력 실행 [계속] recvfrom() 역할 구조 Sendto()와 쌍을 이룸 송신자의 주소 획득 #include <sys/types.h> #include <sys/socket.h> Int recvfrom( int s, void *buf, Int len, Unsigned flags, struct sockaddr *from, Int *fromlen);
데이터그램의 입력/출력 실행 [계속] flag 인수 값 Flag 16 진수 의 미 0x0000 MSG_OOB 0x0001 의 미 0x0000 정상 MSG_OOB 0x0001 영역 외의 데이터 처리 MSG_PEEK 0x0002 커널 수신큐로부터 삭제없이 읽음 MSG_WAITALL 0x0100 요구를 만족할 때까지 연산 블록 요구 MSG_ERRQUEUE 0x2000 에러큐로부터 패킷 수신 MSG_NOSIGNAL 0x4000 다른 종점이 연결 해지될때 스트림 소켓을 위한 SIGPIPE 상승 억제
UDP 데이터그램 서버 작성 예제 6.1[dgramsrvr.c] 초기화 소켓 생성/주소 생성 주소 결합 대 기 수신/응답 종료 Socket() 주소 결합 Bind() for 대 기 수신/응답 종료
UDP 데이터그램 서버 작성[계속] 초기화 Int main(int argc,char **argv) { int z; char *srvr_addr = NULL; struct sockaddr_in adr_inet;/* AF_INET */ struct sockaddr_in adr_clnt;/* AF_INET */ int len_inet; /* length */ int s; /* Socket */ char dgram[512]; /* Recv buffer */ char dtfmt[512]; /* Date/Time Result */ time_t td; /* Current Time and Date */ 0 struct tm tm; /* Date time values */ if ( argc >= 2 ) { /* Addr on cmdline: */ srvr_addr = argv[1]; } else { /* Use default address: */ srvr_addr = "127.0.0.23"; }
UDP 데이터그램 서버 작성[계속] 소켓 생성 주소 생성 s = socket(AF_INET,SOCK_DGRAM,0); if ( s == -1 ) bail("socket()"); memset(&adr_inet,0,sizeof adr_inet); adr_inet.sin_family = AF_INET; adr_inet.sin_port = htons(9090); adr_inet.sin_addr.s_addr = inet_addr(srvr_addr); if ( adr_inet.sin_addr.s_addr == INADDR_NONE ) bail("bad address."); len_inet = sizeof adr_inet;
UDP 데이터그램 서버 작성[계속] 주소 결합 대기 z = bind(s, (struct sockaddr *)&adr_inet, len_inet); if ( z == -1 ) bail("bind()"); for (;;) { } close(s); return 0;
UDP 데이터그램 서버 작성[계속] 수신 len_inet = sizeof adr_clnt; z = recvfrom(s, /* Socket */ dgram, /* Receiving buffer */ sizeof dgram, /* Max recv buf size */ 0, /* Flags: no options */ (struct sockaddr *)&adr_clnt,/* Addr */ &len_inet); /* Addr len, in & out */ if ( z < 0 ) bail("recvfrom(2)");
UDP 데이터그램 서버 작성[계속] 응답 요청 처리 dgram[z] = 0; /* null terminate */ if ( !strcasecmp(dgram,"QUIT") ) break; /* Quit server */ time(&td); /* Get current time & date */ tm = *localtime(&td); strftime(dtfmt, /* Formatted result */ sizeof dtfmt, /* Max result size */ dgram, /* Input date/time format */ &tm);
UDP 데이터그램 서버 작성[계속] 메시지 송신 z = sendto(s, /* Socket to send result */ dtfmt, /* The datagram result to snd */ strlen(dtfmt), /* The datagram lngth */ 0, /* Flags: no options */ (struct sockaddr *)&adr_clnt, /* addr */ len_inet); /* Client address length */ if ( z < 0 ) bail("sendto(2)");
UDP 데이터그램 서버 작성[계속] 서버 프로그램 실행 방법 백그라운드로 실행 다른 IP로 실행 $./dgramsrvr & [1] 4339 $./dgramsrvr 192.168.0.1 & [1] 4341
UDP 데이터그램 클라이언트 작성 예제 6.2[dgramclnt .c] 초기화 주소 생성/소켓 생성 메시지 전송 사용자 입력 주소 생성/소켓 생성 사용자 입력 메시지 전송 결과 출력 메시지 수신 fputs Socket() sendto recvfrom
UDP 데이터그램 클라이언트 작성[계속] 초기화 Int main(int argc,char **argv) { int z; int x; char *srvr_addr = NULL; struct sockaddr_in adr_srvr; /* AF_INET */ struct sockaddr_in adr; /* AF_INET */ int len_inet; /* length */ int s; /* Socket */ char dgram[512]; if ( argc >= 2 ) { /* Addr on cmdline: */ srvr_addr = argv[1]; } else { /* Use default address: */ srvr_addr = "127.0.0.23";
UDP 데이터그램 클라이언트 작성[계속] 주소 생성 소켓 생성 memset(&adr_srvr,0,sizeof adr_srvr); adr_srvr.sin_family = AF_INET; adr_srvr.sin_port = htons(9090); adr_srvr.sin_addr.s_addr = inet_addr(srvr_addr); if ( adr_srvr.sin_addr.s_addr == INADDR_NONE ) bail("bad address."); len_inet = sizeof adr_srvr; s = socket(AF_INET,SOCK_DGRAM,0); if ( s == -1 ) bail("socket()");
UDP 데이터그램 클라이언트 작성[계속] 사용자 입력 메시지 전송 fputs("\nEnter format string: ",stdout); if ( !fgets(dgram,sizeof dgram,stdin) ) break; /* EOF */ z = strlen(dgram); if ( z > 0 && dgram[--z] == '\n' ) dgram[z] = 0; z = sendto(s, /* Socket to send result */ dgram, /* The datagram result to snd */ strlen(dgram), /* The datagram lngth */ 0, /* Flags: no options */ (struct sockaddr *)&adr_srvr,/* addr */ len_inet); /* Server address length */ if ( z < 0 ) bail("sendto(2)"); if ( !strcasecmp(dgram,"QUIT") ) break;
UDP 데이터그램 클라이언트 작성[계속] 메시지 수신 결과 출력 x = sizeof adr; z = recvfrom(s, /* Socket */ dgram, /* Receiving buffer */ sizeof dgram, /* Max recv buf size */ 0, /* Flags: no options */ (struct sockaddr *)&adr, /* Addr */ &x); /* Addr len, in & out */ if ( z < 0 ) bail("recvfrom(2)"); dgram[z] = 0; printf("Result from %s port %u :\n\t'%s'\n", inet_ntoa(adr.sin_addr), (unsigned)ntohs(adr.sin_port), dgram);
데이터그램 클라이언트와 서버 테스트 목차 서버 없이 테스트 다른 IP 주소를 통한 테스트 클라이언트 프로그램에서 bind(2) 함수 생략 Wild 주소의 응답
데이터그램 클라이언트와 서버 테스트 테스트 방법 서버 프로그램 시작 클라이언트 프로그램 시작 클라이언트 프로그램에 입력값 입력 클라이언트 프로그램에 “Ctrl+D”, “QUIT” 입력
데이터그램 클라이언트와 서버 테스트 서버 실행 방법 클라이언트 실행 방법 $./dgramsrvr & [1] 4405 $./dgramclnt Enter format string :
데이터그램 클라이언트와 서버 테스트 서버 없는 테스트 $./dgramclnt Enter format string : %D Connection refused : recvfrom(2) $
데이터그램 클라이언트와 서버 테스트 다른 IP 주소로 테스트 서버 실행 [ 192.168.0.1 ] 클라이언트 실행 [ 192.168.0.2 ] $./dgramsrvr 192.168.0.1 & [1] 4416 $./dgramclnt 192.168.0.1 Enter format string : %D Result from 192.168.0.1 port 9090: ’08/13/99’ Enter format string : QUIT $
데이터그램 클라이언트와 서버 테스트 Wild 주소의 적용 printf(3) 구문의 추가 Prinft(“Client from %s port %u;\n, inet_ntoa(adr_clnt.sin_addr), (unsigned)ntohs(adr_clnt.sin_port));
요약