这是我参加青训营的第十天。
简单的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
}
}
}