1 Star 0 Fork 0

吉桂权/gostudy-im

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
client.go 4.42 KB
一键复制 编辑 原始数据 按行查看 历史
吉桂权 提交于 2023-09-13 16:23 . 增加简单客户端
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))
//}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/jiguiquan/gostudy-im.git
git@gitee.com:jiguiquan/gostudy-im.git
jiguiquan
gostudy-im
gostudy-im
master

搜索帮助