超越 “Hello World”(3)

55-58有一个函数从源套接字from读数据,写到日志文件,再将数据发送到目标套接字to。对于每一个连接有两个pass_through函数的实例在本地和远程套接字间向相反的方向拷贝数据。当I/O错误出现时,视为连接断开。最后,79行的函数向主线程发送确认,通知pass_through函数终止。

55    func pass_through(c *Channel) {
  56      from_peer := printable_addr(c.from.LocalAddr())
  57      to_peer := printable_addr(c.to.LocalAddr())
 
  58      b := make([]byte, 10240)
  59      offset := 0
  60      packet_n := 0
  61      for {
  62        n, err := c.from.Read(b)
  63        if err != nil {
  64          c.logger <- []byte(fmt.Sprintf("Disconnected from %s\n",
                from_peer))
  65          break
  66        }
  67        if n > 0 {
  68          c.logger <- []byte(fmt.Sprintf("Received (#%d, %08X)
                %d bytes from %s\n",
                packet_n, offset, n, from_peer))
  69          c.logger <- []byte(hex.Dump(b[:n]))
  70          c.binary_logger <- b[:n]
  71          c.to.Write(b[:n])
  72          c.logger <- []byte(fmt.Sprintf("Sent (#%d) to %s\n",
                packet_n, to_peer))
  73          offset += n
  74          packet_n += 1
  75        }
  76      }
  77      c.from.Close()
  78      c.to.Close()
  79      c.ack <- true
  80    }

81-107行的函数处理整所有连接。它连接远程套接字(82行),测量连接持续时间(行88,101-103),启动日志器(行93-95),最后启动两个数据传输线程(行97-98)。函数pass_through运行直至通信两端都启动。行99-100等待来之数据传输线程的确认。行104-106终止日志器。

81    func process_connection(local net.Conn, conn_n int, target string) {
  82      remote, err := net.Dial("tcp", target)
  83      if err != nil {
  84        fmt.Printf("Unable to connect to %s, %v\n", target, err)
  85      }
 
  86      local_info := printable_addr(remote.LocalAddr())
  87      remote_info := printable_addr(remote.RemoteAddr())
 
  88      started := time.Now()
 
  89      logger := make(chan []byte)
  90      from_logger := make(chan []byte)
  91      to_logger := make(chan []byte)
  92      ack := make(chan bool)
 
  93      go connection_logger(logger, conn_n, local_info, remote_info)
  94      go binary_logger(from_logger, conn_n, local_info)
  95      go binary_logger(to_logger, conn_n, remote_info)
 
  96      logger <- []byte(fmt.Sprintf("Connected to %s at %s\n",
              target, format_time(started)))
 
  97      go pass_through(&Channel{remote, local, logger, to_logger, ack})
  98      go pass_through(&Channel{local, remote, logger, from_logger, ack})
  99      <-ack // Make sure that the both copiers gracefully finish.
  100      <-ack //
 
  101      finished := time.Now()
  102      duration := finished.Sub(started)
  103      logger <- []byte(fmt.Sprintf("Finished at %s, duration %s\n",
              format_time(started), duration.String()))
 
  104      logger <- []byte{}      // Stop logger
  105      from_logger <- []byte{} // Stop "from" binary logger
  106      to_logger <- []byte{}  // Stop "to" binary logger
  107    }

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

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