1 / 43

TCP/IP Network Experimental Programming [Socket]

TCP/IP Network Experimental Programming [Socket]. cheol-joo chae cjchae@netwk.hannam.ac.kr. 목차. 소켓의 개요 소켓에서 사용되는 구조체 소켓 시스템 콜에 따른 처리의 흐름 소켓 시스템 콜 UDP 에 의한 통신 TCP 에 의한 통신. socket() 소켓을 연다 close() 소켓을 닫는다. bind() 자신의 호스트 IP 주소 포트 번호 설정 listen() connection 의 수취 개시

novia
Download Presentation

TCP/IP Network Experimental Programming [Socket]

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. TCP/IP Network Experimental Programming [Socket] cheol-joo chae cjchae@netwk.hannam.ac.kr

  2. 목차 • 소켓의 개요 • 소켓에서 사용되는 구조체 • 소켓 시스템 콜에 따른 처리의 흐름 • 소켓 시스템 콜 • UDP에 의한 통신 • TCP에 의한 통신

  3. socket() 소켓을 연다 close() 소켓을 닫는다 bind() 자신의 호스트 IP 주소 포트 번호 설정 listen() connection의 수취 개시 connect() connection 확립 요구(자신의 호스트 IP 주소, 포트 번호 설정) accept() 받은 connection에 소켓 작성 recv() 메시지의 수신 recvfrom() 메시지의 수신 send() 메시지의 송신 sendto() 메시지의 송신 select() 입출력의 다양화 소켓의 개요 • 소켓 • 애플리케이션 프로그램에서 네트워크 통신 서비스를 받을 때의 API • 주요 시스템 콜

  4. gethostbyname() 도메인 명에서 IP 주소를 획득 gethostbyaddr() IP 주소에서 도메인 명을 취득 getservbyname() 키워드에서 포트 번호를 취득 getservbyaddr() 포트 번호에서 키워드를 취득 inet_addr() 문자열에서 나타난 IP 주소를 구조체로 변환 iInet_nota() IP 주소 구조체를 문자열로 변환 htonl() 네트워크 바이트 오더로 변환(long) htons() 네트워크 바이트 오더로 변환(short) htohl() 호스트 바이트 오더로 변환(long) htons() 호스트 바이트 오더로 변환(short) 소켓의 개요 • 소켓 라이브러리 함수

  5. s_addr 구조체 IP 주소를 포함 sockaddr 구조체 소켓 주소를 포함하는 구조체의 모형 sockaddr_in 구조체 IP 주소와 포트 번호를 포함 servent 구조체 서비스의 정보를 포함 소켓의 개요 • 소켓 구조체

  6. 소켓에서 사용되는 구조체 • BSD에서의 sockaddr_in 구조체 • BSD에서의 sockaddr 구조체 struct sockaddr_in { u_char sin_len; u_char sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; struct sockaddr { u_char sa_len; /*total length*/ sa_family_t sa_family; /*address family*/ char sa_data[14] /*actually longer; address value*/ };

  7. sa_data 어드레스 데이터 sa_len 구조체 길이 sa_family 어드레스 패밀리 sa_data 어드레스 데이터 sa_len 구조체 길이 sa_family 어드레스 패밀리 sin_port 포트 번호 sin_zero 미사용 소켓에서 사용되는 구조체 • sockaddr 구조체와 sockaddr_in 구조체 • Sockaddr이 기존 구조체이며 TCP/IP 주소 형식으로 만든것이 sockaddr_in sockaddr 구조체 sockaddr_in 구조체

  8. 소켓 시스템 콜에 따른 처리의 흐름 • UDP에 의한 통신의 경우

  9. 소켓 시스템 콜에 따른 처리의 흐름 • 연결과정 • 서버측에서 • socket 시스템 콜을 사용하여 UDP와 어플리케이션 사이에 통신로가 되는 소켓을 오픈 • bind 시스템 콜을 사용하는 포트 번호를 지정하여 서버 프로그램을 작동 • recvfrom 시스템 콜을 사용하여 클라이언트의 요청을 수신 • 클라이언트측에서 • socket 시스템 콜을 사용하여 UDP와 어플리케이션 사이의 통신로가 되는 소켓을 오픈 • bind 시스템 콜에서 자신이 사용하는 포트 번호를 결정 • 특정 포트 번호를 할당할 수도 있지만 운영체제가 자동으로 할당하는 것이 일반적인 방법 • 여기서는 포트번호를 0으로 설정하고 bind 시스템 콜을 실행

  10. 소켓 시스템 콜에 따른 처리의 흐름 • 클라이언트 프로그램이 sendto 시스템 콜에서 메시지를 소켓에 연결 • IP 주소나 포트번호는 sendto의 인수로서 전달되는데 운영체제 내부에서는 인수로 전달된 주소를 근거로 해서 UDP나 IP 헤더에서 만들어진 패킷을 서버에 전송 • 서버에서는 수취한 패킷의 헤더를 해석해 지정된 포트 번호의 패킷 수신 큐에 메시지를 포함시킴 • 서버는 recvfrom을 실행하고 애플리케이션에 메시지를 전송 • 서버 프로그램은 recvfrom 시스템 콜의 인수에서 수신한 메시지에서 송신자의 IP 주소와 포트 번호를 알 수 있음 • 응답 메시지를 주고받을 때에는 recvfrom 시스템 콜을 습득한 IP주소와 포트 번호를 사용해서 sendto 시스템 콜을 호출함 • 클라이언트는 서버에서 응답한 메시지를 recvfrom 시스템 콜로 수신 • UDP에서는 recvfrom에서 얻은 주소를 사용해서 connect 시스템 콜을 실행하여 소켓에서 송수신 가능한 상대의 IP 주소와 포트번호를 고정하는 것이 가능

  11. 소켓 시스템 콜에 따른 처리의 흐름 • TCP에 의한 통신의 경우

  12. 소켓 시스템 콜에 따른 처리의 흐름 • 연결과정 • 서버측에서 • socket 시스템 콜을 사용하여 TCP모듈과 어플리케이션 사이에 통신로가 되는 소켓을 생성 • bind 시스템 콜을 사용하는 포트 번호를 지정 • listen 시스템 콜에서 커넥션 받는 큐의 길이를 지정해 클라이언트의 커넥션 접속 요구를 기다림 • 커넥션이 이루어지면 새로운 소켓이 작성되도록 accet 시스템 콜을 실행하여 새로운 소켓이 만들어지는 것을 기다림 • 클라이언트측에서 • socket 시스템 콜을 사용하여 TCP와 어플리케이션 사이의 통신로를 개설 • Connect 시스템 콜에서 서버의 IP 주소와 포트 번호를 지정해서 TCP의 커넥션 연결을 요구

  13. 소켓 시스템 콜에 따른 처리의 흐름 • 커넥션이 이루어지면 send, recv 시스템 콜을 사용하여 메시지의 송신과 수신이 가능하며 커넥션을 끊을 때에는 close 시스켐 콜을 사용 • 서버측에서는 커넥션을 수신하기 위한 소켓과 실제 메시지를 송수신하기 위한 2 종류의 소켓을 사용 • 클라이언에서는 포트 번호를 지정하는 것이 가능하지만 일반적으로 운영 체제에서 자동으로 할당 받음

  14. 소켓 시스템 콜 • 프로토콜의 선택과 어드레스 지정 • domain : 어드레스 페밀리(프로토콜 패밀리)를 지정 • 어드레스 페밀리란 사용할 어드레스 체계를 의미 • AF_INET : IP 어드레스와 포트 번호로구성되는 어드레스 체계 • PF_INET : TCP/IP 프로토콜 체계를 의미 • type : 사용할 프로토콜을 지정 • TCP를 사용할 경우 SOCK_STREAM, UDP를 사용할 경우 SOCK_DGRAM, raw IP를 사용할 경우 SOCK_RAW #include <sys/types.h> #include <sys/socket.h> int socket (int domain, int type, int protocol) ; 0 TCP/IP를 사용하는 경우에는 0을 입력 SOCK_SREAM TCP를 사용하는 경우 SOCK_DGRAM UDP를 사용하는 경우 AF_INET PF_INET

  15. 0 8 16 31 sin_len 구조체 길이 sin_family 어드레스 패밀리 sin_prot 포트 번호 sin_addr IP 어드레스 sin_zrro 미사용 소켓 시스템 콜 • protocol : 사용하는 프로토콜을 지정 • TCP, UDP 통신일 경우 type을 지정한 프로토콜이 정해지도록 default를 의미하는 0을 지정 • IP 어드레스와 포트 번호 지정 • bind 시스템 콜을 사용 #include <sys/types.h> #include <sys/socket.h> int bind (int s, struct sockaddr *my_addr, socklen_t addrlen); 구조체의 크기 socket의 리턴 값을 저장

  16. 소켓 시스템 콜 • s : socket 리턴값 • my_addr : 자신의 IP 어드레스와 포트 번호를 지정 • 포트 번호 지정에는 sockaddr_in 구조체를 사용 • my_addr.sin_family : AF_INET • my_addr.sin_port : 포트 번호 • my_addr.sin_addr : IP 어드레스 지정 • 리눅스에서는 sin_len이 존재하지 않으므로 my_addr.sin_len은 지정하지 않음 • 운영체제에서 포트 번호를 설정하는 경우에는 sin_port를 0으로 지정 • IP 어드레스를 지정하지 않을 경우에는 INADDR_ANY를 입력 • Bind 리턴 값이 성공했을 경우 0, 에러가 발생했을 경우 -1 • IP 어드레스를 INADDR_ANY로 지정한 경우 호스트나 루트에 모든 IP 어드레스에서 패킷을 요구함 • 호스트에는 NIC의 IP 어드레스와 루프백 IP 어드레스(127.0.0.1)이 추가 • 루트인 경우에는 복수의 IP 어드레스가 추가 • addrlen : 구조체의 my_addr 크기를 지정 • 소켓 사용의 종료시에는 close 시스템 콜을 사용

  17. 0 8 16 31 sin_len 구조체 길이 sin_family 어드레스 패밀리 sin_prot 포트 번호 sin_addr IP 어드레스 sin_zrro 미사용 소켓 시스템 콜 • 커넥션리스 • UDP인 경우 connect 시스템 콜을 사용하지 않은 경우 커넥션리스형 함수가 되고 사용할 경우 커넥션 지향형 함수를 사용 • 메시지 송수신에는 sendto 시스템 콜과 recvfrom 시스템 콜을 사용 #include <sys/types.h> #include <sys/socket.h> int sendto (int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); 플래그 수신메시지의 길이 구조체의 크기 소켓의 리턴 값 송신 메시지

  18. 소켓 시스템 콜 • s : socket 리턴값 • msg : 송신 메시지가 포함되어 있는 메모리의선두 어드레스를 지정 • len : 소신 메시지의 바이트 수를 지정 • to : 마지막 IP 어드레스와 포트 번호를 지정 • tolen : 구조체 to의 크기가 몇 바이트인가를 지정 • flags : 일반적으로 0을 지정 • sendto 시스템 콜의 리턴값은 송신가능한 메시지의 바이트 수 • 즉, 애플리케이션에서 소켓 모듈로 흘러간 바이트 수 • 에러시 -1을 리턴 • 0바이트의 데이터를 송신할 경우 0을 리턴

  19. 0 8 16 31 sin_len 구조체 길이 sin_family 어드레스 패밀리 sin_prot 포트 번호 sin_addr IP 어드레스 sin_zrro 미사용 소켓 시스템 콜 • s : socket 리턴값 • buf : 수신 메시지가 포함되어 있는 버퍼의 선두 어드레스를 지정 • len : buf에 포함 가능한 최대의 바이트 수를 지정 • from : 수신한 패킷의 처음 IP 어드레스와 처음 포트 번호를 포함 #include <sys/types.h> #include <sys/socket.h> int recvfrom (int s, const void *buf, size_t len, int flags, struct sockaddr *from, socklen_t fromlen); 플래그 수신메시지의 길이 구조체의 크기 소켓의 리턴 값 송신 메시지

  20. 소켓 시스템 콜 • fromlen : 구조체 from의 크기가 몇 바이트인가를 포함 • flags : 일반적으로 0을 지정 • recvfrom 시스템 콜의 리턴 값은 수신한 메시지의 바이트 수 • 에러가 발생한 경우 -1을 리턴 • sendto에서 0바이트의 메시지가 보내진 경우 0을 리턴

  21. 0 8 16 31 sin_len 구조체 길이 sin_family 어드레스 패밀리 sin_prot 포트 번호 sin_addr IP 어드레스 sin_zrro 미사용 소켓 시스템 콜 • 커넥션 지향 • TCP 통신을 할 경우 커넥션을 확립하는 작업이 필요 • 통신상대의 IP 어드레스를 지정(고정)할때 connect 시스템 콜을 사용 • TCP인 경우 자동적으로 커넥션 관리를 위한 제어를 함 • UDP인 경우 seonto, recvfrom 대신 send, recv를 사용하여 통신 #include <sys/types.h> #include <sys/socket.h> int connect (int s, const struct sockaddr *addr, socklen_t addrlen); 구조체의 크기 socket의 리턴 값을 저장

  22. 소켓 시스템 콜 • s : socket 리턴값 • addr : 통신 상대의 IP 어드레스와 포트 번호를 지정 • addrlen : addr 구조체의 크기가 몇 바이트인가를 지정 • 서버가 TCP 커넥션을 요구하는 경우 listen 시스템 콜을 실행 • s : socket 리턴값 • backlog : 큐의 길이를 지정 • listen의 리턴 값이 올바를 경우 0, 에러 발생시에는 -1을 표시 #include <sys/socket.h> int listen (int s, int backlog); 커넥션 수취 큐의 길이 socket의 리턴 값

  23. 0 8 16 31 sin_len 구조체 길이 sin_family 어드레스 패밀리 sin_prot 포트 번호 sin_addr IP 어드레스 sin_zrro 미사용 소켓 시스템 콜 • 서버에서 클라이언트의 커넥션 요구를 받아들일 때 accpet 시스템 콜을 실행 • s : socket 리턴값 • addr : 자신의 IP 어드레스와 포트 번호를 지정 • addrlen : addr 구조체의 크기가 몇 바이트인가를 지정 #include <sys/types.h> #include <sys/socket.h> int accept (int s, struct sockaddr *addr, socklen_t *addrlen); 구조체의 크기 socket의 리턴 값을 저장

  24. 소켓 시스템 콜 • 커넥션이 이루어지면 send, recv를 사용하여 메시지 송수신을 처리 • s : socket 리턴값 • msg : 송신하는 메시지가 포함되어 있는 메모리의 처음 어드레스를 지정 • len : 송신하는 메시지의 바이트 수를 지정 • flags : 일반적으로 0을 입력 #include <sys/types.h> #include <sys/socket.h> int send (int s, const void *msg, size_t len, int flags); 플래그 송신 메시지 송신 메시지의 길이 accept의 리턴값 또는 socket의 리턴 값에 connect 한 것

  25. 소켓 시스템 콜 #include <sys/types.h> #include <sys/socket.h> int recv (int s, void *buf, size_t len, int flags); • s : socket 리턴값 • buf : 수신하는 메시지가 포함되어 있는 버퍼의 처음 어드레스를 지정 • len : 버퍼에 포함 가능한 바이트 수를 지정 • flags : 일반적으로 0을 입력 • 리턴값은 수신한 메시지으 바이트 수이고 에러 발생시 -1 리턴 플래그 수신 버퍼의 길이 수신 버퍼 accept의 리턴값 또는 socket의 리턴 값에 connect 한 것

  26. 소켓 시스템 콜 • 소켓 옵션 • setsockopt • 애플리케이션에서 소켓의 설정을 변경하기 위해 사용 • 2.7.6절에의 TCP의 윈도우 크기를 65535옥텟으로 설정 • s : socket에서 오픈한 소켓의 디스크 디스크립터나 accept에서 커넥션을 확립한 후의 디스크 디스크립터를 지정 • size : 설정하고 싶은 윈도우 사이즈를 입력 #include <sys/types.h> #include <sys/socket.h> int size; size = 65535; /* 송신 버퍼의 설정 */ setsockopt (s, SOL_SOCKET, SO_SNDBUF, (char *)&size, sizeof(size)); /* 수신 버퍼의 설정 */ setsockopt (s, SOL_SOCKET, SO_RECVBUF, (char *)&size, sizeof(size));

  27. 소켓 시스템 콜 • DNS 관련 함수 • gethostbyname : 도메인 명에서 IP 어드레스를 검색 • gethostbyaddr : IP 어드레스에서 도메인 명을 검색 • gethostbyname의 name에는 도메인 명을 문자열로 표현자 구조체를 입력 • gethostbyaddr의 addr에는 네트워크 바이트 오더에서 나타난 4바이트의 IP 어드레스를 입력 • len에는 IP 어드레스의 옥텟 수를 나타내는 4를 지정 • type에는 AF_INET를 지정 #include <netdb.h> Struct hostent *gethostbyname(const char *name); #include <sys/socket.h> /* for AF_INET */ Struct hostent *gethostbyaddr(const char *addr, size_t len, int type);

  28. 소켓 시스템 콜 • 리턴되는 hostent 구조체 • h_name : 도메인 명 • h_aliases : 호스트명의 다른 이름을 나타낸 문자열에 포인터 배열 주소 • h_addrtype : AF_INET 등의 어드레스 패밀리 • h_length : 어드레스 길이(바이트 단위로 표시) • h_addr_list : IP 어드레스 포함 struct hostent { char *h_name; /* Official name of host */ char **h_aliases; /* Alias list */ int h_addrtype; /* Host address type */ int h_length; /* Length of address */ char **h_addr_llist; /* List of addresses from */ #define h_addr h_addr_list[10] /* Address, for backward compatibility */

  29. 소켓 시스템 콜 • 포트 번호 관련 함수 • 포트 번호와 그에 대응하는 키워드를 서로 변경할 때 사용 • getservbyname : 키워드에서 포트 번호를 검색하는 함수 • getservbyport : 포트 번호에서 키워드를 검색하는 함수 • proto에 검색하고 싶은 프로토콜을 지정 • proto에 “TCP”또는 “UDP”를 지정 #include <netdb.h> struct servent *getservbyname (const char *name, const char *proto); struct servent *getservbyport (int port, const char *proto);

  30. 소켓 시스템 콜 • 리턴 값 servent 구조체 • s_name : 키워드 포함 • s_aliases : 키워드의 다름 이름이 포함 • s_port : 이용 가능한 프로토콜의 이름이 포함(“TCP”,”UDP”) struct servent { char *s_name; /* Official service name */ char **s_aliases; /* Alias list */ int s_port; /* Port number */ char *s_proto; /* Protocol to usr */ };

  31. 소켓 시스템 콜 • IP 어드레스를 조작하는 함수 • inet_addr() : 10진 형식의 IP 어드레스 문자열을 32비트 정수로 변환 • inet_ntoa() : 32정수 형태에서 10진 형식의 IP 어드레스 문자열로 변환 #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> u_long inet_addr(const char *cp); char *inet_ntoa(struct in_addr in);

  32. 소켓 시스템 콜 • raw IP • raw IP를 사용하여 socket 시스템 콜을 사용할 경우 • raw IP를 사용할 경우는 socket에서 SOCK_RAW를 지정 • IPPROTO_RAW부분은 /usr/include/netinet/in.h에정의 • 애플리케이션 IP 헤더를 포함한 패킷 전체를 작성할 때 setsockopt 시스템 콜을 사용하여 IP_HDRINCL 옵션을 설정 • IP_HDRINCL 옵션을 사용할 경우 IP 헤더를 전부 애플리케이션으로 작성 • 체크섬(ip_cksum)은 운영체제가 계산 • 식별자(ip_id)를 0으로 설정하면 운영체제가 자동을 설정 int s; s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); #include <sys/types.h> #include <sys/socket.h> const int on = 1; setsockopt (s, IPPROTO_IP, IP_HDRINCL, (void *) &on, sizeof(on));

  33. 소켓 시스템 콜 • select 시스템 콜에 의한 다중 처리 • n : 검사하는 파일 디스크 디스크립터의 최대향 • readfds : recv, recvfrom에 의한 통신을 검하하는 파일 디스크 디스크립터를 지정 • writefds : send, sendto에 의한 통신을 검사하는 파일 디스크 피트터를 지정 • execeptfds : TCP의 긴급 데이터가 도착할 수 있는지 여부를 검사할 경우 지정 #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int select (int n, fd_set *readfds, fd_set *writefds, fd_set *execeptfds, struct timeval *timeout);

  34. UDP에 의한 통신 • Server와 Client 구성(UDP)

  35. UDP에 의한 통신 • Server와 Client 처리 흐름

  36. UDP에 의한 통신 • 실행 • 서버측에서 udps 실행 • 클라이언트에서 udpc 실행 • 실행

  37. UDP에 의한 통신 • 실행

  38. TCP에 의한 통신 • Server와 Client 구성(TCP)

  39. TCP에 의한 통신 • Server와 Client 처리 흐름

  40. TCP에 의한 통신 • 실행 • 서버측에서의 tcps를 기동 • 클라이언트에서의 tcpc를 기동 • 실행

  41. TCP에 의한 통신 • 실행

  42. TCP에 의한 통신 • 실행

  43. TCP에 의한 통신 • 실행

More Related