golang p2p udp server

前端之家收集整理的这篇文章主要介绍了golang p2p udp server前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

golang p2p udp server

http://www.dotcoo.com/golang-p2p-udp
package main

import (
    "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.UDPAddr
var serverAddr *net.UDPAddr
var socket *net.UDPConn

func main() {
    var err error

    // 设置log参数
    log.SetFlags(log.Lshortfile)

    // 用户集合
    userlist = make([]*net.UDPAddr,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,hex.EncodeToString(data[:read]))

        switch data[0] {
        case CMD_LOGIN:
            // 新上线用户的信息
            touser_list_data := make([]byte,15)
            touser_list_data = append(touser_list_data,CMD_LIST_RES,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,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)
                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,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 main

import (
    "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.UDPAddr
var serverAddr *net.UDPAddr
var listenAddr *net.UDPAddr
var socket *net.UDPConn

func main() {
    var err error

    // 设置log参数
    log.SetFlags(log.Lshortfile)

    // 用户集合
    userlist = make([]*net.UDPAddr,"123.123.123.123:8080")
    log.Println("serverAddr",err)

    port := 8000
    PORT:

    // 本地地址
    listenAddr,fmt.Sprintf(":%d",port))
    if err != nil {
        log.Println(err)
    }

    // 创建连接
    socket,listenAddr)
    if err != nil {
        log.Println("连接失败!",err)
        port++
        goto PORT
        return
    }
    defer socket.Close()

    // 上线
    login_data := make([]byte,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,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,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,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,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,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])
        }
    }
}

猜你在找的Go相关文章