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

1 year ago
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()
}