1 목포해양대해양컴퓨터공학과 UDP 소켓 네트워크프로그램설계 4 장
2 목포해양대해양컴퓨터공학과 목차 제 4장 UDP 소켓 4.1 UDP 클라이언트 4.2 UDP 서버 4.3 UDP 소켓을이용한데이터송신및수신 4.4 UDP 소켓의연결
3 목포해양대해양컴퓨터공학과 UDP 소켓의특징 UDP 소켓의특성 신뢰할수없는데이터전송방식 목적지에정확하게전송된다는보장이없음. 별도의처리필요 비연결지향적, 순서바뀌는것이가능 흐름제어 (flow control) 를하지않음 메시지의경계가있다! TCP 는스트림전송으로 send() 와 recv() 의횟수가상호관련이없다 UDP 는데이터그램전송으로메시지의경계가존재하며송신메시지와수신메시지사이의상관관계가존재
4 목포해양대해양컴퓨터공학과 UDP 헤더와 TCP 헤더 UDP 헤더 TCP 헤더
5 목포해양대해양컴퓨터공학과 UDP 서버의특징 (1) TCP와 UDP의공통점 포트번호를이용하여종단 ( 응용 ) 간전송 데이터위변조확인 (checksum 존재 ) 실제로 checksum 확인하는경우는거의없음 TCP 서버의특징 처음생성한소켓은연결만을담당 연결과정에서반환된소켓은데이터송수신을담당 서버쪽의데이터송수신소켓과클라이언트의소켓은 1:1 연결 스트림전송으로전송데이터의크기무제한
6 목포해양대해양컴퓨터공학과 UDP 서버의특징 (2) UDP 서버의특징 UDP 는연결자체가없음 UDP 서버는다수의클라이언트소켓과동시에데이터송수신처리 1 : 1 혹은 1: many 연결 데이터그램 ( 메시지 ) 단위전송이며하나의데이터그램은 65535 바이트크기로제한됨 그이상의크기는잘라서보내야함
7 목포해양대해양컴퓨터공학과 UDP 서버 - 클라이언트전송 프로세스 비연결형전송프로세스 UDP 서버 socket() bind() recvfrom() sendto() close() UDP 클라이언트 socket() sendto() recvfrom() close()
8 목포해양대해양컴퓨터공학과 UDP 소켓생성 용도 : 메시지를상대방에게전송 int socket(int family,int type,int proto); int sock; sock = socket(pf_inet, SOCK_DGRAM,0); if (sock<0) { /* ERROR */ }
9 목포해양대해양컴퓨터공학과 UDP 기반의데이터송수신 함수 (1) ssize_t sendto (int sock, const void *msg, int len, unsigned flags const struct sockaddr *addr, int addrlen) 용도 : 메시지를상대방에게전송 반환값 : 성공시전송된바이트수, 실패시 -1 sock: 소켓의파일디스크립터, UDP 소켓 msg: 전송하고자하는데이터를저장해놓은버퍼 len: 보낼데이터의크기 flags: 옵션 ( 일반적으로 0) addr: 전송하고자하는호스트의소켓주소구조체 addrlen: 소켓주소구조체 (addr) 의크기
UDP 기반의데이터송수신 함수 (2) ssize_t recvfrom (int sock, const void *buf, int len, unsigned flags struct sockaddr *addr, int *addrlen) 용도 : 상대방이전송하여수신버퍼에도착한메시지데이터를메모리에복사 반환값 : 성공시복사된바이트수, 실패시 -1 sock: 데이터를수신할소켓의파일디스크립터, UDP 소켓 buf: 수신할데이터를저장할버퍼 len: 수신할수있는최대바이트수 flags: 옵션 addr: 전송한호스트의소켓주소구조체 addrlen: addr 이가리키는구조체변수의크기 FIFO 버퍼에있는단위정보의크기가 len 보다큰경우, len 까지만반환되고, 읽히지않은나머지정보는버려짐 충분한크기의버퍼준비필요! (UDP 데이터최대크기 65,507) MSG_PEEK 플래그사용가능 10
UDP 메시지의처리 경계가있는메시지 TCP 와는달리 UDP 에서는하나의 sendto() 와하나의 recvfrom 이쌍 (pair) 를이룸 sendto() 와 recvfrom() 호출이서로짝을이루도록순서가맞아야함 Server Client MSG 1 MSG 2 세번에걸쳐메시지전송 세번에메시지수신후세번에메시지전송 MSG 3 MSG 1 MSG 2 MSG 3 세번에걸쳐서 메시지수신 11
UDP Echo 서버예제 (simple) #define BUFSIZE 65507 int main(int argc, char **argv) { int serv_sock; char message[bufsize]; int str_len; struct sockaddr_in serv_addr; struct sockaddr_in clnt_addr; int clnt_addr_size; serv_sock=socket(pf_inet, SOCK_DGRAM, 0); 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(argv[1])); if (bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1) error_handling("bind() error"); while(1) { clnt_addr_size = sizeof(clnt_addr); str_len = recvfrom(serv_sock, message, BUFSIZE, 0, (struct sockaddr*)&clnt_addr, &clnt_addr_size); } sendto(serv_sock, message, str_len, 0, (struct sockaddr*)&clnt_addr, sizeof(clnt_addr)); 12 } close(serv_sock); return 0;
UDP Echo 클라이언트예제 (simple) #define BUFSIZE 65507 int main(int argc, char **argv) { int sock; char message[bufsize]; int str_len, addr_size; struct sockaddr_in serv_addr; struct sockaddr_in from_addr; sock=socket(pf_inet, SOCK_DGRAM, 0); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(argv[1]); serv_addr.sin_port = htons(atoi(argv[2])); while(1) { fgets(message, sizeof(message), stdin); if(!strcmp(message,"q\n")) break; sendto(sock, message, strlen(message), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); addr_size = sizeof(from_addr); str_len = recvfrom(sock, message, BUFSIZE, 0, (struct sockaddr*)&from_addr, &addr_size); message[str_len] = 0; // \0 printf( from server: %s", message); } close(sock); return 0; } 13
sudpechoserver.c (1) 14
sudpechoserver.c (2) 15
sudpechoclient.c (1) 16
sudpechoclient.c (2) 17
교재 Makefile 18
UDP 서버-클라이언트전송프로세스 연결형전송프로세스 사용목적 : 사용편의, 송수신성능향상 이전행위에대한오류확인가능 UDP 서버 socket() UDP 클라이언트 socket() bind() connect() recvfrom() send() sendto() close() recv() close() 19
응용과제 2 장과제개선 2 와같이사용자입력을계속받아전달하도록개선 동시에여러클라이언트를동작하여서버동작확인 서버화면캡처 20