实现TCP连接的双向拷贝
用io.Copy
来实现内容拷贝,将源端数据复制到目标端,为防止内存溢出,
io.Copy
方法默认缓冲区为32k,io.CopyBuffer
方法可以设置缓冲区大小
用一个goroutine从server拷贝到client,再用另外一个goroutine从client拷贝到server。任何一方断开连接,双向都断开连接。
实现方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
package main
import (
"io"
"log"
"net"
)
func main() {
listener, err := net.Listen("tcp", "127.0.0.1:8087")
if err != nil {
panic(err)
}
for {
conn, err := listener.Accept()
if err != nil {
panic(err)
}
go handle(conn.(*net.TCPConn))
}
}
func handle(server *net.TCPConn) {
client, err := net.Dial("tcp", "127.0.0.1:8088")
if err != nil {
log.Printf("dial err: %v\n", err)
return
}
go func() {
buf := make([]byte, 2048)
_, err := io.CopyBuffer(server, client, buf)
if err != nil {
log.Printf("server err %v\n", err)
}
server.Close()
}()
buf := make([]byte, 2048)
_, err = io.CopyBuffer(client, server, buf)
if err != nil {
log.Printf("client err %v\n", err)
}
client.Close()
}
|
运行测试
1
2
|
$ nc -lk 127.0.0.1 8088
hello
|
- 运行tcp拷贝服务,监听
8087
端口,转发到8088
端口
1
2
|
$ GO111MODULE=off go run main.go
|
- 创建一个tcp连接到
8087
端口,并发送hello
消息,8088
端口收到消息
1
2
3
4
5
6
7
8
9
10
11
12
|
$ nc -v 127.0.0.1 8087
found 0 associations
found 1 connections:
1: flags=82<CONNECTED,PREFERRED>
outif lo0
src 127.0.0.1 port 58804
dst 127.0.0.1 port 8088
rank info not available
TCP aux info available
Connection to 127.0.0.1 port 8088 [tcp/radan-http] succeeded!
hello
|
参考