序言
众所周知,TCP 协议是当今互联网中的一个非常重要的一环,正是因为有了 TCP 这个协议,才能保证数据能够无误地在设备之间传输
最新的 http3 协议已经抛弃了 tcp 的方式,改用了 udp + quic 来实现了数据的传输
先说一下 TCP/IP 的一些基础:
- TCP 是传输层的一个协议,是在 IP (网络层)之上实现的,这个协议一般是操作系统层面就已经实现了
- TCP 协议是面向连接的,提供了可靠交付功能(数据传输不会丢失,发送方发送的内容和接收方接收到的内容是一致的)
代码实现
服务端
在实现之前,我们先讲一下思路:
- 因为 tcp 是面向连接的,所以我们应该先尝试建立一个连接,建立的过程我们不需要管,操作系统已经帮我们实现了
- 然后,我们需要有一个独立的协程负责处理这个连接,监听连接发送过来的数据
按照这个思路,我们简单实现一下:
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-10-18 23:47:00
* @Description
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
*/
package main
import (
"log"
"net"
)
/**
负责处理一个连接,监听并打印
*/
func accept(conn net.Conn) {
defer conn.Close()
for {
buffer := [256]byte{}
n, err := conn.Read(buffer[:])
if err != nil {
log.Println(err)
break
}
log.Println("message: ", string(buffer[:n]))
}
}
func main() {
// 启动一个 tcp server, 在 3000 端口监听
listen, err := net.Listen("tcp", ":3000")
if err != nil {
log.Fatal(err)
}
defer listen.Close()
for {
// 等待连接,在没有连接的时候,主进程会在这里阻塞,
// 直到有 client 请求连接
conn, err := listen.Accept()
if err != nil {
log.Println(err)
break
}
log.Println("accept from:", conn.RemoteAddr())
// 启动一个 goroutine 处理这个连接
go accept(conn)
}
}
客户端
客户端就比服务端更简单了,因为不需要应付多个服务端,那客户端只需要一个 tcp 就够了,我们简单写一下
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-10-18 23:53:41
* @Description:
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
*/
package main
import (
"fmt"
"log"
"net"
)
func main() {
// 创建一个 tcp 客户端
conn, err := net.Dial("tcp", ":3000")
if err != nil {
log.Panicln(err)
}
defer conn.Close()
for {
var input string
fmt.Scan(&input)
_, err := conn.Write([]byte(input)) // 写入 tcp 连接中
if err != nil {
log.Println(err)
break
}
}
}
Tips
因为 tcp 实际传输的是字节,因此你甚至可以用一些同样是 tcp 协议的客户端来请求这个服务端口,比如 ssh,虽然连不上就对了(乐
作者:NorthCity1984
出处:https://grimoire.cn/golang/go-tcp.html
版权:本文《【Go】简单实现一个tcp服务器》版权归作者所有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
出处:https://grimoire.cn/golang/go-tcp.html
版权:本文《【Go】简单实现一个tcp服务器》版权归作者所有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任