Last active
August 29, 2015 14:05
-
-
Save furu/dde894cc059bfd2c5c12 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"net" | |
"os" | |
"os/signal" | |
"reflect" | |
"syscall" | |
) | |
func handleTCPClient(conn net.Conn) { | |
defer conn.Close() | |
// http://naoina.plog.la/2013/11/12/235753683181 | |
// http://walf443.hatenablog.com/entry/2014/05/13/105216 | |
fdValue := reflect.Indirect(reflect.Indirect(reflect.ValueOf(conn)).FieldByName("fd")) | |
fd := fdValue.FieldByName("sysfd").Int() | |
syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_SETOWN, uintptr(os.Getpid())) | |
go func() { | |
c := make(chan os.Signal, 1) | |
signal.Notify(c, syscall.SIGURG) | |
for { | |
log.Println("^o^ < Waiting for signal") | |
sig := <-c // シグナルが発生するまでブロックされる | |
switch sig { | |
case syscall.SIGURG: | |
log.Println("^o^ = ^o^ < Occuring a signal!: ", sig) | |
// OOB データは 1byte しか受け取れない? | |
oobData := make([]byte, 1) | |
n, _, err := syscall.Recvfrom(int(fd), oobData, syscall.MSG_OOB) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
fmt.Printf("Recieved OOB data '%s' (%d byte)\n", oobData, n) | |
} | |
} | |
}() | |
for { | |
mess := make([]byte, 256) | |
_, err := conn.Read(mess) // OOBデータを受け取って、上のシグナルハンドラーを実行した後に、ここでブロックしている? | |
if err != nil { | |
log.Println(err) | |
break | |
} | |
fmt.Println(string(mess)) | |
} | |
log.Printf("Finish handling %v\n", conn.RemoteAddr()) | |
} | |
func main() { | |
listener, err := net.Listen("tcp", net.JoinHostPort("localhost", "4545")) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
defer listener.Close() | |
log.Printf("Listening on %v\n", listener.Addr()) | |
for { | |
conn, err := listener.Accept() | |
if err != nil { | |
log.Println(err) | |
continue | |
} | |
log.Printf("Handling Client %v\n", conn.RemoteAddr()) | |
go handleTCPClient(conn) | |
} | |
} | |
// syscall | |
// | |
// func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) | |
// | |
// func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"net" | |
"os" | |
"os/signal" | |
"reflect" | |
"syscall" | |
"time" | |
) | |
func main() { | |
conn, err := net.Dial("tcp", net.JoinHostPort("localhost", "4545")) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
defer conn.Close() | |
log.Printf("Connected to %v\n", conn.RemoteAddr()) | |
go func() { | |
c := make(chan os.Signal, 1) | |
signal.Notify(c, os.Interrupt) | |
for { | |
sig := <-c // シグナルが発生するまでブロックされる | |
switch sig { | |
case os.Interrupt: | |
// http://naoina.plog.la/2013/11/12/235753683181 | |
// http://walf443.hatenablog.com/entry/2014/05/13/105216 | |
fdValue := reflect.Indirect(reflect.Indirect(reflect.ValueOf(conn)).FieldByName("fd")) | |
fd := int(fdValue.FieldByName("sysfd").Int()) | |
to, err := syscall.Getpeername(fd) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
// OOB データは 1byte しか送れない? | |
// 受信側では、256byte 分のバッファを用意して、^o^ というメッセージを送ったが、 | |
// ^ しか受け取れなかった。 | |
oobData := []byte("!") | |
err = syscall.Sendto(fd, oobData, syscall.MSG_OOB, to) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
log.Println("Sent OOB data") | |
} | |
} | |
}() | |
for i := 0; i < 30; i++ { | |
fmt.Fprint(conn, i) | |
log.Println("Sent: ", i) | |
time.Sleep(1 * time.Second) | |
} | |
log.Printf("Disconnected from %v\n", conn.RemoteAddr()) | |
} | |
// syscall | |
// | |
// func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) | |
// | |
// func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) | |
// | |
// func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) | |
// | |
// Sockaddr型はインタフェースだけれど、何を実装すればよいのか公開されていない | |
// | |
// type Sockaddr interface { | |
// // contains filtered or unexported methods | |
// } | |
// | |
// Sockaddr のドキュメントの下に、Getpeername() と Getsockname() という関数があって、 | |
// どちらもファイルディスクリプタを引数に取って、Sockaddr型を返すようになっている。 | |
// | |
// func Getpeername(fd int) (sa Sockaddr, err error) | |
// func Getsockname(fd int) (sa Sockaddr, err error) | |
// | |
// 違いがよくわからなくてどちらを使えばよいのかわからないが、とりあえず Sockaddr型が欲しいので、 | |
// どっちかを使う。 | |
// | |
// | |
// OOBデータ - out-of-band data | |
// | |
// * 名前から、普通のデータストリームの外側から送られてくるように思えるけれど、そうではないらしい。 | |
// * 1度に1byteだけ送ることができるらしい。複数(多バイト?)送った場合、最後のものが受け取られる? | |
// * one urgent pointer per stream |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
oob_reciever.go
が期待する動作にならない…