初学GO不到两周,本着熟悉语言的目标写了这个小程序,漏洞很多,实现上写的也有些渣渣,欢迎大家阅读指点。
下载地址:https://github.com/yinxin630/gochat
简单思路描述:
0、服务端监听客户端请求,完成会话转发的任务
1、服务端采用心跳包维护用户在线状态
2、客户端通知服务端自己的监听地址,创建服务端-客户端信息通道
服务端:
package main
import (
"fmt"
"net"
"os"
"strconv"
"time"
)
//用户信息
type User struct {
userName string
userAddr *net.UDPAddr
userListenConn *net.UDPConn
chatToConn *net.UDPConn
}
//服务器监听端口
const LISTENPORT = 1616
//缓冲区
const BUFFSIZE = 1024
var buff = make([]byte, BUFFSIZE)
//在线用户
var onlineUser = make([]User, 0)
//在线状态判断缓冲区
var onlineCheckAddr = make([]*net.UDPAddr, 0)
//错误处理
func HandleError(err error) {
if err != nil {
fmt.Println(err.Error())
os.Exit(2)
}
}
//消息处理
func HandleMessage(udpListener *net.UDPConn) {
n, addr, err := udpListener.ReadFromUDP(buff)
HandleError(err)
if n > 0 {
msg := AnalyzeMessage(buff, n)
switch msg[0] {
//连接信息
case "connect ":
//获取昵称+端口
userName := msg[1]
userListenPort := msg[2]
//获取用户ip
ip := AnalyzeMessage([]byte(addr.String()), len(addr.String()))
//显示登录信息
fmt.Println(" 昵称:", userName, " 地址:", ip[0], " 用户监听端口:", userListenPort, " 登录成功!")
//创建对用户的连接,用于消息转发
userAddr, err := net.ResolveUDPAddr("udp4", ip[0] + ":" + userListenPort)
HandleError(err)
userConn, err := net.DialUDP("udp4", nil, userAddr)
HandleError(err)
//因为连接要持续使用,不能在这里关闭连接
//defer userConn.Close()
//添加到在线用户
onlineUser = append(onlineUser, User{userName, addr, userConn, nil})
case "online ":
//收到心跳包
onlineCheckAddr = append(onl