메모용 개발 블로그
  • Home

Categories

  • All Posts116
  • OS35
    • Linux23
    • MacOS8
    • Windows4
  • 데이터베이스3
    • Oracle1
    • Postgresql1
  • Develop26
    • CSS33
    • Go8
    • HTML52
    • Java1
    • JavaScript4
    • React2
    • Svelte2
  • 개발일기10
  • Docker1
  • Git3
  • GitLab12
  • Nginx7
  • 기타16
  • 이 블로그의 오픈소스3
Go•2024년 5월 20일

Go HTTP 유닉스 소켓

Table of Contents

  • Go HTTP 유닉스 소켓
  • 유닉스 도메인 소켓(Unix Domain Socket)
  • Go
  • Client
  • Server

유닉스 도메인 소켓(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)
	}
}

← Back to all posts