230 likes | 407 Views
DK Han dkhan@mmlab.snu.ac.kr Junghwan Song jhsong@mmlab.snu.ac.kr 2011-04-23 Multimedia & Mobile Communications Lab. Socket 4. Outline. TCP vs. UDP Multicast Broadcast Practice. TCP/IP Protocol Stack. 인터넷 기반의 데이터 송수신을 목적으로 설계된 스택 큰 문제를 작게 나눠서 계층화한 결과.
E N D
DK Han dkhan@mmlab.snu.ac.kr Junghwan Song jhsong@mmlab.snu.ac.kr 2011-04-23 Multimedia & Mobile Communications Lab. Socket 4
Outline • TCP vs. UDP • Multicast • Broadcast • Practice
TCP/IP Protocol Stack • 인터넷 기반의 데이터 송수신을 목적으로 설계된 스택 • 큰 문제를 작게 나눠서 계층화한 결과
UDP • UDP 소켓 • TCP는 1대1의 연결을 필요로 하지만, UDP는 연결의 개념이 없음 • 서버 소켓과 클라이언트 소켓의 구분이 없음 • 하나의 소켓으로 둘 이상의 영역과 데이터 송수신이 가능
UDP • UDP 소켓 • sendto함수
UDP • UDP 소켓 • recvfrom함수
Multicast • 멀티캐스트 • 멀티캐스트 서버는 특정 멀티캐스트 그룹을 대상으로 데이터를 딱 한번 전송 • 딱 한번 정송하더라도 그룹에 속하는 클라이언트는 모두 데이터를 수신 • 멀티캐스트 그룹의 수는 IP주소 범위 내에서 얼마든지 추가가 가능 • 특정 멀티캐스트 그룹으로 전송되는 데이터를 수신하려면 해당 그룹에 가입 • 멀티캐스트는 연결의 개념이 없음 • UDP 소켓 기반
Multicast • TTL(Time To Live) • 패킷을 얼마나 멀리 보낼 것인가를 결정 • TTL은 정수로 표현 • 라우터를 하나 지날 때마다 1씩 감소 • TTL이 0이 되면, 해당 패킷은 소멸
Multicast • TTL(Time To Live) • 멀티캐스트를 위한 TTL설정 • setsockopt함수 사용 • TTL설정과 관련된 프로토콜의 레벨은 IPPROTO_IP • 옵션의 이름은 IP_MULTICAST_TTL
Multicast • 그룹가입방법 • 소켓 옵션정보 변경을 통해 가능 • 프로토콜 레벨은 IPPROTO_IP • 옵션의 이름은 IP_ADD_MEMBERSHIP
Multicast • 그룹가입방법 • Multicast address
Broadcast • 브로드캐스트 • 동일한 네트워크 내에 존재하는 호스트에게 데이터를 전송하는 방법 • 데이터 전송의 대상이 호스트가 아닌 네트워크임 • 멀티캐스트와 마찬가지로 UDP소켓 기반 • Directed Broadcast • IP에서 네트워크 주소를 제외한 호스트 주소를 모두 1로 변경 후 전송 • Local Broadcast • 255.255.255.255로 데이터를 전송하면, 전송한 호스트가 속한 네트워크로 데이터 전송
Broadcast • 브로드캐스트 • 브로드캐스트를 위한 소켓 설정 • SO_BROADCAST 옵션을 1로 변경 • 옵션의 설정, 전송에 사용되는 IP주소 이외에는 일반적인 UDP 코드와 차이없음
Multicast Practice • 멀티캐스트 실습과정 • 1 sender, 2 receiver • 조원과 역할 분담 • Sender가 멀티캐스트 그룹 주소로 news.txt 파일 전송 • UDP 소켓 생성 • 멀티캐스트 그룹에 파일 전송 • Receiver는 멀티캐스트 그룹 가입 후 news.txt 파일 수신 • UDP 소켓 생성 • 멀티캐스트 그룹에 가입 • 파일 수신 • 실습시간 내 구현 • TA에게 확인 후 수업 마침
Multicast Practice • 멀티캐스트 실습과정
<<sender.c>> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #define TTL 64 #define BUF_SIZE 30 void error_handling(char* message); int main(intargc, char* argv[]) { intsend_sock; structsockaddr_inmul_addr; inttime_live = TTL; FILE* fp; char buf[BUF_SIZE]; if(argc != 3) { printf("Usage : %s <Group IP> <PORT>\n", argv[0]); exit(1); } send_sock = socket(PF_INET, SOCK_DGRAM, 0); memset(&mul_addr, 0, sizeof(mul_addr)); mul_addr.sin_family = AF_INET; mul_addr.sin_addr.s_addr = inet_addr(argv[1]); //multicast IP mul_addr.sin_port=htons(atoi(argv[2]));
setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&time_live, sizeof(time_live)); if((fp = fopen("news.txt", "r")) == NULL) { error_handling("fopen() error"); } while(!feof(fp)) { fgets(buf, BUF_SIZE, fp); sendto(send_sock, buf, strlen(buf), 0, (structsockaddr*)&mul_addr, sizeof(mul_addr)); sleep(2); } close(send_sock); return 0; } void error_handling(char* message) { fputs(message, stderr); fputc('\n', stderr); exit(1); }
<<receiver.c>> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #define BUF_SIZE 30 void error_handling(char* message); int main(intargc, char** argv) { intrecv_sock; intstr_len; char buf[BUF_SIZE]; structsockaddr_inaddr; structip_mreqjoin_addr; if(argc != 3) { printf("Usage : %s <GroupIP> <PORT>\n", argv[0]); } recv_sock = socket(PF_INET, SOCK_DGRAM, 0); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(atoi(argv[2]));
if(bind(recv_sock, (structsockaddr*)&addr, sizeof(addr)) == -1) { error_handling("bind() error"); } join_addr.imr_multiaddr.s_addr = inet_addr(argv[1]); join_addr.imr_interface.s_addr = htonl(INADDR_ANY); setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&join_addr, sizeof(join_addr)); while(1) { str_len = recvfrom(recv_sock, buf, BUF_SIZE-1, 0, NULL, 0); if(str_len<0) break; buf[str_len] = 0; fputs(buf, stdout); } close(recv_sock); return 0; } void error_handling(char* message) { fputs(message, stderr); fputc('\n', stderr); exit(1); }