当前位置: 首页 > news >正文

qq选号网站怎么做的wordpress 获取logo

qq选号网站怎么做的,wordpress 获取logo,青岛快速排名,企飞互联网站建设网络公司欢迎来到Golang的世界#xff01;在当今快节奏的软件开发领域#xff0c;选择一种高效、简洁的编程语言至关重要。而在这方面#xff0c;Golang#xff08;又称Go#xff09;无疑是一个备受瞩目的选择。在本文中#xff0c;带领您探索Golang的世界#xff0c;一步步地了… 欢迎来到Golang的世界在当今快节奏的软件开发领域选择一种高效、简洁的编程语言至关重要。而在这方面Golang又称Go无疑是一个备受瞩目的选择。在本文中带领您探索Golang的世界一步步地了解这门语言的基础知识和实用技巧。 在这篇文章中我们将用Go语言实现一个简易网络聊天应用重点探讨Socket编程、map结构用于管理用户、goroutines与channels实现并发通信、select语句处理超时与主动退出以及timer定时器的应用。这些概念将帮助我们构建高效且实用的聊天系统。让我们开始吧 目录 socket-server建立 创建msg广播通道 查询用户与重命名 用户主动退出聊天 用户超时退出聊天 socket-server建立 socket-server的作用是实现网络通信的基础允许不同设备如客户端和服务器通过网络交换数据下面我们模拟TCP服务器能够接收多个客户端的连接请求并在每个连接上启动一个新的goroutine进行数据处理。每当有数据从客户端发送到服务器时服务器会读取并打印这些数据 package mainimport (fmtnet )func main() {// 01 创建服务器listener, err : net.Listen(tcp, :8080)if err ! nil {fmt.Println(net.listen err:, err)return} else {fmt.Println(服务器启动成功...)}for {fmt.Println(主go程监听中...)// 02 监听服务器connect, err : listener.Accept()if err ! nil {fmt.Println(listener.accept err:, err)return}fmt.Println(建立连接成功...)// 03 启动处理业务的go程go handler(connect)}}func handler(conn net.Conn) {for {fmt.Println(启动处理业务)// TODO// 读取客户端发送的数据buf : make([]byte, 1024)cnt, err : conn.Read(buf)if err ! nil {fmt.Println(conn.read err:, err)return} else {fmt.Println(服务器接收客户端发送过来的数据为:, string(buf[:cnt-1]), cnt:, cnt)}}} 这种设计使得服务器具有并发处理能力可以同时处理多个客户端的请求这里我们借助nc工具来模拟请你不了解工具的可以参考我之前的文章地址 具体如下所示 创建msg广播通道 要知道我们程度当中是有很多用户的当一个用户发送消息能让所有的用户看到的话是需要有一个进行全局广播的管道message如下所示全局广播的message获取到“hello”然后遍历所有的用户并向用户msg管道发送hello在go程中每一个用户连接一个需要再启动一个go程读取message数据之后发送给客户端 接下来我们开始创建User结构用于管理每次创建用户的结构 // User 定义用户结构体 type User struct {id stringname stringmsg chan string }// 创建全局的map结构用于保存所有的用户 var allUsers make(map[string]User) 然后我们再每次创建go程的时候以连接的key作为唯一添加到用户的map结构当中 接下来我们定义全局的管道用于接收任何人发送过来的消息 // 定义一个message全局通道用于接收任何人发送过来的消息 var message make(chan string, 10) 接下来再每次创建新用户上线的时候写入message 接下来创建一个全局唯一的广播通道用于通知用户消息然后在main函数中调用一次下面的go程即可 // 向所有的用户广播消息启动全局唯一go程 func broadcast() {fmt.Println(启动广播go程...)defer fmt.Println(broadcast程序结束...) // 程序结束关闭广播go程for {fmt.Println(广播go程监听中...)// 01 从message通道中读取消息info : -message// 02 遍历map结构向每个用户发送消息for _, user : range allUsers {// 03 向每个用户发送消息user.msg - info}} } 接下来每个用户应该还有一个用来监听自己msg管道的go程负责将数据返回给客户端 // 每个用户监听自己的msg通道负责将数据返回给客户端 func writeBackToClient(user *User, conn net.Conn) {fmt.Println(启动用户, user.name, 的writeBackToClient go程...)for data : range user.msg {fmt.Printf(user: %s 写回给客户端的数据为: %s\n, user.name, data)_, _ conn.Write([]byte(data))} } 查询用户与重命名 查询用户当用户输入查询命令who则将当前所有登录的用户展示出来id与name返回给当前用户 // 01 查询当前所有的用户 who if len(buf[:cnt-1]) 3 string(buf[:cnt-1]) who {var userInfos []string// 遍历map结构获取所有的用户信息for _, user : range allUsers {userInfo : fmt.Sprintf(userid:%s, username: %s, user.id, user.name)userInfos append(userInfos, userInfo)}// 最终写到管道中message - strings.Join(userInfos, \n) } 重命名这里我们可以设置一个规则rename | Duke使用竖线进行分割获取竖线后面的部分作为名字通过设置 newUser.name Duke然后通知客户端更新名字成功为了避免想输入命令作为消息这里我们对命令做一个处理 // 01 查询当前所有的用户 who if len(buf[:cnt-1]) 4 string(buf[:cnt-1]) \\who {var userInfos []string// 遍历map结构获取所有的用户信息for _, user : range allUsers {userInfo : fmt.Sprintf(userid:%s, username: %s, user.id, user.name)userInfos append(userInfos, userInfo)}// 最终写到管道中newUser.msg - strings.Join(userInfos, \n) } else if len(buf[:cnt-1]) 9 string(buf[:7]) \\rename {// 更新名字newUser.name strings.Split(string(buf[:cnt-1]), |)[1]allUsers[newUser.id] newUser // 更新map结构中的用户信息// 通知客户端更新成功newUser.msg - fmt.Sprintf(改名成功, 新的名字为: %s, newUser.name) } else {message - string(buf[:cnt-1]) } 用户主动退出聊天 接下来我们通过使用ctrlc的方式进行退出程序用户退出还需要做一下清理工作需要从map当中删除用户信息还需要将对应的conn连接进行close具体如下所示 // 启动一个go程负责监听退出信号通知所有go程退出 func watch(user *User, conn net.Conn, isQuit chan bool) {fmt.Println(启动用户, user.name, 的watch go程...)defer fmt.Println(watch程序结束...) // 程序结束关闭监听go程for {select {case -isQuit: // 收到退出信号通知所有go程退出delete(allUsers, user.id)fmt.Println(删除当前用户, user.name)message - fmt.Sprintf([%s][%s]下线了, user.id, user.name)_ conn.Close()}} } 在handler中启动go watch并传入对应信息 然后在read之后通过读取cnt判断用户是否退出向isQuit中写入信息 最终实现的效果如下所示 用户超时退出聊天 这里我们可以设置使用定时器来进行超时管理如果60s内没有发送任何消息的情况下就直接将这个连接关闭掉 // 启动一个go程负责监听退出信号通知所有go程退出 func watch(user *User, conn net.Conn, isQuit chan bool, resTimer chan bool) {fmt.Println(启动用户, user.name, 的watch go程...)defer fmt.Println(watch程序结束...) // 程序结束关闭监听go程for {select {case -isQuit: // 收到退出信号通知所有go程退出delete(allUsers, user.id)fmt.Println(删除当前用户, user.name)message - fmt.Sprintf([%s][%s]下线了\n, user.id, user.name)_ conn.Close()returncase -time.After(10 * time.Second):fmt.Println(删除当前用户, user.name)delete(allUsers, user.id)message - fmt.Sprintf([%s]用户超时下线了\n, user.name)_ conn.Close()returncase -resTimer:fmt.Printf(连接%s 重置计数器\n, user.name)}} } 这里我们定义一个重置的管道只要用户不断输入就不会超时如果用户没有输入超过10s就会触发超时退出的操作 // 创建一个用于重置计算器的管道用于告知watch函数当前用户正在输入 var resTimer make(chan bool) // 启动go程负责监听用户退出 go watch(newUser, conn, isQuit, resTimer) 完整代码如下所示 package mainimport (fmtnetstringstime )// User 定义用户结构体 type User struct {id stringname stringmsg chan string }// 创建全局的map结构用于保存所有的用户 var allUsers make(map[string]User)// 定义一个message全局通道用于接收任何人发送过来的消息 var message make(chan string, 10)func main() {// 01 创建服务器listener, err : net.Listen(tcp, :8080)if err ! nil {fmt.Println(net.listen err:, err)return} else {fmt.Println(服务器启动成功...)// 启动全局唯一go程用于广播消息go broadcast()}for {fmt.Println(主go程监听中...)// 02 监听服务器connect, err : listener.Accept()if err ! nil {fmt.Println(listener.accept err:, err)return}fmt.Println(建立连接成功...)// 03 启动处理业务的go程go handler(connect)}}func handler(conn net.Conn) {fmt.Println(启动处理业务)// 客户端与服务器建立连接的时候会有ip与port可以当成user的idclientAddr : conn.RemoteAddr().String()fmt.Println(客户端地址为:, clientAddr)// 创建UsernewUser : User{id: clientAddr, // id,不会被修改作为mao中的keyname: clientAddr, // 可以修改会提供rename命令修改建立连接时初始值与id相同msg: make(chan string, 10), // 消息通道注意分配空间}// 添加user到map结构中allUsers[newUser.id] newUser// 定义一个退出信号用于通知所有go程退出var isQuit make(chan bool)// 创建一个用于重置计算器的管道用于告知watch函数当前用户正在输入var resTimer make(chan bool)// 启动go程负责监听用户退出go watch(newUser, conn, isQuit, resTimer)// 启动用户自己的writeBackToClient go程go writeBackToClient(newUser, conn)// 向message写入消息用于通知所有人有用户上线message - fmt.Sprintf([%s][%s]上线了, newUser.id, newUser.name)for {buf : make([]byte, 1024)// 读取客户端发送的数据cnt, err : conn.Read(buf)if cnt 0 {fmt.Println(客户端主动关闭ctrlc准备退出)// 在这里不进行真正的退出动作只是通知所有go程退出isQuit - true}if err ! nil {fmt.Println(conn.read err:, err, cnt, cnt)return} else {fmt.Println(服务器接收客户端发送过来的数据为:, string(buf[:cnt-1]), cnt:, cnt)// -------业务逻辑处理开始-------// 01 查询当前所有的用户 whoif len(buf[:cnt-1]) 4 string(buf[:cnt-1]) \\who {var userInfos []string// 遍历map结构获取所有的用户信息for _, user : range allUsers {userInfo : fmt.Sprintf(userid:%s, username: %s, user.id, user.name)userInfos append(userInfos, userInfo)}// 最终写到管道中newUser.msg - strings.Join(userInfos, \n)} else if len(buf[:cnt-1]) 9 string(buf[:7]) \\rename {// 更新名字newUser.name strings.Split(string(buf[:cnt-1]), |)[1]allUsers[newUser.id] newUser // 更新map结构中的用户信息// 通知客户端更新成功newUser.msg - fmt.Sprintf(改名成功, 新的名字为: %s, newUser.name)} else {message - string(buf[:cnt-1])}resTimer - true // 发送一个信号告知watch函数当前用户正在输入// -------业务逻辑处理结束-------}} }// 向所有的用户广播消息启动全局唯一go程 func broadcast() {fmt.Println(启动广播go程...)defer fmt.Println(broadcast程序结束...) // 程序结束关闭广播go程for {fmt.Println(广播go程监听中...)// 01 从message通道中读取消息info : -messagefmt.Println(广播消息为:, info)// 02 遍历map结构向每个用户发送消息for _, user : range allUsers {// 03 向每个用户发送消息user.msg - info}} }// 每个用户监听自己的msg通道负责将数据返回给客户端 func writeBackToClient(user *User, conn net.Conn) {fmt.Println(启动用户, user.name, 的writeBackToClient go程...)for data : range user.msg {fmt.Printf(user: %s 写回给客户端的数据为: %s\n, user.name, data)_, _ conn.Write([]byte(data))} }// 启动一个go程负责监听退出信号通知所有go程退出 func watch(user *User, conn net.Conn, isQuit chan bool, resTimer chan bool) {fmt.Println(启动用户, user.name, 的watch go程...)defer fmt.Println(watch程序结束...) // 程序结束关闭监听go程for {select {case -isQuit: // 收到退出信号通知所有go程退出delete(allUsers, user.id)fmt.Println(删除当前用户, user.name)message - fmt.Sprintf([%s][%s]下线了\n, user.id, user.name)_ conn.Close()returncase -time.After(10 * time.Second):fmt.Println(删除当前用户, user.name)delete(allUsers, user.id)message - fmt.Sprintf([%s]用户超时下线了\n, user.name)_ conn.Close()returncase -resTimer:fmt.Printf(连接%s 重置计数器\n, user.name)}} }
http://www.dnsts.com.cn/news/263720.html

