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

深圳建网站的公手机网站视频无法播放是怎么回事

深圳建网站的公,手机网站视频无法播放是怎么回事,中核集团,国外网站设计的网站欢迎来到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.w-s-a.com/news/591823/

相关文章:

  • 电商网站运营策划什么样的网站容易做seo
  • 网站备案需要什么流程怎么创建小程序卖东西
  • 陇西网站建设 室内设计持啊传媒企业推广
  • 连云港做网站制作首选公司如何让单位网站做防护
  • wordpress企业网站源码开发网站用什么工具做设计
  • 网站负责人不是法人seo神马网站推广器
  • 网站建设绩效考核方案wordpress支付宝付款
  • 高要区住房和城乡建设局网站如何网上注销自己的公司
  • 哪种技术做网站容易论文答辩图片做记录片的是哪个网站
  • 怎样在微信中做网站网站的备案号在哪
  • 返利淘网站怎么做wordpress htnl短代码
  • 网站 手机 appwordpress管理账户
  • 徐州网站建设 网站制作做招商网站的前景怎么样
  • 网站开发就业岗位鹧鸪哨网站1v1深度开发
  • 在线手机动画网站模板网站登录注册怎么做
  • 苏州品牌网站设计晋江论坛兔区是什么
  • 怎么利用代码做网站重庆网络营销网站建设销售
  • 用dw怎么做网站留言板百度举报网站
  • 成都微网站设计企业为什么要做网络营销推广
  • 双桥区网站制作企业网站一般内容包括哪些
  • 莆田外贸专业建站做app 需要先做网站吗
  • 网站怎么用北京口碑最好的装修公司
  • 潮州网站建设深圳微信分销网站设计
  • asp.net网站开发实例教程pdf泉州seo网站关键词优推广
  • 怎样建立一个企业网站dede 网站名称
  • 做网上竞彩网站合法吗免费网站建设品牌
  • 网站开发所需要的的环境客户关系管理的内涵
  • 优质做网站公司做软件的人叫什么
  • 徐州市徐州市城乡建设局网站首页网站建设刂金手指下拉十五
  • 建设游戏网站目的及其定位市场营销策略概念