前言
提示:这里可以添加本文要记录的大概内容:
计算机网络协议简单划分为7层,此文章主要是讲解传输层。传输层常用的协议是TCP和UDP协议。这两种协议各有优缺点,不同的场景下慎重选择,合适的协议。
提示:以下是本篇文章正文内容,下面案例可供参考
一、TCP和UDP 是什么?
TCP (Transmission Control Protocol)传输控制协议,是在OSI7层协议中的传输层,是面向连接的,传输可靠的基于字节流的协议。
UDP(User Datagram Protocol) 用户数据报协议,非链接的,传输不可靠的,通信无状态的协议;
二、使用场景
1.场景要求通信传输可靠的场景 : TCP
2.场景要求时效性高的场景: UDP
三、TCP和UDP不同
相同点:
在OSI 协议中位于传输层;
不同点: TCP 协议,利用三次握手建立连接, 序号,拥塞控制,request-ack机制,差错重传机制等保证了数据传输的可靠性。传输速率较慢;
UDP 协议简单,不用建立连接,不保证数据的有序性,运输数据丢失。 传输速率较快
四、demo
1.server
代码如下(示例):
package main
import (
"io"
"log"
"net"
"os"
)
// 上传
const OP_UPLOAD = 1
// 下载
const OP_DOWNLOAD = 0
// 上传目录
const UPLOAD_DIR = "upload/"
// 下载动作所需要的源文件目录
const SOURCE_DIR = "source-files/"
func main() {
lis, err := net.Listen("tcp", ":9090")
if err != nil {
log.Println(err)
return
}
defer lis.Close()
log.Println("listen on:", lis.Addr().String())
for {
conn, err := lis.Accept()
if err != nil {
log.Println(err)
return
}
log.Println("new conn:", conn.RemoteAddr().String())
go handle(conn)
}
}
func handle(conn net.Conn) {
defer conn.Close()
bytes := make([]byte, 512)
_, err := conn.Read(bytes)
if err != nil {
log.Println(err)
return
}
op := int(bytes[0])
fileNameLen := int(bytes[1])
fileName := string(bytes[2 : 2+fileNameLen])
if op == OP_UPLOAD {
err := recvFile(conn, UPLOAD_DIR+fileName)
if err != nil {
log.Println(err)
return
}
} else if op == OP_DOWNLOAD {
err := sendFile(conn, SOURCE_DIR+fileName)
if err != nil {
log.Println(err)
return
}
} else {
return
}
}
func recvFile(conn net.Conn, filePath string) (err error) {
file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Println(err)
return err
}
defer file.Close()
bytes := make([]byte, 2048)
for {
n, err := conn.Read(bytes)
if err != nil && err != io.EOF {
log.Println(err)
return err
}
if n == 0 {
break
}
file.Write(bytes[:n])
}
return
}
func sendFile(conn net.Conn, filePath string) (err error) {
src, err := os.Open(filePath)
if err != nil {
log.Println(err)
return err
}
defer src.Close()
bytes := make([]byte, 512)
for {
n, err := src.Read(bytes)
if err != nil && err != io.EOF {
log.Println(err)
return err
}
if n == 0 {
break
}
if _, err = conn.Write(bytes[:n]); err != nil {
log.Println(err)
return err
}
}
return
}
2. client
代码如下:
在这里插入代码片
总结
提示:这里对文章进行总结:
例如: