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