본문 바로가기
📖 CS/정보통신공학

📲 정보통신공학 - Ch2. 프로토콜 구조,TCP IP,인터넷 기반 응용-2

by 정람지 2024. 4. 10.

출처 : William Stallings, "Data and Computer Communications (10th Edition)," Pearson, 2014

하......

정통공싸워

엄마는..운체랑놀거야


2.7  📲 소켓 프로그래밍

소켓

- 1980년대 버클리 소켓 인터페이스로서 Unix 환경에서 개발

- 통신의 종점

- 연결 지향적이거나 비연결이거나 관계없이 => 클라이언트와 서버 프로세스 간 통신을 가능하게 함

 

한 컴퓨터의 클라이언트 소켓은 다른 컴퓨터의 서버 소켓을 부르기 위해 주소를 이용

=> 적당한 소켓이 예약되면, 두 컴퓨터는 데이터 교환을 할 수 있음

1. 서버 소켓의 컴퓨터는 예정에 없는 들어오는 콜을 기다리기 위해 TCP나 UDP 포트를 열어 둠.

2. 클라이언트는 대체로 원하는 서버의 소켓을 도메인 이름 서버(DNS) 데이터베이스에서 찾아서 식별 

3. 연결이 설정되면, 서버는 주 포트 번호를 추가적으로 들어 오는 콜을 위해 해방시킬 목적으로, 대화를 다른 포트번호로 교환


TELNET이나 원격 login과 같은 인터넷 응용

자세한 내용이 사용자들에게 숨겨지는 소켓을 사용

그러나, 소켓은 프로그래머가 네트워킹 기능과 응용을 쉽게 지원할 수 있도록 프로그램(C,java와 같은 언어)내부로부터 만들어질 수 있음

소켓프로그래밍 동작은 다른 흐스트상의 관련없는 프로세스 간 통신을 허락하기 위한 충분한 의미론을 포함


버클리 소켓 인터페이스

넓은 범위의 운영체제에 걸쳐 네트워킹 응용을 개발하는 표준 응용 프로그래밍 인터페이스(API)

소켓 API는 프로세스 간 통신 서비스에의 일반적인 접근을 제공

=> 소켓 특성은 학생들이 프로토콜과 분산 응용의 원리를 체험적인 프로그램 개발을 통해 배우는데 매우 적합


📟 소켓

포트번호와 IP주소를 연결 => 소켓

인터넷 전체를 통틀어 고유 식별자로 사용됨

 

응용은 자신과 연결된 포트에 하나의 소켓 주소가 존재하므로 하나의 응용은 여러 개의 소켓 주소를 가질 수 있음. (포트 여러 개)
소켓은 TCP 또는 UDP를 사용하는 프로그램을 작성하는데 필요한 통신 인터페이스인 API를 정의하는 데 사용

실제로 소켓이 API로사용되는경우에는(프로토콜, 로컬주소, 로컬 
프로세스)로써식별된다. 

 

로컬주소 = IP주소

로컬포트 = 포트번호

포트번호는 시스템 내에서 고유한 식별자 (프로토콜(TCP 또는 UDP)을 지정)

명확성과 구현의 용이성을 위하여 API로 사용되는 소켓 주소는 프로토콜 외에 IP 주소와 포트 번호를 모두 사용하여 식별


2개의 프로토콜에 대하여 소켓 API는 두 가지 유형의 소켓을 지원

스트림 소켓:

- 연결지향적이고 신뢰적인 데이터 전송을 지원하는 TCP를 사용

- 모든 데이터 블록은 양쪽 소켓 사이에 제대로 전달되고 순서에 맞게 수신
데이터그램소켓:

- TCP와는 달리 연결지향적 특성이 없는 UCP를 사용

- 제대로 된 전달과 순서에 맞는 수신을 보장받지 못함

+ 원초적(Raw) 소켓:
IP와 같은 하위 계층
프로토콜을 직접 접속


📟 소켓 인터페이스 호출

주요 시스템 호출

 

