超越 “Hello World”(2)

2-11行声明了程序将要用到的包。需要注意,如果一个包被包含了但是没有用到,Go将认为这是一种错误,并强制删除没有用到的声明(还记得上次你想放弃并不耐烦地清理C++项目中STL包含进来的列表吗?)

1    package main
  2    import (
  3      "encoding/hex"
  4      "flag"
  5      "fmt"
  6      "net"
  7      "os"
  8      "runtime"
  9      "strings"
  10      "time"
  11    )

12-16行声明了用来表示命令行标识的全局变量。下面将看到如何解析它们。

12    var (
  13      host *string = flag.String("host", "",
          "target host or address")
  14      port *string = flag.String("port", "0", "target port")
  15      listen_port *string = flag.String("listen_port", "0",
          "listen port")
  16    )

17-20行我们看到了Go语言可变参数函数参数的语法。

17    func die(format string, v ...interface{}) {
  18      os.Stderr.WriteString(fmt.Sprintf(format+"\n", v...))
  19      os.Exit(1)
  20    }

21-28行有两个函数用来启动十六进制导出和二进制日志器。区别仅在于日志名不同。

21    func connection_logger(data chan []byte, conn_n int,
            local_info, remote_info string) {
  22      log_name := fmt.Sprintf("log-%s-%04d-%s-%s.log",
            format_time(time.Now()), conn_n, local_info, remote_info)
  23      logger_loop(data, log_name)
  24    }
  25    func binary_logger(data chan []byte, conn_n int, peer string) {
  26      log_name := fmt.Sprintf("log-binary-%s-%04d-%s.log",
            format_time(time.Now()), conn_n, peer)
  27      logger_loop(data, log_name)
  28    }

29-43行是Go乐趣的开始,logger_loop函数创建一个日志文件,然后开始进入无限循环(35-42行)。36行代码等待来之管道data的消息。一个有意思的技巧在34行,defer操作符允许我们定义一个代码块,在函数域的末尾这个代码块一定会执行(类似于Java的 finally)。如果接收到的数据为空,函数退出。

29    func logger_loop(data chan []byte, log_name string) {
  30      f, err := os.Create(log_name)
  31      if err != nil {
  32        die("Unable to create file %s, %v\n", log_name, err)
  33      }
  34      defer f.Close()
  35      for {
  36        b := <-data
  37        if len(b) == 0 {
  38          break
  39        }
  40        f.Write(b)
  41        f.Sync()
  42      }
  43    }
  44    func format_time(t time.Time) string {
  45      return t.Format("2006.01.02-15.04.05")
  46    }
  47    func printable_addr(a net.Addr) string {
  48      return strings.Replace(a.String(), ":", "-", -1)
  49    }
  50    type Channel struct {
  51      from, to              net.Conn
  52      logger, binary_logger chan []byte
  53      ack                  chan bool
  54    }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/901c8d2d20942b7d88e3cd2a380cd535.html