package netProgram import ( "log" "net" "sync" "time" ) // 网络轮询器 // 网络IO(使用系统调用syscall的IO)的阻塞 func BIONet() { addr := "127.0.0.1:5678" wg := sync.WaitGroup{} // 1模拟读,体会读的阻塞状态 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() conn, _ := net.Dial("tcp", addr) defer conn.Close() buf := make([]byte, 1024) // 注意:两次时间的间隔 log.Println("start read.", time.Now().Format("03:04:05.000")) n, _ := conn.Read(buf) log.Println("content:", string(buf[:n]), time.Now().Format("03:04:05.000")) }(&wg) // 2模拟写 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() l, _ := net.Listen("tcp", addr) defer l.Close() for { conn, _ := l.Accept() go func(conn net.Conn) { defer conn.Close() log.Println("connected.") // 阻塞时长 time.Sleep(3 * time.Second) conn.Write([]byte("Blocking I/O")) }(conn) } }(&wg) wg.Wait() } // Channel(Go的自管理的IO)的阻塞 func BIOChannel() { // 0初始化数据 wg := sync.WaitGroup{} // IO channel ch := make(chan struct{}) // 1模拟读,体会读的阻塞状态 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() log.Println("start read.", time.Now().Format("03:04:05.000")) content := <-ch // IO Read, Receive log.Println("content:", content, time.Now().Format("03:04:05.000")) }(&wg) // 2模拟写 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() // 阻塞时长 time.Sleep(3 * time.Second) ch <- struct{}{} // Write, Send }(&wg) wg.Wait() } // 网络IO(使用系统调用syscall的IO)的非阻塞 func NIONet() { addr := "127.0.0.1:5678" wg := sync.WaitGroup{} // 1模拟读,体会读的阻塞状态 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() conn, _ := net.Dial("tcp", addr) defer conn.Close() buf := make([]byte, 1024) // 注意:两次时间的间隔 log.Println("start read.", time.Now().Format("03:04:05.000")) // 设置截止时间 conn.SetReadDeadline(time.Now().Add(400 * time.Millisecond)) n, _ := conn.Read(buf) log.Println("content:", string(buf[:n]), time.Now().Format("03:04:05.000")) }(&wg) // 2模拟写 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() l, _ := net.Listen("tcp", addr) defer l.Close() for { conn, _ := l.Accept() go func(conn net.Conn) { defer conn.Close() log.Println("connected.") // 阻塞时长 time.Sleep(3 * time.Second) conn.Write([]byte("Blocking I/O")) }(conn) } }(&wg) wg.Wait() } // Channel(Go的自管理的IO)的非阻塞 func NIOChannel() { // 0初始化数据 wg := sync.WaitGroup{} // IO channel ch := make(chan struct{ id uint }) // 1模拟读,体会读的阻塞状态 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() log.Println("start read.", time.Now().Format("03:04:05.000")) content := struct{ id uint }{} select { case content = <-ch: // IO Read, Receive default: } log.Println("content:", content, time.Now().Format("03:04:05.000")) }(&wg) // 2模拟写 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() // 阻塞时长 time.Sleep(3 * time.Second) ch <- struct{ id uint }{42} // Write, Send }(&wg) wg.Wait() } // 网络IO(使用系统调用syscall的IO)的非阻塞 func NIONetChannel() { addr := "127.0.0.1:5678" wg := sync.WaitGroup{} // 1模拟读,体会读的阻塞状态 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() conn, _ := net.Dial("tcp", addr) defer conn.Close() // 注意:两次时间的间隔 log.Println("start read.", time.Now().Format("03:04:05.000")) // 独立的goroutine,完成Read操作,将结果Send到channel中 wgwg := sync.WaitGroup{} chRead := make(chan []byte) wgwg.Add(1) go func() { defer wgwg.Done() buf := make([]byte, 1024) n, _ := conn.Read(buf) chRead <- buf[:n] }() //time.Sleep(100 * time.Millisecond) // 是select+default实现非阻塞操作 var data []byte select { case data = <-chRead: default: } log.Println("content:", string(data), time.Now().Format("03:04:05.000")) wgwg.Wait() }(&wg) // 2模拟写 wg.Add(1) go func(wg *sync.WaitGroup) { defer wg.Done() l, _ := net.Listen("tcp", addr) defer l.Close() for { conn, _ := l.Accept() go func(conn net.Conn) { defer conn.Close() log.Println("connected.") // 阻塞时长 time.Sleep(3 * time.Second) conn.Write([]byte("Blocking I/O")) }(conn) } }(&wg) wg.Wait() }