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.

590 lines
13 KiB

1 year ago
package netProgram
import (
1 year ago
"encoding/gob"
"errors"
"fmt"
"io"
1 year ago
"log"
1 year ago
"math/rand"
1 year ago
"net"
1 year ago
"os"
1 year ago
"sync"
"time"
)
// 客户端
func TcpClient() {
// tcp服务端地址
//serverAddress := "127.0.0.1:5678"
// tcp协议类型
serverAddress := "[::1]:5678" // IPv6
//serverAddress := "127.0.0.1:5678" // IPv4
// 模拟多客户端
// 并发的客户端请求
num := 10
wg := sync.WaitGroup{}
wg.Add(num)
for i := 0; i < num; i++ {
// 并发请求
go func(wg *sync.WaitGroup) {
defer wg.Done()
// A. 建立连接
conn, err := net.Dial(tcp, serverAddress)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
}(&wg)
}
wg.Wait()
}
func TcpTimeoutClient() {
// tcp服务端地址
serverAddress := "192.168.110.123:5678" // IPv6 4
// 模拟多客户端
// 并发的客户端请求
num := 10
wg := sync.WaitGroup{}
wg.Add(num)
for i := 0; i < num; i++ {
// 并发请求
go func(wg *sync.WaitGroup) {
defer wg.Done()
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
//conn, err := net.Dial(tcp, serverAddress)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
}(&wg)
}
wg.Wait()
}
func TcpBacklogClient() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// 模拟多客户端
// 并发的客户端请求
num := 256
wg := sync.WaitGroup{}
wg.Add(num)
for i := 0; i < num; i++ {
// 并发请求
go func(wg *sync.WaitGroup, no int) {
defer wg.Done()
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
//conn, err := net.Dial(tcp, serverAddress)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("%d: connection is establish, client addr is %s\n", no, conn.LocalAddr())
}(&wg, i)
time.Sleep(30 * time.Millisecond)
}
wg.Wait()
}
1 year ago
func TcpClientRW() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
//conn, err := net.Dial(tcp, serverAddress)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
// B.从服务端接收数据SerRead
buf := make([]byte, 1024)
rn, err := conn.Read(buf)
if err != nil {
log.Println(err)
}
log.Println("received from server data is:", string(buf[:rn]))
// C.向服务器端发送数据SerWrite
wn, err := conn.Write([]byte("send some data from client" + "\n"))
if err != nil {
log.Println(err)
}
log.Printf("client write len is %d\n", wn)
}
func TcpWClient() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
//conn, err := net.Dial(tcp, serverAddress)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
//
//select {}
// 1. 阻塞Read
//buf := make([]byte, 1024)
//rn, err := conn.SerRead(buf)
//if err != nil {
// log.Println(err)
//}
//log.Println("received from server data is:", string(buf[:rn]))
// 2. 循环读
conn.SetReadDeadline(time.Now().Add(10 * time.Second))
for {
buf := make([]byte, 10)
rn, err := conn.Read(buf)
if err != nil {
log.Println(err)
break
}
log.Println("received from server data is:", string(buf[:rn]))
}
}
func TcpClientRWConcurrency() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
//conn, err := net.Dial(tcp, serverAddress)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
wg := sync.WaitGroup{}
// 并发的写
wg.Add(1)
go CliWrite(conn, &wg)
// 并发的读
wg.Add(1)
go CliRead(conn, &wg)
wg.Wait()
}
func CliWrite(conn net.Conn, wg *sync.WaitGroup) {
defer wg.Done()
for {
// B.向客户端发送数据SerWrite
wn, err := conn.Write([]byte("send some data from client" + "\n"))
if err != nil {
log.Println(err)
}
log.Printf("client write len is %d\n", wn)
time.Sleep(3 * time.Second)
}
}
func CliRead(conn net.Conn, wg *sync.WaitGroup) {
defer wg.Done()
for {
// C.从客户端接收数据SerRead
buf := make([]byte, 1024)
rn, err := conn.Read(buf)
if err != nil {
log.Println(err)
}
log.Println("received from server data is:", string(buf[:rn]))
}
}
func TcpClientFormat() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
//conn, err := net.Dial(tcp, serverAddress)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
wg := sync.WaitGroup{}
// 接收端
wg.Add(1)
go CliReadFormat(conn, &wg)
wg.Wait()
}
func CliReadFormat(conn net.Conn, wg *sync.WaitGroup) {
defer wg.Done()
for {
// 从客户端接收数据
// 接收到数据后,先解码
// 传递的消息类型
type Message struct {
ID uint `json:"id,omitempty"`
Code string `json:"code,omitempty"`
Content string `json:"content,omitempty"`
}
message := Message{}
// 1, JSON解码
//// 创建解码器
//decoder := json.NewDecoder(conn)
//// 利用解码器进行解码
//// 解码操作从conn中读取内容成功会将解码后的结果赋值到message变量
//if err := decoder.Decode(&message); err != nil {
// log.Println(err)
// continue
//}
//log.Println(message)
// 2, GOB解码
// 创建解码器
decoder := gob.NewDecoder(conn)
// 利用解码器进行解码
// 解码操作从conn中读取内容成功会将解码后的结果赋值到message变量
if err := decoder.Decode(&message); err != nil {
log.Println(err)
continue
}
log.Println(message)
}
}
// 短连接示例
func TcpClientSort() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
wg := sync.WaitGroup{}
// 接收端
wg.Add(1)
go CliReadSort(conn, &wg)
wg.Wait()
}
func CliReadSort(conn net.Conn, wg *sync.WaitGroup) {
defer wg.Done()
// 传递的消息类型
type Message struct {
ID uint `json:"id,omitempty"`
Code string `json:"code,omitempty"`
Content string `json:"content,omitempty"`
}
message := Message{}
for {
// 从客户端接收数据
// 接收到数据后,先解码
// GOB解码
// 创建解码器
decoder := gob.NewDecoder(conn)
// 利用解码器进行解码
// 解码操作从conn中读取内容成功会将解码后的结果赋值到message变量
err := decoder.Decode(&message)
// 错误 io.EOF 时,表示连接被给关闭
if err != nil && errors.Is(err, io.EOF) {
log.Println(err)
log.Println("link was closed")
break
}
log.Println(message)
}
}
// 响应服务端的心跳检测
func TcpClientHB() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
wg := sync.WaitGroup{}
// 接收端
wg.Add(1)
go CliReadPing(conn, &wg)
wg.Wait()
}
// 传递的消息类型
type MessageHB struct {
ID uint `json:"id,omitempty"`
Code string `json:"code,omitempty"`
Content string `json:"content,omitempty"`
Time time.Time `json:"time,omitempty"`
}
func CliReadPing(conn net.Conn, wg *sync.WaitGroup) {
defer wg.Done()
// 传递的消息类型
message := MessageHB{}
for {
// GOB解码
decoder := gob.NewDecoder(conn)
// 解码操作从conn中读取内容成功会将解码后的结果赋值到message变量
err := decoder.Decode(&message)
// 错误 io.EOF 时,表示连接被给关闭
if err != nil && errors.Is(err, io.EOF) {
log.Println(err)
break
}
// 判断是为为 ping 类型消息
if message.Code == "PING-SERVER" {
log.Println("receive ping from", conn.RemoteAddr())
CliWritePong(conn, message)
}
}
}
func CliWritePong(conn net.Conn, pingMsg MessageHB) {
pongMsg := MessageHB{
ID: uint(rand.Int()),
Code: "PONG-CLIENT",
Content: fmt.Sprintf("pingID:%d", pingMsg.ID),
Time: time.Now(),
}
// GOB, 二进制编码
// 创建编码器
encoder := gob.NewEncoder(conn)
// 利用编码器进行编码
// encode 成功后会写入到conn已经完成了conn.Write()
if err := encoder.Encode(pongMsg); err != nil {
log.Println(err)
return
}
log.Println("pong was send to", conn.RemoteAddr())
return
}
// 连接池使用
func TcpClientPool() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// A建立连接池
pool, err := NewTcpPool(serverAddress, PoolConfig{
Factory: &TcpConnFactory{},
InitConnNum: 4,
})
if err != nil {
log.Fatalln(err)
}
1 year ago
log.Println(pool, pool.Len())
1 year ago
wg := sync.WaitGroup{}
clientNum := 50
wg.Add(clientNum)
// B, 复用连接池中的连接
for i := 0; i < clientNum; i++ {
// goroutine 模拟独立的客户端
go func(wg *sync.WaitGroup) {
defer wg.Done()
// 获取连接
conn, err := pool.Get()
if err != nil {
log.Println(err)
return
}
//log.Println(conn)
// 回收连接
pool.Put(conn)
}(&wg)
}
wg.Wait()
1 year ago
// 释放连接池
pool.Release()
log.Println(pool, pool.idleList, pool.Len())
}
// 粘包
func TcpClientSticky() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
//conn, err := net.Dial(tcp, serverAddress)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
// 从服务端接收数据SerRead
buf := make([]byte, 1024)
for {
rn, err := conn.Read(buf)
if err != nil {
log.Println(err)
break
}
log.Println("received data:", string(buf[:rn]))
}
}
// 粘包,编解码器解决
func TcpClientCoder() {
// tcp服务端地址
serverAddress := "127.0.0.1:5678" // IPv6 4
// A. 建立连接
conn, err := net.DialTimeout(tcp, serverAddress, time.Second)
//conn, err := net.Dial(tcp, serverAddress)
if err != nil {
log.Println(err)
return
}
// 保证关闭
defer conn.Close()
log.Printf("connection is establish, client addr is %s\n", conn.LocalAddr())
// 从服务端接收数据SerRead
// 创建解码器
decoder := NewDecoder(conn)
data := ""
i := 0
for {
// 错误 io.EOF 时,表示连接被给关闭
if err := decoder.Decode(&data); err != nil {
log.Println(err)
break
}
log.Println(i, "received data:", data)
i++
}
}
func TcpClientSpecial() {
// 1建立连接
// raddr remote addr服务端的地址
raddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:5678")
if err != nil {
log.Fatalln(err)
}
// laddr, local addr, 客户端的地址,可以用于设置客户端的端口
tcpConn, err := net.DialTCP("tcp", nil, raddr)
if err != nil {
log.Fatalln(err)
}
// 保证关闭
defer tcpConn.Close()
log.Printf("connection is establish, client addr is %s\n", tcpConn.LocalAddr())
// 2读写数据
buf := make([]byte, 1024)
for {
n, err := tcpConn.Read(buf)
if err != nil {
log.Println(err)
return
}
log.Println("receive len:", n)
log.Println("receive data:", string(buf[:n]))
}
}
func TcpFileClient() {
// 1建立连接
tcpConn, err := net.Dial("tcp", "192.168.50.131:5678")
if err != nil {
log.Fatalln(err)
}
// 保证关闭
defer tcpConn.Close()
log.Printf("connection is establish, client addr is %s\n", tcpConn.LocalAddr())
// 1.获取文件信息
filename := "./data/Beyond.mp3"
// 打开文件
file, err := os.Open(filename)
if err != nil {
log.Fatalln(err)
}
// 关闭文件
defer file.Close()
buf := make([]byte, 1024)
for {
// 读取文件内容
rn, err := file.Read(buf)
if err != nil {
// io.EOF 错误表示文件读取完毕
if err == io.EOF {
break
}
log.Fatalln(err)
}
// 发送到服务端
if _, err := tcpConn.Write(buf[:rn]); err != nil {
log.Fatalln(err)
}
}
log.Println("file send complete.")
1 year ago
}