相关文章:

  • 克拉玛依网站建设网站系统升级
  • 做美图+网站有哪些青岛官网优化
  • 潍坊优化网站多久可以拿证
  • 有的网站打不开 但别人电脑能打开纪检网站建设计划书
  • 网站建设前期情况说明博客群wordpress
  • 网站建设更新不及时亚马逊雨林的资料
  • 东莞网站设计找哪里四平市住房和畅想建设局网站
  • 北京工信部网站监控网站模版
  • 移动端网站怎么制作高埗仿做网站
  • wordpress 标签id南昌专业网站优化推广
  • 手机网站开发屏幕尺寸一般是多少抖音代运营直播
  • 网站建设维护管理软件公司备案的网站被别的公司盗用
  • 网站淘宝推广怎么做买手表去哪个网站买是正品的
  • 自己买一个服务器怎么做网站网站建设费用的会计分录
  • 温州手机网站制作哪家好摄影做网站
  • 张家港营销型网站建设上海推广网站
  • 网站上怎么做推广比较好呢网站制作需要学什么
  • 沙田网站建设广东官网网站建设哪家好
  • 网站的内容建设网站建设服务属于信息技术服务吗
  • 网站建设方案硬件支撑网站通栏图片代码
  • 订单查询网站怎么做手机上怎么制作网页
  • 手机网站建设的整体流程图网站登录人太多进不去怎么办
  • 大岭山营销型网站建设网站制作 外包
  • 微网站与app的区别北京专业网站营销
  • 网站迁移到别的服务器要怎么做阿里云 wordpress 插件
  • 茶社网站开发与设计的开题报告手机网站前端写法
  • 一级a做爰片免费网站孕交视频教程手机端企业网站怎么做
  • 网站绑定别名好吗西安网站制作托
  • 一个网站项目几个人做北京快三下载官方网站
  • 网站里的图片切换怎么做有网站教做水电资料吗