开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:服务器循环接收客户端消息】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9781
服务器循环接收客户端消息
内容介绍
一、具体完善内容
二、注意事项
一、具体完善内容
将作业:要求在之前的基础上完成可以循环地输入内容,能够通过终端输入数据(输入一行送一行),并发送给服务端[],在终端输入 exit,表示退出程序进行完善,让其在客户端不再退出而是做 for 循环。打开 client.go,ReadString 应该进行 for 循环,将fmt.Printf(“客户端发送了%d 字节的数据,并退出“,n)删除,再将其包裹调整,如下:
for
{
//从终端读取一行用户输入,并准备发送给服务器
line, err : = reader.Readstring("\n')
if err != nil {
fmt.Println("readString err=", err)
}
//再将 line 发送给 服务器
_
,err = conn.
W
rite([
]byte(line))
if err != nil {
fmt.Println("conn.write err=", err)
}
}
在发送时并没有办法退出,所以要做一个判断,如下:
// 如果用户输入的是 exit 就退出
if
line
==
“exit“
{
f
m
t.P
rintln(
“
客户端退出.
.”)
break
}
但此时是不正确的,本身是存在\n 的,进行比较时要将 line 进行处理,将其除去,如下:
strings
.T
rim(
line,”\r\n”)
但如果进行这样的操作,需要引入包,如下:
package main
import
(
"fmt"
"net"
"bufio"
"os"
"strings"
)
此时,要同时考虑到服务端 server,在以上运行中,循环服务器的情况如下:
但此时如果不回车则会一直等待,要将 server 提示信息去除后循环结果如下:
此时并没有进行换行,要_,err = conn.Write([ ]byte(line))后加入_,err = conn.Write([ ]byte(line + “\n”)),再进行运行,进入到客户端,进入到 cmd,写入go run client.go 进行连接,则循环结果如下:
而切换为两个客户端连接时,是可以进行区分的,如下:
此时已经完成两个客户端到一个服务器端,而一个服务器端可以协程两个客户端进行服务,在进行退出时也可以捕获到客户端的退出。
此时的模式是 A 客户端与服务器端进行交互,如果 A 客户端与B客户端要进行交互,则服务器端的内容与功能要增加,可以在协程中拿到 B 客户端的连接。
对 client.go 进行了改进,划线区域如下:
for
{
//从终端读取一行用户输入,并准备发送给服务器
line,
err :
= reader.Readstring("\n')
if err != nil {
fmt.Println("read
S
tring err=", err)
}
// 如果用户输入的是 exit 就退出
line =
strings
.T
rim(
line,”\r\n”)
if
line
==
“exit“
{
f
m
t.P
rintln(
“
客户端退出.
.”)
break
}
//再将 line 发送给服务器
_
,err = conn.
W
rite([
]byte(
line
+
“\
n”
))
if err != nil {
fmt.Println("conn.write err=", err)
}
}
二、注意事项
如果写为 fmt.Print(string(buf)),会出现一些错误,字节里可能预先有一些内容,buf 后面的内容可会会导致其出现一些问题,如下:
此时内容会出现空格而排在后面,写为 fmt.Print(string(buf[:n]))是正确的。