소켓사용에서 첫 단계는 socket( ) 명령어를 사용하여 신규 소켓을 생성하는 것

이 명령어는 3개의 파라미터를 가짐

 

1 🛜 domain 파라미터

통신 프로세스가 있는 영역을 지정

영역 예시 :

- AF_UNIX : 동일 시스템 내에 있는 프로세스 사이의 통신용

- AF_INET : 터넷프로로콜을사용하는프로세스사이의통신용

- AF_INET6 : 인터넷 프로로콜을 사용하는 프로세스 사이의 통신용

 

2 🛜 type 파라미터

소켓이 스트림 소켓인지 데이터그램 소켓인지를 구별하는 파라미터

 

3 🛜 protocol 파라미터

TCP 또는 UDP를 가르키는 파라미터


소켓의 데이터 구조

- 구현에 따라 다름

- 발신지포트, IP 주소, 연결이 설정되었는지 대기중인지의 여부, 목적지 포트, IP주소, 그리고 연결과 관련된 여러 가지 옵션과 파라미터 포함


bind() 함수: 소켓에 소켓 주소를 묶어 주는 역할


📞소켓 연결

 

프로그램이 서버와 클라이언트 역할을 수행하기 위해서는 소켓이 필요

소켓 : 프로세스가 데이터를 송수신하기 위해 운영 체제로부터 할당받는 엔드포인트

  1. 서버 소켓 생성: 서버는 socket() 함수를 호출하여 소켓을 생성합니다. 그 후 bind() 함수를 사용하여 서버의 IP 주소와 포트 번호를 소켓에 연결합니다.
  2. 연결 대기: 서버는 listen() 함수를 호출하여 클라이언트의 연결 요청을 기다립니다. 이 때, backlog 파라미터는 수용 가능한 최대 대기 연결 수를 결정합니다.
  3. 연결 수립: 서버는 accept() 함수를 호출하여 연결 요청을 수락합니다. 이 함수는 클라이언트와의 연결이 수립될 때까지 블로킹(blocking) 상태가 됩니다. accept() 함수는 새로운 소켓을 반환하며, 이 소켓은 클라이언트와의 통신에 사용됩니다.
  4. 데이터 송수신: 수립된 연결을 통해 서버와 클라이언트는 데이터를 교환할 수 있습니다. 이 과정에서 send()와 recv() 함수를 사용하여 데이터를 보내고 받을 수 있습니다.
  5. 클라이언트 소켓 생성: 클라이언트도 socket() 함수를 호출하여 소켓을 생성합니다.
  6. 서버에 연결 요청: 클라이언트는 connect() 함수를 사용하여 서버의 주소에 연결을 시도합니다. 클라이언트는 서버의 IP 주소와 포트 번호를 명시해야 하며, 이를 위해 struct sockaddr 구조체를 사용합니다.
  7. 외부 주소 연결: 특정 경우, 클라이언트는 외부 네트워크의 서버에 연결할 때 foreignAddress 구조체를 사용하여 주소를 명시해야 할 수 있습니다.
  8. 도메인 이름 해석: getpeername() 함수를 사용하여 연결된 상대방의 주소 정보를 얻을 수 있으며, sockfd 매개변수를 통해 소켓을 지정합니다.

📞 소켓 통신

소켓 통신 함수

  1. send()
    • 소켓 식별자 sockfd를 사용해 데이터를 송신하는 함수.
    • msg 포인터가 가리키는 메모리에서 len 바이트만큼의 데이터를 소켓을 통해 전송.
    • flags는 전송 옵션을 지정.
  2. recv()
    • 소켓 식별자를 통해 데이터를 수신하는 함수.
    • buf 포인터가 가리키는 메모리에 len 바이트만큼의 데이터를 수신하여 저장.
  3. sendto()
    • 데이터를 특정 대상 주소로 송신하는 함수.
    • send() 함수와 유사하지만, 대상 주소 정보(IP 주소 및 포트)를 포함.
  4. recvfrom()
    • 특정 소스로부터 데이터를 수신하는 함수.
    • recv() 함수와 유사하지만, 소스 주소 정보를 반환 받을 수 있음.

