golang(4):编写socket服务,简单支持命令

前端之家收集整理的这篇文章主要介绍了golang(4):编写socket服务,简单支持命令前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本文的原文连接是: http://www.jb51.cc/article/p-clygwvee-ber.html 转载请必须注明出处!

1,socket服务

使用golang开发socket服务还是非常简单的。
socket的库都封装好了。
参考文档:
https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/08.1.md

2,简单例子

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "net"
  6. "os"
  7. "time"
  8. )
  9.  
  10. func main() {
  11. tcpAddr,err := net.ResolveTCPAddr("tcp4",":8080")
  12. checkError(err)
  13. listener,err := net.ListenTCP("tcp",tcpAddr)
  14. checkError(err)
  15. for {//循环处理
  16. conn,err := listener.Accept()
  17. if err != nil {
  18. continue
  19. }
  20. go handleClient(conn)//创建一个goroutinue处理
  21. }
  22. }
  23.  
  24. func handleClient(conn net.Conn) {
  25. defer conn.Close()
  26. daytime := time.Now().String()
  27. conn.Write([]byte(daytime)) // don't care about return value
  28. // we're finished with this client
  29. }
  30. func checkError(err error) {
  31. if err != nil {
  32. fmt.Fprintf(os.Stderr,"Fatal error: %s",err.Error())
  33. os.Exit(1)
  34. }
  35. }

通过net.ListenTCP(“tcp”,tcpAddr) 创建一个服务,
然后用for循环,通过listener.Accept() 再创建一个goroutinue处理。

测试,使用telnet测试

  1. $ telnet 127.0.0.1 8080
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. 2015-07-14 17:33:59.602610026 +0800 CSTConnection closed by foreign host.

3,增加交互处理

当客户端输入参数的时候,服务端可以处理。
这里遇到几个问题一个是客户端输入的带回车\r\n要替换掉。
在一个字符串比较用等号即可,但是byte转换字符串长度不一样,需要特殊处理。

  1. package main
  2.  
  3. import (
  4. "net"
  5. "os"
  6. "fmt"
  7. "time"
  8. "strings"
  9. )
  10.  
  11. func main() {
  12. // println(os.Args[0])
  13. // println("Hello world!")
  14.  
  15. tcpAddr,":8080")
  16. checkError(err, 1)
  17.  
  18. listener,tcpAddr)
  19. checkError(err, 2)
  20.  
  21. for {
  22. conn,err := listener.Accept()
  23. if err != nil {
  24. continue
  25. }
  26. go handleClient(conn)
  27. }
  28.  
  29. os.Exit(0)
  30. }
  31.  
  32. func handleClient(conn net.Conn) {
  33. conn.SetReadDeadline(time.Now().Add(2 * time.Minute)) // 设置两分钟超时。
  34. user_cmd := make([]byte, 128) //设置用户输入的命令
  35. defer conn.Close()
  36.  
  37. for {
  38. read_len,err := conn.Read(user_cmd)
  39.  
  40. if err != nil {
  41. fmt.Println(err)
  42. break
  43. }
  44. if read_len == 0 {
  45. break // connection already closed by client
  46. }
  47.  
  48. //fmt.Println(string(user_cmd))
  49. //fmt.Println(len(string(user_cmd)))//长度是128,而不是time字符串的长度。
  50. //####################需要特殊处理字符串,找到每一个字符,然后累加。####################
  51. cmd_str := ""
  52. for i := 0; i < len(user_cmd); i ++ {
  53. //println(cmd_str[i])
  54. if user_cmd[i] == 0 {
  55. break
  56. }else {
  57. cmd_str += string(user_cmd[i])
  58. }
  59. }
  60.  
  61. //替换字符
  62. cmd_str = strings.Replace(cmd_str,"\r\n","", -1)
  63.  
  64. if cmd_str == "time" {
  65. time_now := time.Now().String()
  66. conn.Write([]byte(time_now))
  67. }else if cmd_str == "exit" {//退出命令。
  68. conn.Close()
  69. }
  70.  
  71. user_cmd = make([]byte, 128) // clear last read content
  72. }
  73. }
  74.  
  75. func checkError(err error,num int) {
  76. if err != nil {
  77. fmt.Fprintf(os.Stderr,"%d) Fail Error:%s",num,err.Error())
  78. os.Exit(1)
  79. }
  80. }

客户端telnet调用:当输入time返回时间,当输入exit关闭连接。

  1. $ telnet 127.0.0.1 8080
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. time
  6. 2015-07-14 17:44:06.743505631 +0800 CST
  7. exit
  8. Connection closed by foreign host.

4,总结

本文的原文连接是: http://www.jb51.cc/article/p-clygwvee-ber.html 转载请必须注明出处!

使用golang开发服务端还是非常方便的。 代码非常简洁,配合上goroutinue就可以写出高效的服务端代码

猜你在找的Go相关文章