一秒学会tcp


前言

提示:这里可以添加本文要记录的大概内容:

计算机网络协议简单划分为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

代码如下:

在这里插入代码片

总结

提示:这里对文章进行总结:
例如:

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值