본문 바로가기

DEV/시스템 프로그래밍

소켓(Socket)이란?

Socket이란?

  - 프로그램 간 communication의 endpoint를 추상화한 것

 

그림에서 본 것처럼 프로그램 1(Client)이 프로그램 2(Server)에게 메시지(Data)를 보내고 싶을 때

해당 메시지를 프로그램 2와 연결되어있는 소켓에 넣어주면 프로그램 2는 해당 메시지를 가져올 수 있다.

이렇게 프로그램 사이의 통신을 매개하는 역할을 하는 것이 소켓(Socket)이라 할 수 있다.

 

 

Socket descriptor란?

- application이 file에 접근하기 위해 file descriptor를 사용하는 것과 동일하게,

  application이 socket에 접근하기 위해서는 socket descriptor가 필요하다

  

 

file descriptor란?(링크 삽입 예정)

 

  Socket descriptor는 file descriptor처럼 수행된다.

  1. read, write 등 system call 함수들은 socket descriptor에서도 동일하게 동작한다.

  2. socket은 file offset의 개념을 지원하지 않아 lssek함수는 사용할 수 없다.

 

 

 

간단히 소켓을 만들어보자

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

socket()

 

- 첫 번째 인자 domain

network communication의 특성을 결정한다. 

AF_INET: IPv4 Internet 도메인 (주로 이것이 사용된다)

AF_INET: IPv6 Internet 도메인

AF_UNIX: UNIX 도메인

AF_UNSPEC: unspecified

 

 

- 두번째 인자 type

socket의 타입과 socket communication의 특성을 결정한다.

SOCK_DGRAM: TCP 프로토콜 사용(conncetion less, unreliable)

SOCK_STREAN: UDP 프로토콜 사용(connection-oriented, reliable)

 

 

- 세번째 인자 protocol

1, 2번 인자만으로도 프로토콜이 정의되지만 전송 타입과 통신의 형태가 다른 프로토콜이 존재하기 때문에

세 번째 인자는 통신을 구체화하기 위해 사용된다.

0: 주로 0이 사용된다.

 

 

 

#include <stdio.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

int socket(int domain, int type, int protocol);

int main()
{
    int file_d; // 파일 디스크럽터
    int sock_d; // 소켓 디스크럽터

    file_d = open("/etc/passwd", O_RDONLY);
    printf("/etc/passwd의 file descriptor = %d\n", file_d);

    sock_d = socket(AF_INET, SOCK_STREAM, 0);
    printf("IPv4의 TCP socket descriptor = %d\n", sock_d);

    close(file_d);
    close(sock_d);
}

결과화면

 

Sock Address

#include <sys/socket.h>

struct sockaddr
{
    sa_family_t sa_family;
    char sa_data[];
};

socket 통신을 하기 위해서는 당연하게도 client와 server가 누군지 알아야 한다.

이때 IP 주소, PORT 번호 등이 사용되는데 이러한 정보를 socket address라고 부른다.

 

위 코드에 있는 sockaddr 구조체에 IP 주소, PORT 번호 등을 직접 쓰거나 읽기가 불편해 사용되는 것이

인터넷 전용 소켓 주소 구조체인 sockaddr_in이다.

#include <netinet/in.h>
struct in_addr
{
    in_addr_t s_addr; /* IPv4 address */
};

struct sockaddr_in
{
    sa_family_t sin_family;  /* address family */
    in_port_t sin_port;      /* port number */
    struct in_addr sin_addr; /* IPv4 address */
    char sin_zero[8];        /* not used */
};

 

sin_family는 AF_INET, AF_UNIX 등 communication의 특성이다.

sockaddr과 sockaddr_in의 차이