UDPSocket.go

package ipc

import (
	"bytes"
	"encoding/gob"
	"log"
	"net"
	"time"
)

type UDPSocket struct {
	UDPBase
	listeners map[string]func(interface{}) interface{}
	conn      *net.UDPConn
	addr      *net.UDPAddr
}

func NewUDPSocket(addr string, port int) *UDPSocket {
	socket := &UDPSocket{
		UDPBase: UDPBase{
			addr: addr,
			port: port,
			mtu:  32000,
		},
		listeners: make(map[string]func(interface{}) interface{}),
	}
	socket.create(addr, port)
	return socket
}

func (u *UDPSocket) create(addr string, port int) {
	u.addr, _ = net.ResolveUDPAddr("udp", net.JoinHostPort(addr, string(port)))
	u.conn, _ = net.ListenUDP("udp", u.addr)
	if u.conn == nil {
		log.Println("UDPSocket create failed.")
	}
}

func (u *UDPSocket) bind() {
	if u.conn == nil {
		log.Println("UDPSocket bind failed.")
	}
}

func (u *UDPSocket) addListener(key string, handler func(interface{}) interface{}) {
	u.listeners[key] = handler
}

func (u *UDPSocket) listen() {
	buffer := make([]byte, u.mtu)
	for {
		n, addr, err := u.conn.ReadFromUDP(buffer)
		if err != nil {
			log.Println("Failed to read from UDP connection:", err)
			continue
		}

		typeByte := buffer[0]
		data := buffer[1:n]

		var deserializedData interface{}
		dec := gob.NewDecoder(bytes.NewReader(data))
		err = dec.Decode(&deserializedData)
		if err != nil {
			log.Println("Failed to deserialize data:", err)
			continue
		}

		responseData := u.run(string(typeByte), deserializedData)

		var responseBuffer bytes.Buffer
		enc := gob.NewEncoder(&responseBuffer)
		err = enc.Encode(responseData)
		if err != nil {
			log.Println("Failed to serialize response:", err)
			continue
		}

		response := append([]byte{typeByte}, responseBuffer.Bytes()...)
		_, err = u.conn.WriteToUDP(response, addr)
		if err != nil {
			log.Println("Failed to send response:", err)
		}
	}
}

func (u *UDPSocket) run(command string, data interface{}) interface{} {
	handler, exists := u.listeners[command]
	if exists {
		return handler(data)
	}
	return nil
}

UDPSocket์€ UDP๋ฅผ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ํŠน์ • ๋ช…๋ น์–ด์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์†Œ์ผ“์ž…๋‹ˆ๋‹ค. ์ด ์†Œ์ผ“์€ ๋“ค์–ด์˜ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

UDPSocket ๊ตฌ์กฐ์ฒด

  • UDPBase: UDP ํ†ต์‹ ์— ํ•„์š”ํ•œ ๊ธฐ๋ณธ ์„ค์ •์„ ํฌํ•จํ•˜๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค.

  • listeners: ๋ช…๋ น์–ด ๋ฌธ์ž์—ด์„ ์ฒ˜๋ฆฌํ•  ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ์ €์žฅํ•˜๋Š” ๋งต์ž…๋‹ˆ๋‹ค.

  • conn: UDP ์—ฐ๊ฒฐ์„ ๊ด€๋ฆฌํ•˜๋Š” ํฌ์ธํ„ฐ์ž…๋‹ˆ๋‹ค.

  • addr: ํ†ต์‹ ํ•  ์ฃผ์†Œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

NewUDPSocket ํ•จ์ˆ˜

์ด ํ•จ์ˆ˜๋Š” UDPSocket์˜ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์„ค์ •์„ ํ†ตํ•ด UDP ์†Œ์ผ“์„ ์„ค์ •ํ•œ ํ›„, create ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์—ฐ๊ฒฐ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

create ๋ฉ”์„œ๋“œ

์ด ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์ฃผ์†Œ์™€ ํฌํŠธ๋กœ UDP ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ResolveUDPAddr๋กœ ์ฃผ์†Œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ , ListenUDP๋กœ ์—ฐ๊ฒฐ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ์ƒ์„ฑ์— ์‹คํŒจํ•˜๋ฉด ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

bind ๋ฉ”์„œ๋“œ

์ด ๋ฉ”์„œ๋“œ๋Š” ์†Œ์ผ“์ด ์ œ๋Œ€๋กœ ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์—ฐ๊ฒฐ์ด ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

addListener ๋ฉ”์„œ๋“œ

์ด ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. key๋Š” ๋ช…๋ น์–ด ๋ฌธ์ž์—ด์ด๊ณ , handler๋Š” ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

listen ๋ฉ”์„œ๋“œ

์ด ๋ฉ”์„œ๋“œ๋Š” UDP ์—ฐ๊ฒฐ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ , ์ฒ˜๋ฆฌํ•œ ํ›„ ์‘๋‹ต์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

  1. conn.ReadFromUDP(buffer)๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.

  2. ์ฒซ ๋ฐ”์ดํŠธ๋Š” ๋ช…๋ น์–ด(typeByte)๋กœ ์‚ฌ์šฉ๋˜๊ณ , ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ(data)๋Š” ๋””์ฝ”๋”ฉ๋ฉ๋‹ˆ๋‹ค.

  3. ๋””์ฝ”๋”ฉ๋œ ๋ฐ์ดํ„ฐ๋ฅผ run ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•˜๊ณ , ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  4. ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ์ง๋ ฌํ™”ํ•˜์—ฌ ์›๋ž˜ ์ฃผ์†Œ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

run ๋ฉ”์„œ๋“œ

์ด ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ์ฐพ์•„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ช…๋ น์–ด์— ๋Œ€ํ•œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์กด์žฌํ•˜๋ฉด ์‹คํ–‰ํ•˜๊ณ , ์—†์œผ๋ฉด nil์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์š”์•ฝ

  • UDPSocket ๊ตฌ์กฐ์ฒด: UDP๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ณ  ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์†Œ์ผ“์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

  • NewUDPSocket ํ•จ์ˆ˜: ์ƒˆ๋กœ์šด UDP ์†Œ์ผ“์„ ์ƒ์„ฑํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

  • create ๋ฉ”์„œ๋“œ: ์ฃผ์–ด์ง„ ์ฃผ์†Œ์™€ ํฌํŠธ๋กœ UDP ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  • bind ๋ฉ”์„œ๋“œ: ์†Œ์ผ“์ด ์ œ๋Œ€๋กœ ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  • addListener ๋ฉ”์„œ๋“œ: ํŠน์ • ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

  • listen ๋ฉ”์„œ๋“œ: UDP ์—ฐ๊ฒฐ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ , ์ฒ˜๋ฆฌํ•œ ํ›„ ์‘๋‹ต์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

  • run ๋ฉ”์„œ๋“œ: ์ฃผ์–ด์ง„ ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ์ฐพ์•„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ UDP ์†Œ์ผ“์„ ์„ค์ •ํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๊ณ , ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณผ์ •์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Last updated