目录
前言
Go作为一门“新兴”语言,凭借其简单易学和优越的性能,以及原生的goroutine并发模型,在网络服务器编程方面有其不可替代的位置,下面就来记录使用go从简单的tcp服务到逐渐完善的服务端开发过程,在此过程中我们将用到:
- net包中关于tcp的方法;
- goroutine和channel的并发编程;
- golang的异常处理;
net包中关于tcp开发的方法
服务端代码
package main
import (
"fmt"
"net"
)
func main() {
// listen监听TCP
addr := "0.0.0.0:12345"
lsr, err := net.Listen("tcp", addr)
if err != nil {
fmt.Println("failed listen", addr, err)
return
}
defer lsr.Close()
// accept同步等待客户端连接
// conn客户端新建连接
conn, err := lsr.Accept()
if err != nil {
fmt.Println("failed accept", err)
return
}
defer conn.Close()
fmt.Println("new tcp connection")
fmt.Println("connection local address", conn.LocalAddr())
fmt.Println("connection remote address", conn.RemoteAddr())
// read同步等待客户端发送数据包
// readBuffer预分配读取空间
var readBuffer = make([]byte, 1024)
readBytes, err := conn.Read(readBuffer)
if err != nil {
fmt.Println("failed read", err)
return
}
fmt.Println("read", readBytes, string(readBuffer[:readBytes]))
// 业务逻辑处理
sendBuffer := []byte("Hello " + string(readBuffer[:readBytes]))
// 网络应答
sendBytes, err := conn.Write(sendBuffer)
if err != nil {
fmt.Println("failed write", err)
return
}
fmt.Println("send", sendBytes, string(sendBuffer))
// 完毕
}
客户端代码
package main
import (
"fmt"
"net"
)
func main() {
// dial客户端连接到服务端
addr := "0.0.0.0:12345"
conn, err := net.Dial("tcp", addr)
if err != nil {
fmt.Println("failed connect to server", addr, err)
return
}
defer conn.Close()
fmt.Println("new tcp connection")
fmt.Println("connection local address", conn.LocalAddr())
fmt.Println("connection remote address", conn.RemoteAddr())
// 业务逻辑
var sendBuffer = []byte("tcpclient")
// write发送请求包
sendBytes, err := conn.Write(sendBuffer)
if err != nil {
fmt.Println("failed send", addr, err)
return
}
fmt.Println("send", sendBytes, string(sendBuffer))
// read同步等待服务端应答
// readBuffer预分配读取空间
var readBuffer = make([]byte, 1024)
readBytes, err := conn.Read(readBuffer)
if err != nil {
fmt.Println("failed read", err)
return
}
fmt.Println("read", readBytes, string(readBuffer[:readBytes]))
}
运行结果
服务端
new tcp connection
connection local address 127.0.0.1:12345
connection remote address 127.0.0.1:63549
read 9 tcpclient
send 15 Hello tcpclient
客户端
new tcp connection
connection local address 127.0.0.1:63549
connection remote address 127.0.0.1:12345
send 9 tcpclient
read 15 Hello tcpclient
当然,这仅仅是最基础的tcp网络应用示例,服务端仅能处理一次请求,明天我们继续完善:
- 服务端如何处理多tcp客户端链接;
- 非阻塞服务端如何开发;
- 服务端如何退出;