소켓 연결 및 종료 관련 함수

  1. close()
    • 소켓 식별자를 사용하여 연결된 소켓을 닫는 함수.
    • 데이터 전송이 완료된 후 소켓을 닫아 자원을 반환.
  2. shutdown()
    • 소켓의 일부 기능을 종료하는 함수.
    • 데이터 송수신을 중단하고 소켓을 단계적으로 종료.

네트워크 주소 변환 함수

  1. htons()
    • 호스트 바이트 순서의 포트 번호를 네트워크 바이트 순서로 변환하는 함수.

📞 서버 프로그램

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

void error(char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno, clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    int n;
    if (argc < 2) {
        fprintf(stderr,"ERROR, no port provided\n");
        exit(1);
    }
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(portno);
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    if (bind(sockfd, (struct sockaddr *) &serv_addr,
             sizeof(serv_addr)) < 0) 
              error("ERROR on binding");
    listen(sockfd,5);
    clilen = sizeof(cli_addr);
    newsockfd = accept(sockfd, 
               (struct sockaddr *) &cli_addr, &clilen);
    if (newsockfd < 0) 
         error("ERROR on accept");
    bzero(buffer,256);
    n = read(newsockfd,buffer,255);
    if (n < 0) error("ERROR reading from socket");
    printf("Here is the message: %s\n",buffer);
    n = write(newsockfd,"I got your message",18);
    if (n < 0) error("ERROR writing to socket");
    return 0; 
}

 


📞 클라이언트 프로그램

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

void error(char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    if (argc < 3) {
        fprintf(stderr,"usage %s hostname port\n", argv[0]);
        exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR connecting");
    printf("Please enter the message: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);
    return 0;
}

📡  주요 용어 복습

IP 데이터그램 

SSH

TCP세그먼트
개방 시스템 접속 (OSI)

구문론
네트워크 접속 계층 

네트워크접속점(NAP)
단순 메일 전송 프로토콜 (SMTP)
데이터그램 소켓 

데이터그램 통신 

동등 계층
라우터 

멀티미디어 

물리 계층

비디오
비탄력적 트래픽
사용자 데이터그램 프로토콜 (UDP)
서브네트워크 

서비스 품질 (QoS)

세그먼트소켓

소켓 프로그래밍

수송 계층

인터넷 계층
인터넷 프로토콜 (IP)

전송제어 프로토콜 (TCP)

체크섬
캡슐화
타이밍

스트림 소켓
스트림 통신 

텍스트
영상
오디오
원초적 소켓
응용 계층
응용 프로그래밍 인터페이스(API)
의미론 

서비스접속점(SAP)

인터네트워킹

인터넷
파일 전송 프로토콜 (FTP)

패킷
포트
프레임 체크 시퀀스

프로토콜
프로토콜 구조
프로토콜 데이터 유닛(PDU)

헤더
호스트-호스트 계층

 

좋아..정리나중에


📡 복습 문제 / 연습 문제


🅀 네트워크 접속 계층의 주요 기능은 무엇인가? 

 

🅀 수송 계층에 의해 수행되는 작업은 무엇인가? 

 

🅀 프로토콜이란무엇인가?


🅀 라우터란무엇인가? 


🅀 PDU란 무엇인가?


🅀 프로토콜 구조란 무엇인가?


🅀 TCP/IP는 무엇인가?


🅀 TCP/IP 구조에서 보이는 계층구조의 장점은 무엇인가?


🅀 오늘날 가장 널리 사용되고 있는 IP 버전은 얼마인가?

IPv6


🅀 인터넷의 모든 트래픽은 TCP를 사용하는가?

아뇨


🅀 IPv4와 IPv6 사이의 주소 공간을 비교하라. 각 버전에서 사용되는 비트 수는?


 

오늘의뿌듯짤