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])        }    }}
原创粉丝点击