golang p2p udp server

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

golang p2p udp server

  1. http://www.dotcoo.com/golang-p2p-udp
  2. package main
  3.  
  4. import (
  5. "net"
  6. "encoding/binary"
  7. "encoding/hex"
  8. "log"
  9. "time"
  10. )
  11.  
  12. const (
  13. // login client -> server
  14. CMD_LOGIN byte = byte(iota)
  15. CMD_LOGIN_RES
  16.  
  17. // user list server -> client
  18. CMD_LIST
  19. CMD_LIST_RES
  20.  
  21. // ping server -> client
  22. CMD_PING
  23. CMD_PONG
  24.  
  25. // cone client -> client
  26. CMD_CONE
  27. CMD_CONE_RES
  28.  
  29. // message client -> client
  30. CMD_MEG
  31. CMD_MSG_RES
  32. )
  33.  
  34. var userlist []*net.UDPAddr
  35. var serverAddr *net.UDPAddr
  36. var socket *net.UDPConn
  37.  
  38. func main() {
  39. var err error
  40.  
  41. // 设置log参数
  42. log.SetFlags(log.Lshortfile)
  43.  
  44. // 用户集合
  45. userlist = make([]*net.UDPAddr,10)
  46.  
  47. // 服务器地址
  48. serverAddr,err = net.ResolveUDPAddr("udp4",":8080")
  49. log.Println(err)
  50.  
  51. // 创建监听
  52. socket,err = net.ListenUDP("udp4",serverAddr)
  53. if err != nil {
  54. log.Println("监听失败! ",err)
  55. return
  56. }
  57. defer socket.Close()
  58.  
  59. // ping
  60. // go ping()
  61.  
  62. // 处理
  63. for {
  64. // 处理数据报文
  65. data := make([]byte,4096)
  66. read,addr,err := socket.ReadFromUDP(data)
  67. if err != nil {
  68. log.Println("读取数据失败!",err)
  69. continue
  70. }
  71. log.Printf("UDP: %d,%s,%s\n",read,hex.EncodeToString(data[:read]))
  72.  
  73. switch data[0] {
  74. case CMD_LOGIN:
  75. // 新上线用户的信息
  76. touser_list_data := make([]byte,15)
  77. touser_list_data = append(touser_list_data,CMD_LIST_RES,0)
  78. // touser_list_data = append(touser_list_data,addr.IP...)
  79. copy(touser_list_data[1:5],addr.IP)
  80. binary.LittleEndian.PutUint16(touser_list_data[5:],uint16(addr.Port))
  81.  
  82. log.Println("touser_list_data:",hex.EncodeToString(touser_list_data))
  83.  
  84. // 构建在线的用户信息列表
  85. user_list_data := make([]byte,100)
  86. user_list_data = append(user_list_data,CMD_LIST_RES)
  87.  
  88. // 通知所有在线用户,有新用户上线
  89. for _,touser := range userlist {
  90. // 添加在线用户信息到列表
  91. // user_list_data = append(user_list_data,touser.IP...)
  92. user_list_data = append(user_list_data,0)
  93. copy(user_list_data[len(user_list_data)-6:],touser.IP)
  94. binary.LittleEndian.PutUint16(user_list_data[len(user_list_data)-2:],uint16(touser.Port))
  95.  
  96. // 给在线用户发送数据
  97. socket.WriteToUDP(touser_list_data,touser)
  98. }
  99.  
  100. // 给新上限用户发送在线用户的列表
  101. log.Println("user_list_data:",hex.EncodeToString(user_list_data))
  102. socket.WriteToUDP(user_list_data,addr)
  103.  
  104. // 将新用户存储
  105. userlist = append(userlist,addr)
  106. case CMD_LOGIN_RES:
  107. case CMD_LIST:
  108. case CMD_LIST_RES:
  109.  
  110. case CMD_PING:
  111. case CMD_PONG:
  112. log.Println("CMD_PONG udp: ",addr)
  113. case CMD_CONE:
  114. case CMD_CONE_RES:
  115. case CMD_MEG:
  116. case CMD_MSG_RES:
  117. default:
  118. log.Println("default udp: ",addr)
  119. }
  120. }
  121. }
  122.  
  123. func ping() {
  124. ping_data := make([]byte,15)
  125. ping_data = append(ping_data,CMD_PING,0)
  126.  
  127. for {
  128. for _,touser := range userlist {
  129. socket.WriteToUDP(ping_data,touser)
  130. }
  131.  
  132. time.Sleep(5 * time.Second)
  133. }
  134. }

