diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..b277cfb --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,53 @@ +--- +name: catsync-build +on: + push: + paths: + - '.gitea/workflows/build.yml' + - 'go.mod' + - 'go.sum' + - 'main.go' + - 'assets/**' + - 'pb/**' + pull_request: + paths: + - '.gitea/workflows/build.yml' + - 'go.mod' + - 'go.sum' + - 'main.go' + - 'assets/**' + - 'pb/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: simple-build + runs-on: ubuntu-20.04 + strategy: + matrix: + goos: [linux, windows] + goarch: [amd64, arm64] + gover: ['1.23.1', 'oldstable'] + exclude: + - goarch: arm64 + goos: windows + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.gover }} + - name: install-tools + run: | + apt-get update -y + apt-get install -y protobuf-compiler + go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.0 + - name: protobuf-gen + run: | + protoc --go_out=. ./assets/protobuf/*.proto + - name: build + run: | + GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} go build -x . + diff --git a/.gitignore b/.gitignore index 1b1402c..0be7c57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,2 @@ -out/ -build/ -cmake-kits.json -.cache/ -.idea -compile_commands.json -*.a +catsync +pb/ diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index e69de29..0000000 diff --git a/assets/protobuf/peer_message.proto b/assets/protobuf/peer_message.proto new file mode 100644 index 0000000..7dc567c --- /dev/null +++ b/assets/protobuf/peer_message.proto @@ -0,0 +1,20 @@ +syntax="proto3"; +package main; +option go_package = "/pb"; + +import public "google/protobuf/timestamp.proto"; + +message PeerMessage { + uint32 magic_number= 1; + uint32 version = 2; + PeerMessageType type = 3; + google.protobuf.Timestamp send_timestamp = 4; + + string uid = 5; +} + +enum PeerMessageType { + PEER_MESSAGE_TYPE_REQUEST = 0; + PEER_MESSAGE_TYPE_RESPONSE = 1; + PEER_MESSAGE_TYPE_ACK = 2; +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3efdae4 --- /dev/null +++ b/go.mod @@ -0,0 +1,7 @@ +module code.uocat.com/tqcq/catsync + +go 1.23.3 + +require ( + google.golang.org/protobuf v1.36.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d093a77 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ= +google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= diff --git a/main.go b/main.go new file mode 100644 index 0000000..a85f627 --- /dev/null +++ b/main.go @@ -0,0 +1,96 @@ +package main + +import ( + "code.uocat.com/tqcq/catsync/pb" + "context" + "fmt" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/timestamppb" + "net" + "sync" + "time" +) + +var ( + PeerList = make(map[string]net.UDPAddr) +) + +func LANServer(ctx context.Context, conn *net.UDPConn) { + + var wait_group sync.WaitGroup + defer wait_group.Wait() + for { + buf := make([]byte, 1024) + n, remote_addr, err := conn.ReadFromUDP(buf) + if err != nil { + fmt.Printf("Recv failed. %v\n", err) + continue + } + if n != 0 { + // process request + wait_group.Add(1) + go func() { + defer wait_group.Done() + + fmt.Printf("remote_addr: %s\n", remote_addr.AddrPort().String()) + pm := &pb.PeerMessage{} + err := proto.Unmarshal(buf[:n], pm) + if err != nil { + fmt.Printf("Unmarshal failed. %v\n", err) + return + } + + fmt.Printf("uid: %s, send_timestamp: %s\n", pm.Uid, pm.SendTimestamp.AsTime().Local()) + }() + continue + } + } +} + +func LANClient(ctx context.Context, conn *net.UDPConn) { + broadcast_addr, err := net.ResolveUDPAddr("udp4", "255.255.255.255:8829") + if err != nil { + fmt.Printf("err: %v", err) + return + } + + for { + pm := &pb.PeerMessage{ + MagicNumber: 13, + Version: 0, + SendTimestamp: timestamppb.Now(), + Type: pb.PeerMessageType_PEER_MESSAGE_TYPE_REQUEST, + Uid: "test uid", + } + buf, err := proto.Marshal(pm) + if err != nil { + fmt.Printf("err: %v\n", err) + } else { + _, _ = conn.WriteToUDP(buf, broadcast_addr) + } + time.Sleep(5 * time.Second) + } +} + +func main() { + listenAddr, err := net.ResolveUDPAddr("udp4", ":8829") + if err != nil { + fmt.Printf("ResolveUDPAddr failed. %v\n", err) + return + } + broadcastServer, err := net.ListenUDP("udp4", listenAddr) + if err != nil { + fmt.Printf("ListenUDP Failed. %v\n", err) + return + } + defer broadcastServer.Close() + fmt.Printf("Server Started.\n") + + ctx := context.Background() + go LANServer(ctx, broadcastServer) + go LANClient(ctx, broadcastServer) + select { + case <-ctx.Done(): + fmt.Printf("ctx Done: %v", <-ctx.Done()) + } +}