Apple 정품 아이폰 16 Pro 자급제, 화이트 티타늄, 256GB






블로그 내에서 다른 포스팅 검색하기기
검색어를 입력해주세요

C언어의 BSD 소켓이란?



BSD 소켓은 Berkeley Software Distribution에서 개발된 네트워크 프로그래밍 인터페이스입니다. 
BSD 소켓은 TCP/IP 프로토콜을 기반으로 하며, 소켓이라는 추상적인 개념을 통해 네트워크 통신을 수행할 수 있습니다. 
BSD 소켓은 다양한 운영체제에서 지원되며, C언어에서는 <sys/socket.h> 헤더 파일을 포함하여 사용할 수 있습니다.

소켓통신

 

서버 소켓 생성 예제


서버 소켓을 생성하려면 socket() 함수를 사용합니다. 
socket() 함수는 세 개의 인자를 받으며, 각각 소켓의 도메인, 타입, 프로토콜을 지정합니다. 

 

Socket 인자

 

도메인
주소 체계를 의미하며, 일반적으로 AF_INET (IPv4) 또는 AF_INET6 (IPv6)를 사용합니다. 

타입
전송 방식을 의미하며, TCP를 사용하려면 SOCK_STREAM, UDP를 사용하려면 SOCK_DGRAM을 사용합니다. 

프로토콜
특정 프로토콜을 지정하려면 해당 번호를 입력하거나, 기본값으로 0을 입력합니다. 

반환
socket() 함수는 성공하면 소켓의 파일 디스크립터를 반환하고, 실패하면 -1을 반환합니다.




 

소켓 바인딩 예제


서버 소켓을 바인딩하려면 bind() 함수를 사용합니다. 
bind() 함수는 세 개의 인자를 받으며, 각각 소켓의 파일 디스크립터, 주소 구조체의 포인터, 주소 구조체의 크기를 지정합니다.
주소 구조체는 도메인에 따라 다르게 정의되며, AF_INET 도메인에서는 struct sockaddr_in 구조체를 사용합니다.

struct sockaddr_in 구조체는 네 개의 멤버를 가지며, 각각 도메인, 포트 번호, IP 주소, 여분의 공간을 저장합니다.
포트 번호와 IP 주소는 네트워크 바이트 순서로 변환하여 저장해야 합니다.

bind() 함수는 성공하면 0을 반환하고, 실패하면 -1을 반환합니다.

 

 

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    // 서버 소켓 생성
    int server_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sock == -1)
    {
        perror("socket error!\n");
        return 0;
    }
    return 0;
}



아래는 소켓 생성 후 바인딩 예제입니다.


#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    // 서버 소켓 생성
    int server_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sock == -1)
    {
        perror("socket create error!\n");
        return 0;
    }

    // 서버 주소 구조체 설정
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8090);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    memset(server_addr.sin_zero, 0, sizeof(server_addr.sin_zero));

    // 서버 소켓 바인딩
    int r = bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (r == -1)
    {
        perror("bind error!");
        return 0;
    }

    return 0;
}



서버와 클라이언트 통신

 

서버 소켓을 리스닝하고 클라이언트 연결 수락 예제


서버 소켓을 리스닝하려면 listen() 함수를 사용합니다.
listen() 함수는 두 개의 인자를 받으며, 각각 소켓의 파일 디스크립터와 연결 요청을 대기할 수 있는 최대 큐의 크기를 지정합니다.
listen() 함수는 성공하면 0을 반환하고, 실패하면 -1을 반환합니다.

서버 소켓이 클라이언트의 연결 요청을 수락하려면 accept() 함수를 사용합니다. 
accept() 함수는 세 개의 인자를 받으며, 각각 소켓의 파일 디스크립터, 클라이언트 주소 구조체의 포인터, 클라이언트 주소 구조체의 크기를 저장할 변수의 포인터를 지정합니다. 
accept에 성공하면 새로운 소켓의 파일 디스크립터를 반환하고, 실패하면 -1을 반환합니다. 
또한 이 함수는 블로킹 함수이므로, 연결 요청이 있을 때까지 대기합니다.

 

서버 소켓을 리스닝하고 클라이언트 연결을 수락하는 예제



#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    // 서버 소켓 생성 및 바인딩 코드 생략
// ...
// ...

    // 서버 소켓 리스닝
    int r = listen(server_sock, 5);
    if (r == -1)
    {
        perror("listen error!\n");
        return 0;
    }

    // 클라이언트 주소 구조체 설정
    struct sockaddr_in client_addr;
    socklen_t client_addr_size = sizeof(client_addr);

    // 서버 소켓이 클라이언트 연결 요청 수락
    int client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_addr_size);
    if (client_sock == -1)
    {
        perror("accept error!\n");
        return 0;
    }

    return 0;
}

 

네트워크 통신 ...어렵다

 

클라이언트 요청을 읽는 예제


서버 소켓이 클라이언트의 요청을 읽기 위해 read() 함수를 사용합니다.
read() 함수는 세 개의 인자를 받으며, 각각 소켓의 파일 디스크립터, 버퍼의 포인터, 버퍼의 크기를 지정합니다.
read() 함수는 성공하면 읽은 바이트 수를 반환하고, 실패하면 -1을 반환합니다. 

다음은 서버 소켓이 클라이언트 요청을 읽는 에제입니다.

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    // 서버 소켓 생성 및 바인딩 코드 생략
    // ...
    // 서버 소켓 리스닝 및 클라이언트 연결 요청 수락 코드 생략
    // ...

    // 버퍼 설정
    char buf[1024];
    int buf_size = sizeof(buf);

    // 클라이언트 요청 읽기
    int r = read(client_sock, buf, buf_size);
    if (r == -1)
    {
        perror("read error!\n");
        return 0
    }

    // 클라이언트 요청 출력
    printf("msg: %s\n", buf);
    close(client_sock);
    return 0;
}




오늘은 C언어에서 BSD 소켓을 사용하여 서버 소켓을 만들고 클라이언트의 요청을 수락 및 메시지 수신 하는 예제를 알아보았습니다.

반응형


살구엉덩이님의
글이 좋았다면 응원을 보내주세요!