| @ -0,0 +1,177 @@ | |||
| package main | |||
| import ( | |||
| "encoding/binary" | |||
| "fmt" | |||
| "github.com/pborman/getopt/v2" | |||
| "io" | |||
| "io/ioutil" | |||
| "net" | |||
| "os" | |||
| "strings" | |||
| "time" | |||
| ) | |||
| const HeadSize int = 4 | |||
| func initServer(network,addr string) net.Listener { | |||
| listener,err := net.Listen(network,addr) | |||
| if err != nil { | |||
| fmt.Println("Listener for",addr) | |||
| } | |||
| return listener | |||
| } | |||
| func testServer(listener net.Listener) { | |||
| defer listener.Close() | |||
| for { | |||
| unixConn, err := listener.Accept() | |||
| if err != nil { | |||
| continue | |||
| //return | |||
| } | |||
| fmt.Println("A client connected : " + unixConn.RemoteAddr().String()) | |||
| unixPipe(unixConn) | |||
| } | |||
| } | |||
| func unixPipe(conn io.ReadWriteCloser) { | |||
| defer conn.Close() | |||
| buf := make([]byte,1024*1024*10) | |||
| for { | |||
| conn.Read(buf[:HeadSize]) | |||
| payloadLength := binary.LittleEndian.Uint32(buf) | |||
| length,err := conn.Read(buf[HeadSize : HeadSize+int(payloadLength)]) | |||
| if err != nil { | |||
| if err == io.EOF { | |||
| fmt.Println("read from client error=", err, "need to read len=", payloadLength) | |||
| } else { | |||
| fmt.Println("client disconnected=", err, "need to read len=", payloadLength) | |||
| } | |||
| return | |||
| } | |||
| buf[0] = '@' | |||
| buf[1] = '#' | |||
| conn.Write(buf[:HeadSize+length]) | |||
| fmt.Println(time.Now(),"received len=",length) | |||
| } | |||
| } | |||
| func initClient(network,addr string) io.ReadWriteCloser{ | |||
| conn, err := net.Dial(network, addr) | |||
| if err != nil { | |||
| fmt.Println("dialUnix err=", err) | |||
| } | |||
| fmt.Println("connected!") | |||
| return conn | |||
| } | |||
| func testClient(conn io.ReadWriteCloser,content []byte,count int) { | |||
| data := make([]byte, HeadSize+len(content)) | |||
| dataLength := uint32(len(content)) | |||
| binary.LittleEndian.PutUint32(data,dataLength) | |||
| copy(data[HeadSize:], content) | |||
| fmt.Println("client will send",data) | |||
| buf := make([]byte,1024*1024*10) | |||
| var max,sum time.Duration | |||
| var min = time.Second * 100 | |||
| for i := 0; i < count;i++ { | |||
| begin := time.Now() | |||
| conn.Write(data) | |||
| length, err := conn.Read(buf[:len(data)]) | |||
| if err != nil { | |||
| fmt.Println("read from server, error=",err) | |||
| return | |||
| } | |||
| elapsed := time.Since(begin) | |||
| if max < elapsed { | |||
| max = elapsed | |||
| } | |||
| if min > elapsed { | |||
| min = elapsed | |||
| } | |||
| sum += elapsed | |||
| fmt.Println("read use ",elapsed,"length=",length,buf[0],buf[1]) | |||
| time.Sleep(time.Millisecond *100) | |||
| } | |||
| ave := time.Duration(int64(sum) / 1000) | |||
| fmt.Println("total use ","max=",max,"min=",min,"ave=",ave) | |||
| } | |||
| func main() { | |||
| // Declare the flags to be used | |||
| helpFlag := getopt.Bool('h', "display help") | |||
| serverFlag := getopt.BoolLong("server", 's', "", "the command") | |||
| addrString := getopt.StringLong("address", 'a', "/tmp/unix_sock", "address") | |||
| countFlag := getopt.IntLong("count", 'c',1,"test count of loop") | |||
| textFlag := getopt.StringLong("text", 't',"00112233445566778899","text to send") | |||
| fileFlag := getopt.StringLong("file", 'f',"","read data from file to send") | |||
| //repeatFlag := getopt.StringLong("retransmit", 'r',"","address for retransmit data to next node") | |||
| //:= getopt.BoolLong("server", 's', "", "the command") | |||
| // Parse the program arguments | |||
| getopt.Parse() | |||
| // Get the remaining positional parameters | |||
| //args := getopt.Args() | |||
| if *helpFlag { | |||
| getopt.PrintUsage(os.Stdout) | |||
| return | |||
| } | |||
| var network string | |||
| isUnixDomain := strings.ContainsRune(*addrString,'/') | |||
| if !isUnixDomain { | |||
| network = "tcp" | |||
| } else { | |||
| network = "unix" | |||
| if *serverFlag { | |||
| os.Remove(*addrString) | |||
| } | |||
| } | |||
| sendContent := []byte(*textFlag) | |||
| fmt.Println("It will use :",network,*addrString) | |||
| if len(*fileFlag) > 0 { | |||
| f , err := os.Open(*fileFlag) | |||
| if err != nil { | |||
| fmt.Println("open file",*fileFlag,err) | |||
| return | |||
| } | |||
| sendContent,err = ioutil.ReadAll(f) | |||
| if err != nil { | |||
| fmt.Println("read file",*fileFlag,err) | |||
| return | |||
| } | |||
| } | |||
| if *serverFlag { | |||
| listener := initServer(network,*addrString) | |||
| defer listener.Close() | |||
| testServer(listener) | |||
| } else { | |||
| conn := initClient(network,*addrString) | |||
| defer conn.Close() | |||
| testClient(conn,sendContent,*countFlag) | |||
| } | |||
| } | |||