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 }