Menu

메모용 개발 블로그

전체보기 > Develop > Go >

Go HTTP 유닉스 소켓

2024-05-20 15:21:38

유닉스 도메인 소켓(Unix Domain Socket)

유닉스 도메인 소켓(Unix domain socket)은 유닉스 계열 운영체제에서 프로세스간 통신에 사용되는 소켓이다.

흔히 통신을 위해서 사용하는 TCP/UDP 통신의 경우 네트워크 상의 다른 컴퓨터와 통신이 가능하지만 유닉스 도메인 소켓은 프로세스간 통신에 사용되는 만큼 로컬에서만 사용가능하다.

Unix domain socket은 TCP/UDP 통신에 비해서 과정이 간략하여 같은 기기 내 통신이라면 선택하기 좋다.

Go

Go 언어에서 유닉스 도메인 소켓을 활용하여 통신을 한 것을 남기고자 한다.

편하게 관리하기 위해서 유닉스 도메인 소켓에서 HTTP 통신을 하는 예제이다.

Client

client.go

package main

import (
	"context"
	"io"
	"log"
	"net"
	"net/http"
)

// SockFilePath 유닉스 도메인 소켓 파일 경로
var SockFilePath string = "./ping-server.sock"

func main() {
	// http 클라이언트 생성, 유닉스 도메인 소켓으로 연결
	client := http.Client{
		Transport: &http.Transport{
			DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
				return net.Dial("unix", SockFilePath)
			},
		},
	}

	// 요청 송신
	resp, err := client.Post("http://unix/ping", "", nil)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	// 응답 읽기
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	log.Println(string(body))
}

Server

server.go

package main

import (
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"syscall"
)

// SockFilePath 유닉스 도메인 소켓 파일 경로
var SockFilePath string = "./ping-server.sock"

func main() {
	// 유닉스 도메인 소켓 파일 생성, 수신 대기
	socket, err := net.Listen("unix", SockFilePath)
	if err != nil {
		log.Fatal(err)
	}

	// 종료 시 소켓 파일 제거
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-c
		os.Remove(SockFilePath)
		os.Exit(1)
	}()

	mux := http.NewServeMux()

	// Post 요청 핸들러 등록
	mux.HandleFunc("POST /ping", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("pong!"))
	})

	server := http.Server{
		Handler: mux,
	}

	// 유닉스 도메인 소켓으로 서버 시작
	err = server.Serve(socket)

	if err != nil {
		log.Fatalln(err)
	}
}