Transcript 1 - MMLab
Socket 4
DK Han
Junghwan Song
[email protected]
[email protected]
2011-04-23
Multimedia & Mobile Communications Lab.
Outline
TCP vs. UDP
Multicast
Broadcast
Practice
TCP/IP Protocol Stack
인터넷 기반의 데이터 송수신을 목적으로 설계된 스택
큰 문제를 작게 나눠서 계층화한 결과
TCP vs UDP
TCP vs UDP
구분
TCP
UDP
신뢰성
Reliable
신뢰성을 위해 Ack,
Checksum 사용
Unreliable
연결성
Connection-Oriented
Connection이후 통신 가능
Connectionless
Connection 과정 없음
재전송
재전송 요청함
Error 및 Packet Loss 탐지
재전송 없음
특징
Flow control을 위해 Window
사용
고속데이터 전송 가능
용도
신뢰성이 필요한 통신
파일전송, 대부분의 APP.
총 패킷수가 적은 통신
동영상 및 음성 등 멀티미디어
통신
UDP
UDP 소켓
TCP는 1대1의 연결을 필요로 하지만, UDP는 연결의
개념이 없음
서버 소켓과 클라이언트 소켓의 구분이 없음
하나의 소켓으로 둘 이상의 영역과 데이터 송수신이 가능
UDP
UDP 소켓
sendto 함수
UDP
UDP 소켓
recvfrom함수
Multicast
멀티캐스트
멀티캐스트 서버는 특정 멀티캐스트 그룹을 대상으로
데이터를 딱 한번 전송
딱 한번 정송하더라도 그룹에 속하는 클라이언트는 모두
데이터를 수신
멀티캐스트 그룹의 수는 IP주소 범위 내에서 얼마든지
추가가 가능
특정 멀티캐스트 그룹으로 전송되는 데이터를 수신하려면
해당 그룹에 가입
멀티캐스트는 연결의 개념이 없음
•
UDP 소켓 기반
Multicast
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
멀티캐스트 실습과정
Team
Multicast IP address
1조
224.1.1.2
2조
224.1.1.3
3조
224.1.1.4
4조
224.1.1.5
5조
224.1.1.6
<<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(int argc, char* argv[])
{
int send_sock;
struct sockaddr_in mul_addr;
int time_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, (struct sockaddr*)&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(int argc, char** argv)
{
int recv_sock;
int str_len;
char buf[BUF_SIZE];
struct sockaddr_in addr;
struct ip_mreq join_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, (struct sockaddr*)&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);
}
APPENDIX : setsockopt