You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
4.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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