代码拉取完成,页面将自动刷新
package main
import (
"flag"
"fmt"
"io"
"net"
"os"
"strings"
)
type Client struct {
ServerIp string
ServerPort int
Name string
conn net.Conn
flag int // 记录当前客户端的聊天模式
}
// 创建客户端的方法
func NewClient(serverIp string, serverPort int) *Client {
// 创建客户端对象
client := &Client{
ServerIp: serverIp,
ServerPort: serverPort,
flag: 999,
}
// 连接Server
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", serverIp, serverPort))
if err != nil {
fmt.Println("net.Dial error:", err)
return nil
}
client.conn = conn
// 返回对象
return client
}
func (this *Client) menu() bool {
fmt.Println("1:群聊模式")
fmt.Println("2:私聊模式")
fmt.Println("3:更新用户名")
fmt.Println("0:退出")
var flag int
fmt.Scanln(&flag) // 从用户键盘获得输入,并赋值给flag
if flag >= 0 && flag <= 3 {
this.flag = flag
return true
} else {
fmt.Println("青输入合法范围内的数字")
return false
}
}
// 修改用户名
func (this *Client) UpdateName() bool {
fmt.Println("======请输入用户名:======")
fmt.Scanln(&this.Name) // 将控制台输入的用户名直接赋值给this.Name
sendMsg := "rename|" + this.Name
_, err := this.conn.Write([]byte(sendMsg))
if err != nil {
fmt.Println("this.conn.Write err:", err)
return false
}
return true
}
// 群聊
func (this *Client) PublicChat() {
fmt.Println("======请输入聊天内容,exit退出:======")
var chatMsg string
fmt.Scanln(&chatMsg)
for chatMsg != "exit" {
if len(chatMsg) != 0 {
_, err := this.conn.Write([]byte(chatMsg + "\n"))
if err != nil {
fmt.Println("this.conn.Write err:", err)
break
}
}
chatMsg = ""
fmt.Println("======请输入聊天内容:======")
fmt.Scanln(&chatMsg)
}
}
// 查询当前在线用户
func (this *Client) SelectUsers() {
sendMsg := "w"
_, err := this.conn.Write([]byte(sendMsg))
if err != nil {
fmt.Println("SelectUsers err:", err)
}
}
// 私聊模式
func (this *Client) PrivateChat() {
var remoteName string
var chatMsg string
this.SelectUsers() // 先查询一下当前在线用户
fmt.Println("======请输入聊天对象,exit退出:======")
fmt.Scanln(&remoteName)
// 一次exit只可以退出一层for循环
for remoteName != "exit" {
fmt.Println("======请输入聊天内容,exit退出:======")
fmt.Scanln(&chatMsg)
for chatMsg != "exit" {
if len(chatMsg) != 0 {
remoteMsg := "to|" + strings.TrimSpace(remoteName) + "|" + chatMsg
fmt.Println("remoteMsg=", remoteMsg)
_, err := this.conn.Write([]byte(remoteMsg + "\n"))
if err != nil {
fmt.Println("this.conn.Write err:", err)
break
}
}
chatMsg = ""
fmt.Println("======请输入聊天内容,exit退出:======")
fmt.Scanln(&chatMsg)
}
this.SelectUsers() // 先查询一下当前在线用户
fmt.Println("======请输入聊天对象,exit退出:======")
fmt.Scanln(&remoteName)
}
}
var serverIp string
var serverPort int
// 从命令行flag中获得输入的变量
// 格式:client.exe -ip 127.0.0.1 -port 8888
func init() {
// 解释:从flag命令行中解析出ip参数,赋值给serverIp这个变量
flag.StringVar(&serverIp, "ip", "127.0.0.1", "设置服务器IP地址(默认127.0.0.1)")
flag.IntVar(&serverPort, "port", 8888, "设置服务器IP地址(默认8888)")
}
// 主业务功能
func (this *Client) Run() {
for this.flag != 0 {
for this.menu() != true {
// 如果menu()返回值不为true,则一直空循环
}
switch this.flag {
case 1:
fmt.Println("1:群聊模式")
this.PublicChat()
break
case 2:
fmt.Println("2:私聊模式")
this.PrivateChat()
break
case 3:
fmt.Println("3:更新用户名")
this.UpdateName()
break
// 为0时,会在外围的循环中跳出
}
}
}
func main() {
// 解析命令行
flag.Parse()
client := NewClient(serverIp, serverPort)
if client == nil {
fmt.Println("连接服务器失败")
}
fmt.Println("=======连接服务器成功======")
// 单独开启一个goroutine去处理server的回执消息
go client.DealResponse()
client.Run()
}
// 专门用来处理服务器返回值的goroutine
func (this *Client) DealResponse() {
io.Copy(os.Stdout, this.conn) // 将this.conn中的流直接拷贝到标准输出os.Stdout,永久阻塞监听
// 等价于下面的写法
//for {
// buf := make([]byte, 4096)
// this.conn.Read(buf)
// fmt.Println(string(buf))
//}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。