2024-05-20 15:21:38
유닉스 도메인 소켓(Unix domain socket)은 유닉스 계열 운영체제에서 프로세스간 통신에 사용되는 소켓이다.
흔히 통신을 위해서 사용하는 TCP/UDP 통신의 경우 네트워크 상의 다른 컴퓨터와 통신이 가능하지만 유닉스 도메인 소켓은 프로세스간 통신에 사용되는 만큼 로컬에서만 사용가능하다.
Unix domain socket은 TCP/UDP 통신에 비해서 과정이 간략하여 같은 기기 내 통신이라면 선택하기 좋다.
Go 언어에서 유닉스 도메인 소켓을 활용하여 통신을 한 것을 남기고자 한다.
편하게 관리하기 위해서 유닉스 도메인 소켓에서 HTTP 통신을 하는 예제이다.
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.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)
}
}