写了个聊天室,为什么以发中文就死循环呢?

weixin_35859019 2016-08-21 04:59:00

死循环, 发英文一切正常, 发中文就死循环; 这是什么问题?


package main

import (
"fmt"
"net"
"os"
"time"
"unicode/utf8"
)

func main() {

if len(os.Args) != 3 {
fmt.Print("参数不正确,无法启动!")
//os.Exit(0)
}

if os.Args[1] == "server" {
Server(os.Args[2])
}

if os.Args[1] == "client" {
Client(os.Args[2])

}
time.Sleep(5 * time.Second)
}

//错误检查
func checkError(err error, message string) (res bool) {
if err != nil {
fmt.Println(message + " " + err.Error())
return false
}
return true
}

func Server(port string) {
service := ":" + port

l, err := net.Listen("tcp", service)
checkError(err, "Listen")

conns := make(map[string]net.Conn) //创建连接池 ip=>conn
msgs := make(chan string, 100) //创建消息池 就是chan;

//启动广播线程
go Broadcast(&conns, msgs) // ['brɔdkæst] 广播

fmt.Println("服务端已经启动,正在监听......")
for {

//接受连接
conn, err := l.Accept()
checkError(err, "接受连接异常")

//增加字典 IP-> Conn
conns[conn.RemoteAddr().String()] = conn

//启动一个线程 用于该连接的消息读取到信道;
go Getmsg(conn, msgs)
}
}

//获取消息
func Getmsg(conn net.Conn, msgs chan string) {
msg := make([]byte, 1024)
for {
//读取消息
length, err := conn.Read(msg)
if checkError(err, "Getmsg") == false {
conn.Close()
break
}
//将消息存放到信道
msgs <- string(msg[0:length])
}
}

//广播消息
func Broadcast(conns *map[string]net.Conn, msgs chan string) {
for {
// 阻塞读取信道内容
msg := <-msgs
fmt.Println(msg)

for key, conn := range *conns {
//向客户端发送消息
_, err := conn.Write([]byte(msg))
if err != nil {
fmt.Println(err.Error())
//若写入失败,说明断开,删除该连接
delete(*conns, key)
}
}
}
}

//客户端;
func Client(address string) {
fmt.Print(100)
//创建拨号器
conn, err := net.Dial("tcp4", address)
checkError(err, "Dial")

//启动客户端发送线程
go ClientSend(conn)

//轮询接受消息
for {
msg := make([]byte, 1024) //存放接受到消息,固定byte一次到位,省的底层数组可能变动;
length, err := conn.Read(msg)
if checkError(err, "Connection") == false {
conn.Close()
fmt.Println("与服务器断开")
os.Exit(0)
}
fmt.Println(string(msg[0:length]))
}
}

//发送消息
func ClientSend(conn net.Conn) {
//用户名
username := conn.LocalAddr().String()
var input string
for {
//获取命令
fmt.Scanln(&input)

//退出客户端
if input == "/quit" {
fmt.Println("1秒后关闭客户端..")
//os.Sleep(1)
conn.Close()
os.Exit(0)
}
//发送消息
_, err := conn.Write([]byte(username + " Say:: " + input))
if err != nil {
fmt.Println(err.Error())
conn.Close()
break
}
}
}
...全文
248 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_35859019 2016-09-01
  • 打赏
  • 举报
回复
引用 1 楼 xming4321 的回复:
客户端死循环 还是服务端?
D:\Go\001.exe server 9001 服务端 D:\Go\001.exe client 127.0.0.1:9001 客户端 只要客户端发 中文, 服务端和客户端都死循环;
十一文 2016-08-26
  • 打赏
  • 举报
回复
客户端死循环 还是服务端?
fvbfvbfvbfvb 2016-08-26
  • 打赏
  • 举报
回复
client 读取控制台输入时出错,你可以打印看下: //获取命令 n, err := fmt.Scanln(&input) fmt.Println(n, err) 可以改为以下方式: reader := bufio.NewReader(os.Stdin) data, _, _ := reader.ReadLine() input = string(data)

2,190

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • Freeman Z
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