golang p2p udp server
来源:互联网 发布:js trimend 编辑:程序博客网 时间:2024/05/16 07:39
golang p2p udp server
http://www.dotcoo.com/golang-p2p-udppackage mainimport ( "net" "encoding/binary" "encoding/hex" "log" "time")const ( // login client -> server CMD_LOGIN byte = byte(iota) CMD_LOGIN_RES // user list server -> client CMD_LIST CMD_LIST_RES // ping server -> client CMD_PING CMD_PONG // cone client -> client CMD_CONE CMD_CONE_RES // message client -> client CMD_MEG CMD_MSG_RES)var userlist []*net.UDPAddrvar serverAddr *net.UDPAddrvar socket *net.UDPConnfunc main() { var err error // 设置log参数 log.SetFlags(log.Lshortfile) // 用户集合 userlist = make([]*net.UDPAddr, 0, 10) // 服务器地址 serverAddr, err = net.ResolveUDPAddr("udp4", ":8080") log.Println(err) // 创建监听 socket, err = net.ListenUDP("udp4", serverAddr) if err != nil { log.Println("监听失败! ", err) return } defer socket.Close() // ping // go ping() // 处理 for { // 处理数据报文 data := make([]byte, 4096) read, addr, err := socket.ReadFromUDP(data) if err != nil { log.Println("读取数据失败!", err) continue } log.Printf("UDP: %d, %s, %s\n", read, addr, hex.EncodeToString(data[:read])) switch data[0] { case CMD_LOGIN: // 新上线用户的信息 touser_list_data := make([]byte, 0, 15) touser_list_data = append(touser_list_data, CMD_LIST_RES, 0, 0, 0, 0, 0, 0) // touser_list_data = append(touser_list_data, addr.IP...) copy(touser_list_data[1:5], addr.IP) binary.LittleEndian.PutUint16(touser_list_data[5:], uint16(addr.Port)) log.Println("touser_list_data:", hex.EncodeToString(touser_list_data)) // 构建在线的用户信息列表 user_list_data := make([]byte, 0, 100) user_list_data = append(user_list_data, CMD_LIST_RES) // 通知所有在线用户,有新用户上线 for _, touser := range userlist { // 添加在线用户信息到列表 // user_list_data = append(user_list_data, touser.IP...) user_list_data = append(user_list_data, 0, 0, 0, 0, 0, 0) copy(user_list_data[len(user_list_data)-6:], touser.IP) binary.LittleEndian.PutUint16(user_list_data[len(user_list_data)-2:], uint16(touser.Port)) // 给在线用户发送数据 socket.WriteToUDP(touser_list_data, touser) } // 给新上限用户发送在线用户的列表 log.Println("user_list_data:", hex.EncodeToString(user_list_data)) socket.WriteToUDP(user_list_data, addr) // 将新用户存储 userlist = append(userlist, addr) case CMD_LOGIN_RES: case CMD_LIST: case CMD_LIST_RES: case CMD_PING: case CMD_PONG: log.Println("CMD_PONG udp: ", addr) case CMD_CONE: case CMD_CONE_RES: case CMD_MEG: case CMD_MSG_RES: default: log.Println("default udp: ", addr) } }}func ping() { ping_data := make([]byte, 0, 15) ping_data = append(ping_data, CMD_PING, 0) for { for _, touser := range userlist { socket.WriteToUDP(ping_data, touser) } time.Sleep(5 * time.Second) }}
golang p2p udp client
package mainimport ( "fmt" "net" "log" "encoding/binary" "encoding/hex" "strings" "bufio" "os")const ( // login client -> server CMD_LOGIN byte = byte(iota) CMD_LOGIN_RES // user list server -> client CMD_LIST CMD_LIST_RES // ping server -> client CMD_PING CMD_PONG // cone client -> client CMD_CONE CMD_CONE_RES // message client -> client CMD_MEG CMD_MSG_RES)var userlist []*net.UDPAddrvar serverAddr *net.UDPAddrvar listenAddr *net.UDPAddrvar socket *net.UDPConnfunc main() { var err error // 设置log参数 log.SetFlags(log.Lshortfile) // 用户集合 userlist = make([]*net.UDPAddr, 0, 10) // 服务器地址 serverAddr, err = net.ResolveUDPAddr("udp4", "123.123.123.123:8080") log.Println("serverAddr", err) port := 8000 PORT: // 本地地址 listenAddr, err = net.ResolveUDPAddr("udp4", fmt.Sprintf(":%d", port)) if err != nil { log.Println(err) } // 创建连接 socket, err = net.ListenUDP("udp4", listenAddr) if err != nil { log.Println("连接失败!", err) port++ goto PORT return } defer socket.Close() // 上线 login_data := make([]byte, 0, 10) login_data = append(login_data, CMD_LOGIN) login_data = append(login_data, []byte("nickname")...) // 发送上线数据 _, err = socket.WriteToUDP(login_data, serverAddr) if err != nil { log.Println("发送数据失败!", err) return } // 读取消息 go readMsg() // 用户交互 readCmd()}// 用户交互func readCmd() { for { fmt.Printf("p2p > ") scanner := bufio.NewScanner(os.Stdin) if !scanner.Scan() { continue } var line = scanner.Text() if err := scanner.Err(); err != nil { log.Println("read error: ", err) continue } switch { case strings.HasPrefix(line, "help"): fmt.Println(" list: show all user list\n send: send message\n\tsend <id> <message>") case strings.HasPrefix(line, "list"): fmt.Println("user list:") for id, user := range userlist { fmt.Println(id+1, user.IP, user.Port) } case strings.HasPrefix(line, "send"): id := 0; content := "" fmt.Sscanf(line, "send %d %s", &id, &content) if id <= 0 || id > len(userlist) { fmt.Printf("error: id %d not fund\n", id) continue } log.Printf("send message: %s %d, %s", userlist[id-1], id, content) sendData := make([]byte, 0, 100) sendData = append(sendData, CMD_MEG) sendData = append(sendData, []byte(content)...) n, err := socket.WriteToUDP(sendData, userlist[id-1]) log.Println(n, err) default: fmt.Printf("command error: %s\nuse the 'help' command to get help\n", line) } }}func readMsg() { for { // 接收数据 data := make([]byte, 1024) read, addr, err := socket.ReadFromUDP(data) if err != nil { log.Println("读取数据失败!", err) continue } log.Printf("UDP: %d, %s, %s\n", read, addr, hex.EncodeToString(data[:read])) switch data[0] { case CMD_LOGIN_RES: case CMD_LIST_RES: for i := 1; i < read; i+=6 { addrData := data[i:] touser := &net.UDPAddr{ IP: net.IP(addrData[:4]), Port: int(binary.LittleEndian.Uint16(addrData[4:])), } coneData := make([]byte, 0, 10) coneData = append(coneData, CMD_CONE) coneData = append(coneData, []byte("nickname")...) socket.WriteToUDP(coneData, touser) log.Println("cone: ", touser, coneData) userlist = append(userlist, touser) } case CMD_PING: log.Printf("CMD_PING\n") pong_data := make([]byte, 0, 15) pong_data = append(pong_data, CMD_PONG, 1) n, err := socket.WriteTo(pong_data, addr) log.Println("CMD_PING: ", n, err) case CMD_PONG: case CMD_CONE: coneResData := make([]byte, 0, 10) coneResData = append(coneResData, CMD_CONE_RES) coneResData = append(coneResData, []byte("nickname")...) socket.WriteToUDP(coneResData, addr) case CMD_CONE_RES: log.Println("CMD_CONE_RES:", addr) case CMD_MEG: fmt.Println(string(data[1:read])) case CMD_MSG_RES: default: log.Println("default UDP: ", data[0]) } }}
阅读全文
0 0
- golang p2p udp server
- golang udp
- P2P之UDP穿透
- P2P UDP开源库
- UDP P2P通信
- UDP P2P NAT详解
- P2P之UDP穿透
- 基于UDP协议可靠传输协议QUIC协议和golang server代码和client代码
- P2P:UDP穿透NAT防火墙
- P2P UDP NAT 原理 穿透
- P2P:UDP穿透NAT防火墙
- P2P之UDP穿透NAT
- P2P UDP NAT穿透原理
- P2P UDP NAT 原理 穿透
- p2p的UDP打洞原理
- P2P穿透UDP/TCP原理
- P2P穿透UDP/TCP原理
- P2P:UDP穿透NAT防火墙
- 通俗理解卷积神经网络
- node-webkit开发桌面应用
- 一个真正免费使用的微信营销平台
- 51nod 1681 公共祖先
- nginx+LVS+keepalived实现企业高可用
- golang p2p udp server
- 有效减小apk大小的方式
- DC/OS微服务平台搭建
- react native 封装组件以复用
- 消息摘要 MD5 和 SHA 的使用
- js,jquery获取服务器时间
- idea 上传项目到GitHub遇到的坑
- 设计模式原则(5):迪米特法则
- CSS基础-清除浮动