네트워크 프로그래밍과 소켓의 이해 #network

2023. 3. 30. 13:55_Study/Network

728x90

 

네트워크 프로그래밍과 소켓이란?

 

#0329 #네트워크프로그래밍

🐇¸.•*¨*•¸.•*¨*•¸.•*¨*•¸.•*¨*•

해당 자료는 도서 : 윤성우 열혈 TCP/IP 소켓 프로그래밍 을 참고하였습니다.

 


 

네트워크 프로그래밍 : 네트워크에 연결되어 있는 서로 다른 두 컴퓨터가 데이터를 주고 받을 수 있도록 하는 것

 

먼저 위의 그림을 설명하기 위해선 OSI 7 계층에 대한 설명이 필요하다.

OSI 7 layers

국제 표준화 기구(ISO)에서 개발한 모델로 컴퓨터 네트워크 프로토콜 디자인과 통신을 7계층으로 나누어 설명한다.

각 계층은 하위 계층의 기능만을 이용, 상위계층에게 기능을 제공한다.

IT관련 용어 - [OSI 7계층] 이란? (OSI 7 Layer) : 네이버 블로그 (naver.com)

그러나 OSI 7 계층은 레퍼런스 모델로 프로토콜 개발에 참조되는 용도이며 실제로 구현된 프로토콜 모델은 TCP/IP Protocol 이다.

- Transmission Control Protocol

- Internet Protocol

 

OSI 7 계층이란?, OSI 7 계층을 나눈 이유 :: effortDev (tistory.com)

 

네트워크 프로그래밍에서 중요하게 여겨지는 계층들을 살펴보자면 1,2,3 계층이 있다.

 

1계층 Physical Layer

- 전기적, 기계적 특성을 이용해서 통신 케이블로 데이터를 전송

- 통신 단위는 비트(0,1)

- 데이터를 전달하는 기능, 어떤 데이터 인지 관여하지 않음

장비: 통신 케이블, 리피터, 허브

 

2계층 Data Link Layer

- 물리 계층을 통해 송수신되는 정보의 오류 검출 및 흐름 관리

- 안전한 정보의 전달을 수행할 수 있도록 도움

- 통신 오류 검출, 재전송

- MAC 주소를 이용하여 통신

장비: 브리지, 스위치 (스위칭 브리지) 등

 

 

3계층: Network Layer

- 데이터를 목적지 까지 전달하는 기능 (라우팅)

- 경로를 선택하고, 경로에 따라 패킷을 전송

- IP 주소를 사용

- 다양한 프로토콜 및 라우팅 기술 사용

장비 : 라우터

4계층 : Transport layer (전송 계층)

- 최종 시스템 및 호스트 간의 데이터 전송 조율을 담당

- 흐름 제어, 중복 검사

- 보낼 데이터의 용량, 목적지 등을 처리

- TCP/UDP 프로토콜 사용

 

5계층 : Session layer (세션 계층)

- 통신 세션을 구성하는 계층으로 포트(port) 연결

- 사용자간의 포트 연결(session)이 유효한지 확인하고 설정

 

6계층 : Presentation layer (표현 계층)

- 운영체제의 일부분

- 네트워크 형식 - 응용 프로그램 형식

-부호화, 변화, 데이터 압축 및 암호화 등

 

7계층 : Application layer (응용 계층)

- 응용 프로세스 간 정보 교환

- 각종 응용 프로그램

 

 

다시 돌아와서, 데이터 전송은 해당 그림 처럼 응용 계층에서 보낼 파일을 물리계층까지 전달하고 라우터와 스위치를 통해 다른 네트워크로 전달되는 과정을 의미한다.

 

 

그리고 전달되는 경로인 communication link는 여러 방법이 있으며 단일 방법도 있고, 다방면도 있다.

 

 

1. 물리적인 연결 : 대부분 인터넷이란 거대한 네트워크로 연결되어 있어서 신경 쓸 필요가 없다.

2. 소프트웨어적 연결 : 데이터의 송수신 방법만 고민? -> 운영체제에서 소켓(Socket)이라는 것을 제공

 

따라서 네트워크 프로그래밍소켓 프로그래밍 이라고 한다.

네트워크로 연결된 둘 이상의 컴퓨터 사이에서의 데이터 송수신 프로그램의 작성을 의미

 

소켓이라는 표현을 사용한 이유는 가전제품의 소켓을 생각하면, 전력망으로부터 전기를 사용하기 위해 사용하는 소켓을 생각하면 된다. 따라서 네트워크 망에 연결하기 위해 네트워크 소켓을 사용하는 것이다. 소켓은 크게 두 가지로 나뉘는데 아래와 같다. 

 

