SOCKS5简单项目逻辑 | 青训营笔记

45 阅读2分钟

这是我参加青训营的第十天。

简单的TCP实现

为了实现一个复杂的代理业务,首先我们实现一个简单的TCP业务逻辑。

首先是第一段程序(主函数):

  • net.Listen("tcp", "127.0.0.1:1080"):在本地主机上监听端口 1080,并返回一个 net.Listener 类型的对象。如果发生错误,则会调用 panic(err)
  • for 循环:在每次迭代中,通过调用 server.Accept() 接受新连接。如果发生错误,会在日志中输出错误信息,并继续下一次迭代。其中,Accept() 方法是用于接受连接请求的。在服务器端编程中,Accept() 方法用于监听客户端的连接请求,并在有客户端连接请求时返回一个新的 socket,表示与该客户端的连接。
  • go process(client):调用 process(client) 函数处理连接。由于这里使用了 go 关键字,所以该函数会在一个新的 goroutine 中运行,这样可以并行处理多个连接。

这个程序实现了一个简单的 TCP 服务器,它监听本地主机的端口 1080,接受客户端连接并将连接交给 process(client) 函数处理。

第二段程序 (process函数):

这段代码是一个处理客户端连接的函数。它接收一个net.Conn类型的参数,表示一个客户端连接。

defer conn.Close()语句会在函数结束时关闭连接。

使用bufio.NewReader(conn)创建一个读取器。

紧接着是一个for循环,在循环体中,使用reader.ReadByte()方法读取一个字节。如果读取失败,就退出循环。

然后,使用conn.Write([]byte{b})方法将读取到的字节写回给客户端。如果写入失败,也会退出循环。

这段代码实现了一个简单的回显服务,它会读取客户端发来的数据,并将读取到的数据原样返回给客户端。

package main

import (
	"bufio"
	"log"
	"net"
)

func main() {
	server, err := net.Listen("tcp", "127.0.0.1:1080")
	if err != nil {
		panic(err)
	}
	for {
		client, err := server.Accept()
		if err != nil {
			log.Printf("Accept failed %v", err)
			continue
		}
		go process(client)
	}
}

func process(conn net.Conn) {
	defer conn.Close()
	reader := bufio.NewReader(conn)
	for {
		b, err := reader.ReadByte()
		if err != nil {
			break
		}
		_, err = conn.Write([]byte{b})
		if err != nil {
			break
		}
	}
}

image.png

image.png