Skip to content

Add example/singleapp/unix/socket/01.basic #819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/singleapp/unix/socket/01.basic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
./bin
31 changes: 31 additions & 0 deletions examples/singleapp/unix/socket/01.basic/Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# https://taskfile.dev

version: '3'

tasks:
default:
cmds:
- task: run
fmt:
cmds:
- goimports -w .
prepare:
cmds:
- mkdir -p bin
build:
deps: [ fmt ]
cmds:
- go build -o bin/server server/server.go
- go build -o bin/client client/client.go
run:
deps: [ build ]
cmds:
- ./bin/server &
- sleep 1
- ./bin/client
- sleep 1
- pgrep server && pkill server
ignore_error: true
clean:
cmds:
- rm -rf ./bin
81 changes: 81 additions & 0 deletions examples/singleapp/unix/socket/01.basic/client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//go:build linux

package main

import (
"log"
"net"

"golang.org/x/sys/unix"
)

func init() {
log.SetFlags(log.Lmicroseconds)
}

func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}

func run() error {
var (
sfd int
err error
)

sfd, err = unix.Socket(unix.AF_INET, unix.SOCK_STREAM, unix.IPPROTO_TCP)
if err != nil {
return err
}
defer func() {
log.Println("[CLIENT] ソケットクローズ")
unix.Close(sfd)
}()

var (
ip = net.ParseIP("127.0.0.1")
ipv4 [4]byte

sAddr unix.Sockaddr
)
copy(ipv4[:], ip.To4())

sAddr = &unix.SockaddrInet4{Port: 8888, Addr: ipv4}
err = unix.Connect(sfd, sAddr)
if err != nil {
return err
}

//
// Send
//
var (
buf = make([]byte, 2048)
msg = "helloworld"
)
copy(buf, []byte(msg))

err = unix.Send(sfd, buf[:len(msg)], 0)
if err != nil {
return err
}

//
// Recv
//
var (
n int
)
clear(buf)

n, err = unix.Read(sfd, buf)
if err != nil {
return err
}

log.Printf("[CLIENT] %s", buf[:n])

return nil
}
136 changes: 136 additions & 0 deletions examples/singleapp/unix/socket/01.basic/server/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//go:build linux

package main

import (
"errors"
"log"
"net"

"golang.org/x/sys/unix"
)

func init() {
log.SetFlags(log.Lmicroseconds)
}

func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}

func run() error {
//
// Create
//
var (
sfd int
err error
)

sfd, err = unix.Socket(unix.AF_INET, unix.SOCK_STREAM, unix.IPPROTO_TCP)
if err != nil {
return err
}
defer func() {
log.Println("[SERVER] サーバーソケットクローズ")
unix.Close(sfd)
}()

//
// Bind and Listen
//
var (
ip = net.ParseIP("127.0.0.1")
ipv4 [4]byte

sAddr unix.Sockaddr
backLog = 2
)
copy(ipv4[:], ip.To4())

sAddr = &unix.SockaddrInet4{Port: 8888, Addr: ipv4}
err = unix.Bind(sfd, sAddr)
if err != nil {
return err
}

err = unix.Listen(sfd, backLog)
if err != nil {
return err
}

//
// Accept
//
var (
cfd int
cAddr unix.Sockaddr
)

cfd, cAddr, err = unix.Accept(sfd)
if err != nil {
return err
}
defer func() {
log.Println("[SERVER] パケット送受信用ソケットクローズ")
unix.Close(cfd)
}()

cAddrInet4 := cAddr.(*unix.SockaddrInet4)
log.Printf("[SERVER] Connect from %v:%v", cAddrInet4.Addr, cAddrInet4.Port)

//
// Recv
//
var (
buf = make([]byte, 2048)
n int
)

n, err = unix.Read(cfd, buf)
if err != nil {
return err
}

log.Printf("[SERVER] %s", string(buf[:n]))

//
// Send
//
var (
msg = "HELLOWORLD"
)

clear(buf)
copy(buf, []byte(msg))

err = unix.Send(cfd, buf[:len(msg)], 0)
if err != nil {
return err
}

//
// Disconnect detection
//
LOOP:
for {
clear(buf)

n, err = unix.Read(cfd, buf)
switch {
case n == 0:
log.Println("[SERVER] 切断検知 (0 byte read)")
break LOOP
case err != nil:
var sysErr unix.Errno
if errors.As(err, &sysErr); sysErr == unix.ECONNRESET {
log.Printf("[SERVER] 切断検知 (%s)", sysErr)
break LOOP
}
}
}

return nil
}
Loading