发送给服务器要用 utf8 编码方式
服务端代码:
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:5200"
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 := "你说啥..."
switch reciveStr {
case "who are you":
resStr = "我是小兵张嘎"
case "你的性别":
resStr = "你猜猜看啦"
case "你会什么":
resStr = "我会讲故事"
case "你讲个吧":
resStr = "从前有座bai山,山上有座庙,du庙里有个老和尚,老zhi和尚的dao身边有三个和尚——顽皮zhuan的小和尚、贪吃的shu胖和尚和匆忙的瘦和尚,老和尚在给三个和尚讲故事,故事是这样的:一个和尚挑水吃,两个和尚抬水吃,三个和尚没水吃。"
default:
}
return []byte(resStr)
}
client 客户端代码:
package main
import (
"bufio"
"fmt"
"net"
"os"
"strings"
)
var serverClose = make(chan bool, 1)
func main() {
//1. 连接服务端
serverStr := "127.0.0.1:5200"
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
}