golang p2p udp client

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "net"
  6. "log"
  7. "encoding/binary"
  8. "encoding/hex"
  9. "strings"
  10. "bufio"
  11. "os"
  12. )
  13.  
  14. const (
  15. // login client -> server
  16. CMD_LOGIN byte = byte(iota)
  17. CMD_LOGIN_RES
  18.  
  19. // user list server -> client
  20. CMD_LIST
  21. CMD_LIST_RES
  22.  
  23. // ping server -> client
  24. CMD_PING
  25. CMD_PONG
  26.  
  27. // cone client -> client
  28. CMD_CONE
  29. CMD_CONE_RES
  30.  
  31. // message client -> client
  32. CMD_MEG
  33. CMD_MSG_RES
  34. )
  35.  
  36. var userlist []*net.UDPAddr
  37. var serverAddr *net.UDPAddr
  38. var listenAddr *net.UDPAddr
  39. var socket *net.UDPConn
  40.  
  41. func main() {
  42. var err error
  43.  
  44. // 设置log参数
  45. log.SetFlags(log.Lshortfile)
  46.  
  47. // 用户集合
  48. userlist = make([]*net.UDPAddr,"123.123.123.123:8080")
  49. log.Println("serverAddr",err)
  50.  
  51. port := 8000
  52. PORT:
  53.  
  54. // 本地地址
  55. listenAddr,fmt.Sprintf(":%d",port))
  56. if err != nil {
  57. log.Println(err)
  58. }
  59.  
  60. // 创建连接
  61. socket,listenAddr)
  62. if err != nil {
  63. log.Println("连接失败!",err)
  64. port++
  65. goto PORT
  66. return
  67. }
  68. defer socket.Close()
  69.  
  70. // 上线
  71. login_data := make([]byte,10)
  72. login_data = append(login_data,CMD_LOGIN)
  73. login_data = append(login_data,[]byte("nickname")...)
  74.  
  75. // 发送上线数据
  76. _,err = socket.WriteToUDP(login_data,serverAddr)
  77. if err != nil {
  78. log.Println("发送数据失败!",err)
  79. return
  80. }
  81.  
  82. // 读取消息
  83. go readMsg()
  84.  
  85. // 用户交互
  86. readCmd()
  87. }
  88.  
  89. // 用户交互
  90. func readCmd() {
  91. for {
  92. fmt.Printf("p2p > ")
  93.  
  94. scanner := bufio.NewScanner(os.Stdin)
  95. if !scanner.Scan() {
  96. continue
  97. }
  98.  
  99. var line = scanner.Text()
  100. if err := scanner.Err(); err != nil {
  101. log.Println("read error: ",err)
  102. continue
  103. }
  104.  
  105. switch {
  106. case strings.HasPrefix(line,"help"):
  107. fmt.Println(" list: show all user list\n send: send message\n\tsend <id> <message>")
  108. case strings.HasPrefix(line,"list"):
  109. fmt.Println("user list:")
  110. for id,user := range userlist {
  111. fmt.Println(id+1,user.IP,user.Port)
  112. }
  113. case strings.HasPrefix(line,"send"):
  114. id := 0;
  115. content := ""
  116. fmt.Sscanf(line,"send %d %s",&id,&content)
  117.  
  118. if id <= 0 || id > len(userlist) {
  119. fmt.Printf("error: id %d not fund\n",id)
  120. continue
  121. }
  122.  
  123. log.Printf("send message: %s %d,%s",userlist[id-1],id,content)
  124.  
  125. sendData := make([]byte,100)
  126. sendData = append(sendData,CMD_MEG)
  127. sendData = append(sendData,[]byte(content)...)
  128.  
  129. n,err := socket.WriteToUDP(sendData,userlist[id-1])
  130. log.Println(n,err)
  131. default:
  132. fmt.Printf("command error: %s\nuse the 'help' command to get help\n",line)
  133. }
  134. }
  135. }
  136.  
  137. func readMsg() {
  138. for {
  139. // 接收数据
  140. data := make([]byte,1024)
  141. read,hex.EncodeToString(data[:read]))
  142.  
  143. switch data[0] {
  144. case CMD_LOGIN_RES:
  145.  
  146. case CMD_LIST_RES:
  147. for i := 1; i < read; i+=6 {
  148. addrData := data[i:]
  149. touser := &net.UDPAddr{
  150. IP: net.IP(addrData[:4]),Port: int(binary.LittleEndian.Uint16(addrData[4:])),}
  151.  
  152. coneData := make([]byte,10)
  153. coneData = append(coneData,CMD_CONE)
  154. coneData = append(coneData,[]byte("nickname")...)
  155.  
  156. socket.WriteToUDP(coneData,touser)
  157. log.Println("cone: ",touser,coneData)
  158.  
  159. userlist = append(userlist,touser)
  160. }
  161. case CMD_PING:
  162. log.Printf("CMD_PING\n")
  163. pong_data := make([]byte,15)
  164. pong_data = append(pong_data,CMD_PONG,1)
  165. n,err := socket.WriteTo(pong_data,addr)
  166. log.Println("CMD_PING: ",n,err)
  167. case CMD_PONG:
  168.  
  169. case CMD_CONE:
  170. coneResData := make([]byte,10)
  171. coneResData = append(coneResData,CMD_CONE_RES)
  172. coneResData = append(coneResData,[]byte("nickname")...)
  173.  
  174. socket.WriteToUDP(coneResData,addr)
  175. case CMD_CONE_RES:
  176. log.Println("CMD_CONE_RES:",addr)
  177. case CMD_MEG:
  178. fmt.Println(string(data[1:read]))
  179. case CMD_MSG_RES:
  180.  
  181. default:
  182. log.Println("default UDP: ",data[0])
  183. }
  184. }
  185. }

猜你在找的Go相关文章