| @ -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) | |||||
| } | |||||
| } | |||||