TCP 工作在网络的传输层,它属于一种面向连接的可靠的通信协议。
TCP 服务器的工作过程:
- TCP 服务器首先注册一个公知端口,然后调用 Listen() 函数在这个端口上创建一个 TCPListener 监听对象,并在该对象上监听客户机的连接请求。
- 启用 TCPListener 对象的 Accept() 方法接收客户机的连接请求,并返回一个协议相关的 Conn 对象,这里就是 TCPConn 对象。
- 如果返回了一个新的 TCPConn 对象,服务器就可以调用该对象的 Read() 方法接收客户机发来的数据,或者调用 Write() 方法向客户机发送数据了。
主程序
package main
import(
"server"
)
func main() {
server := server.NewServer(":8000");
server.Start();
}
服务端定义
package server
import (
"log"
"net"
"os"
)
type Server struct {
Address string
}
func NewServer(address string) *Server{
return &Server{
Address: address,
}
}
// 开启TCP服务
func (this *Server) Start(){
l, err := net.Listen("tcp", this.Address);
checkError(err)
defer l.Close()
log.Printf("Server start: %s\n", this.Address)
for {
conn, err := l.Accept()
if err != nil {
log.Println(err.Error())
continue
}
go handleConnection(conn);
}
}
// 连接接收
func handleConnection(conn net.Conn){
rAddr := conn.RemoteAddr()
log.Printf("Connect from client: %s\n", rAddr)
defer conn.Close()
var buf [1036]byte
n, err := conn.Read(buf[0:])
if err != nil {
return
}
msg := string(buf[0:n])
log.Printf("Receive from client: %s length: %d", rAddr, n)
}
func checkError(err error) {
if err != nil {
log.Printf("Fatal error %s", err.Error())
os.Exit(1)
}
}
客户端测试
客户端的工作过程如下:
- TCP 客户机在获取了服务器的服务端口号和服务地址之后,可以调用 DialTCP() 函数向服务器发出连接请求,如果请求成功会返回 TCPConn 对象。
- 客户机调用 TCPConn 对象的 Read() 或 Write() 方法,与服务器进行通信活动。
- 通信完成后,客户机调用 Close() 方法关闭连接,断开通信链路。
package main
import(
"fmt"
"net"
"os"
)
func main() {
var buf [512]byte
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: %s host:port", os.Args[0])
}
service := os.Args[1]
tcpAddr, err := net.ResolveTCPAddr("tcp", service)
checkError(err)
conn, err := net.DialTCP("tcp", nil, tcpAddr)
checkError(err)
rAddr := conn.RemoteAddr()
n, err := conn.Write([]byte("Hello server"))
checkError(err)
n, err = conn.Read(buf[0:])
checkError(err)
fmt.Println("Reply form server", rAddr.String(), string(buf[0:n]))
conn.Close()
os.Exit(0)
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
}