TCP 服务端
package main
import (
"fmt"
"net"
)
var serverChan chan bool = make(chan bool, 1)
func OpenTcpSever(ipAndPort string) {
var err error
var tcpListener net.Listener
tcpListener, err = net.Listen("tcp", ipAndPort)
if err != nil {
serverChan <- false
return
}
defer tcpListener.Close()
serverChan <- true
for {
con, err := tcpListener.Accept()
if err != nil {
continue
}
fmt.Println(con.RemoteAddr(), "客户端连接成功.")
go AccessClient(con)
}
}
func AccessClient(con net.Conn) {
buffer := make([]byte, 1024*2)
var (
recNu int
err error
resSplice []byte
)
defer con.Close()
for {
recNu, err = con.Read(buffer)
if err != nil {
break
}
fmt.Printf("服务端收到客户端[%v]内容:%v\n", con.RemoteAddr(), string(buffer[:recNu]))
resSplice = responStr(buffer[:recNu])
_, err = con.Write(resSplice)
if err != nil {
break
} else {
fmt.Printf("服务端回复客户端[%v]内容:%v\n", con.RemoteAddr(), string(resSplice))
}
}
fmt.Println(con.RemoteAddr(), "异常退出!")
}
func main() {
//1. 开启一个监听服务端
serverIP := "127.0.0.1:15210"
go OpenTcpSever(serverIP)
//2. 检验服务是否开启成功
serBl := <-serverChan
if serBl {
fmt.Println("监听本地端口", serverIP, "成功,等待客户端连接。")
fmt.Println("输入quite退出服务端...")
var uIn string
for {
fmt.Scanln(&uIn)
if uIn == "quite" {
break
}
fmt.Println("输入退出命令错误!!!请输入quite退出服务端")
}
} else {
fmt.Println("监听本地端口", serverIP, "失败!")
}
close(serverChan)
}
//根据服务器接收到的命令去返回命令
func responStr(data []byte) []byte {
reciveStr := string(data)
resStr := "保存成功"
//数据处理成功
if reciveStr == "true" {
} else {
//数据处理失败
resStr = "数据处理失败"
}
return []byte(resStr)
}
TCP客户端
package main
import (
"bufio"
"fmt"
"net"
"os"
"strings"
)
var serverClose = make(chan bool, 1)
func main() {
//1. 连接服务端
serverStr := "127.0.0.1:15200"
con, err := net.Dial("tcp", serverStr)
if err != nil {
fmt.Println("连接服务端:", serverStr, "错误:", err.Error())
return
}
defer con.Close()
fmt.Println("连接服务端成功:", serverStr)
//开一个接收协程
go ReciveData(con)
for {
fmt.Println("-----功能列表----")
fmt.Println("1.发送信息")
fmt.Println("2.退出客户端")
fmt.Println("3.重新连接")
var usInput int
fmt.Scanln(&usInput)
switch usInput {
case 1:
//此方法存在bug 如果中间有空格 fmt.Scanln会在第一个空格处截取
var usSendStr string
fmt.Println("请输入发送内容:")
// fmt.Scanln(&usSendStr)
//解决方案
stdin := bufio.NewReader(os.Stdin)
//fmt.Fscan(stdin, &usSendStr)
usSendStr, _ = stdin.ReadString('\n')
usSendStr = strings.TrimRight(usSendStr, "\r\n")
_, err = con.Write([]byte(usSendStr))
if err == nil {
fmt.Printf("客户端[%v]给服务端:%v 数据:%v 成功。\n ", con.LocalAddr().String(), con.RemoteAddr().String(), usSendStr)
go ReciveData(con)
} else {
fmt.Println("发送给服务端:", con.RemoteAddr().String(), "失败!")
}
case 2:
//退出程序
os.Exit(0)
case 3:
if len(serverClose) != 1 {
fmt.Println("连接服务端正常,无需重复连接...")
break
}
if bl := <-serverClose; bl {
fmt.Println("开始重新连接服务端:", serverStr)
if con != nil {
con.Close()
}
con, err = net.Dial("tcp", serverStr)
if err != nil {
fmt.Println("连接服务端失败,请稍后重试!")
serverClose <- true
} else {
fmt.Println("重新连接服务端:", serverStr, "成功!")
}
}
default:
fmt.Println("输入无效命令...")
}
}
}
func ReciveData(con net.Conn) {
var (
recBuf = make([]byte, 1024*2)
recNu int
err error
)
for {
recNu, err = con.Read(recBuf)
if err != nil {
break
}
fmt.Printf("\n收到服务端%v回复数据:%v \n", con.RemoteAddr().String(), string(recBuf[:recNu]))
}
fmt.Println(con.RemoteAddr().String(), "服务端连接异常掉线!")
serverClose <- true
}
websocket 服务端
package main
import (
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"log"
)
var upgrader = websocket.Upgrader{}
func main() {
// 使用gin框架,和普通的http协议的服务器没什么不一样
s := gin.Default()
s.GET("/echo", echo)
_ = s.Run("localhost:8090")
}
func echo(c *gin.Context) {
//服务升级,对于来到的http连接进行服务升级,升级到ws
cn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
defer cn.Close()
if err != nil {
panic(err)
}
for {
//messageType int, p []byte, err error
mt, message, err := cn.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recv: %s", message)
err = cn.WriteMessage(mt, message)
if err != nil {
log.Println("write:", err)
break
}
}
}
websocket 客户端
package main
import (
"github.com/gorilla/websocket"
"log"
"net/url"
"os"
"os/signal"
"time"
)
func main() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
u := url.URL{Scheme: "ws", Host: "localhost:8090", Path: "/echo"}
log.Printf("connecting to %s", u.String())
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
log.Printf("recv: %s", message)
}
}()
//ticker := time.NewTicker(time.Second)
//defer ticker.Stop()
for {
select {
// if the goroutine is done , all are out
case <-done:
return
case t := <-time.Tick(time.Second):
err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
if err != nil {
log.Println("write:", err)
return
}
case <-interrupt:
log.Println("interrupt")
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}