GO使用TCP长连接
  DLjUyo7XFbHQ 2023年11月02日 31 0

1,TCP服务器端

package main

import (
	"fmt"
	"net"
	"os"
	"os/signal"
	"sync"
	"sync/atomic"
	"syscall"
)

var (
	connIDCounter uint64
	connIDLock    sync.Mutex
)

// 线程安全的map
var hashMap = sync.Map{}

// 线程安全的自增
func generateConnID() uint64 {
	atomic.AddUint64(&connIDCounter, 1)
	return atomic.LoadUint64(&connIDCounter)
}
func main() {
	// 监听指定的TCP地址和端口
	listener, err := net.Listen("tcp", "localhost:8080")
	if err != nil {
		fmt.Println("启动错误:", err.Error())
		return
	}

	// 创建一个通道来接收信号
	sigCh := make(chan os.Signal, 1)
	// 监听指定的信号
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

	// 启动一个 goroutine 来处理接收到的信号
	go func() {
		// 等待信号
		sig := <-sigCh
		fmt.Printf("接收到信号:%v\n", sig)

		defer func(listener net.Listener) {
			err := listener.Close()
			if err != nil {

			}
		}(listener)
		// 在这里编写你的程序逻辑
		fmt.Printf("关闭程序")
		// 退出程序
		os.Exit(0)
	}()
	fmt.Println("服务器启动成功 localhost:8080")

	for {
		// 接受客户端连接
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("Error accepting connection链接异常:", err.Error())
			return
		}

		// 处理连接
		go handleConnection(conn)
	}
}

func handleConnection(conn net.Conn) {
	connID := generateConnID()
	fmt.Printf("Connection ID: %d\n", connID)
	hashMap.Store(conn, connID)
	// 循环接收新消息
	for {
		// 获取值
		value, ok := hashMap.Load(conn)
		if ok {
			//fmt.Println("Value:", value)
		}
		// 接收数据
		buffer := make([]byte, 1024)
		_, err := conn.Read(buffer)
		if err != nil {
			fmt.Println("客户端关闭链接:", value, err.Error())
			err := conn.Close()
			if err != nil {
				return
			}
			return
		}

		// 处理接收到的数据
		data := string(buffer)

		fmt.Println("收到客户端消息:", value, data)

		// 发送数据
		response := "Hello, client!"
		_, err = conn.Write([]byte(response))
		if err != nil {
			fmt.Println("客户端关闭链接:", value, err.Error())
			err := conn.Close()
			if err != nil {
				return
			}
			return
		}
	}
}

2,TCP客户端

package main

import (
	"fmt"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	fmt.Println("连接开始:")
	for i := 0; i < 10; i++ {
		go client()
		//time.Sleep(time.Second * 1) // 阻塞1秒
	}
	//阻止main函数执行完毕
	for {
		time.Sleep(time.Second * 10) // 阻塞1秒
	}

}
func client() {
	// 建立TCP连接
	conn, err := net.Dial("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println("连接失败:", err)
		return
	}
	fmt.Println("连接成功:")
	// 创建一个通道来接收信号
	sigCh := make(chan os.Signal, 1)
	// 监听指定的信号
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

	// 启动一个 goroutine 来处理接收到的信号
	go func() {
		// 等待信号
		sig := <-sigCh
		fmt.Printf("接收到信号:%v\n", sig)

		err := conn.Close()
		if err != nil {
			return
		}
		// 在这里编写你的程序逻辑
		fmt.Printf("关闭程序")
		// 退出程序
		os.Exit(0)
	}()
	go handleConnection(conn)
	for {
		time.Sleep(time.Second * 1) // 阻塞1秒
		// 发送消息
		message := "Hello, Server!"
		_, err = conn.Write([]byte(message))
		if err != nil {
			fmt.Println("发送消息失败:", err)
			return
		}

		fmt.Println("消息发送成功:", message)
	}
}
func handleConnection(conn net.Conn) {
	for {
		// 接收数据
		buffer := make([]byte, 1024)
		_, err := conn.Read(buffer)
		if err != nil {
			fmt.Println("Error reading:", err.Error())
			return
		}

		// 处理接收到的数据
		data := string(buffer)
		fmt.Println("收到服务器消息:", data)
	}

}

3,先启动tcpServer.go,在启动tcpClient.go 就可以看效果了

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
DLjUyo7XFbHQ