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 就可以看效果了