- 서버(리스닝) 소켓

- 클라이언트 소켓

 

 

전화기도 전화망을 통해서 음성데이터를 주고받는 도구이기 때문에 소켓과 비슷하다.

 

소켓에 대한 정의를 정리하면

- 네트워크(인터넷)의 연결도구

- 운영체제에 의해 제공되는 소프트웨어적인 장치

- 소켓은 프로그래머에게 데이터 송수신에 대해 물리적, 소프트웨어적인 세부내용을 신경 쓰지 않게 함.

 

 

서버(리스닝) 소켓

: 전화기를 놓으려면 먼저 전화기를 구입해야한다. 전화기를 사용하는 예시를 들어 소켓을 설명해본다.

전화기에 해당하는 소켓을 생성하는 함수

#include <sys/socket.h>
int socket(int domain, int type, int protocol);

성공시 파일디스크립터, 실패시 -1 반환

 

연결 설정 후 데이터 통신이 이루어진다.

해당 socket()함수는 전화를 거는 용도의 소켓전화를 수신하는 용도의 소켓 생성방법이 차이가 있다.

domain : IPv4, IPv6, IPX, low level socket 등 설정

type : TCP, UDP 설정

protocol : 특정 프로토콜 사용을 지정(보통 0)

 

 

: 전화기를 구입했으면 전화번호를 받아야한다. 소켓에선 IP와 포트번호라는 주소정보이다.

소켓에 주소정보를 할당하는 함수 bind

#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);

bind 함수를 통해 주소정보가 할당되어 응용프로그램과 연결된다.

 

struct sockaddr_in 은 IPv4를 좀 더 편리하게 사용하기 위한 구조체이며 액자식 구성으로 되어있다. (내부에 또 구조체가 있다.)

serv_addr.sin_family = AF_INET; //IPv4 사용

serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); // 주소 할당

- INADDR_ANY: 소켓이 동작하는 컴퓨터의 IP 주소가 자동으로 할당

serv_addr.sin_port = htons(atoi(argv[1])); // 포트번호 할당

- htoms: 호스트 바이트 순서를 네트워크 바이트 순서(Big endian)로 변경

 

 

전화기가 전화 케이블에 연결되는 순간 전화 받을 수 있는 상태가 된다. 이처럼 소켓도 연결 요청이 가능한 상태가 되어야 한다.

 

 

소켓을 연결 요청이 가능한 상태가 되게하는 함수 listen

#include <sys/socket.h>
int listen(int sockfd, int backlog);

성공시 0 실패시 -1 반환

 

클라이언트의 연결 요청을 기다리는 상태의 소켓으로 변경하는데 클라이언트의 연결요청을 기다린다.

이는 연결 요청을 받는 소켓(서버)에서만 필요하며 클라이언트에게는 필요가 없다.

backlog : 대기한 큐의 수

 

 

전화기가 전화케이블에 연결되었으면, 전화벨이 울릴때 수화기를 들어야 한다.

함수 호출을 통해서 요청을 수락하는 함수 accept

#include <sys/socket.h>
int accept(int sockfd, strcut sockaddr *addr, socklen_t *addrlen);

연결요청을 수락하는 기능을 수행하며 송수신은 양방향으로 가능하다.

여기서 임베디드 단위 코딩에서의 동적메모리는 지양한다.

 

 

이를 정리하면 네트워크 프로그래밍에서 연결 요청을 허용하는 소켓의 생성과정을 다음과 같이 정리할 수 있다.

 

1단계 소켓생성  socket 함수호출
2단계  IP주소와 PORT번호 할당  bind함수호출
3단계 연결요청 가능상태로 변경  listen 함수호출
4단계  연결요청에 대한 수락 accpet 함수 호출 

 

연결요청을 허용하는 프로그램을 가리켜 일반적으로 서버(Server)라고 하고

서버는 연결을 요청하는 클라이언트 보다 먼저 실행되어야 한다.

클라이언트보다 복잡한 실행 과정을 거치는 이 소켓을 서버 소켓, 리스닝 소켓 이라고 한다.

 

 

 

클라이언트 소켓

 

연결을 요청하는 소켓의 구현

: 전화를 거는 상황에 비유할 수 있고 서버와 다르게 구현이 매우 간단하다.

소켓의 생성  ,  연결의 요청으로 구분된다.

 

connect() 함수

#include <sys/socket.h>

int connect(int sockfd, struct sockaddr *serv_addr, socklent_t addrlen);