网络基础小记(一)

网络基础小记(一),第1张

TCP为啥需要三次握手、四次挥手 三次握手的最主要的目的是保证链接是双工的,可靠性更多是通过重传机制来保证的因为连接是全双工的,双方必须都收到对方的FIN包及确认才可以关闭


[s] 是seq包; [S.]是ack包; [P]是数据包; [F]是fin包 为什么time_wait需要等待2MSL 保证TCP协议的全双工连接能够可靠关闭保证这次连接的重复数据段从网络中消失 为啥会出现大量close_wait 首先close_wait一般出现在被动关闭方并发请求太多导致被动关闭方未能及时释放端口资源导致
package main

import (
	"fmt"
	"net"
)

func main() {
	//1、监听端口
	listener, err := net.Listen("tcp", "0.0.0.0:9090")
	if err != nil {
		fmt.Printf("listen fail, err: %v\n", err)
		return
	}
	//2.建立套接字连接
	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Printf("accept fail, err: %v\n", err)
			continue
		}
		//3. 创建处理协程
		go func(conn net.Conn) {
			//defer conn.Close() //思考题:这里不填写会有啥问题?
			// 这里不关闭的话 服务端出现close_wait 客户端fin_wait
			for {
				var buf [128]byte
				n, err := conn.Read(buf[:])
				if err != nil {
					fmt.Printf("read from connect failed, err: %v\n", err)
					break
				}
				str := string(buf[:n])
				fmt.Printf("receive from client, data: %v\n", str)
			}
		}(conn)
	}
}

TCP为啥需要流量控制 由于通讯双方,网速不同。通讯方任一方发送的过快都会导致对方消息处理不过来,所以就需要把数据放到缓冲区中如果缓冲区满了,发送方还在疯狂发送,那么接收方只能把数据包丢弃。因此我们需要控制发送速率我们缓冲区剩余大小称之为接收窗口,用变量win表示、如果wiin=0.则发送方停止发送
TCP为啥需要拥塞控制 流量控制和拥塞控制是两个概念,拥塞控制是调解网络的负载接收方网络资源繁忙,因未及时响应ACK导致发送方重传大量数据,这样将会导致网络更加拥堵拥堵控制是动态调整win大小,不只是依赖缓冲区大小确认窗口大小 TCP拥塞控制 慢开始和拥塞避免快速重传和快速恢复

为什么会出现粘包和拆包 应用程序写入的数据大于套接字缓冲区大小,这将会发生拆包应用程序写入数据小于套接字缓冲=区大小,网卡将应用多次写入的数据发送到网络上,这将会发生粘包进行MSS(最大报文长度)大小的TCP分段,当TCP报文长度-TCP头部长度>MSS的时候将发送拆包接收方法不及时读取套接字缓冲区数据,这将会发生粘包
一个简单的decode和encode代码
package main

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
)

const Msg_Header = "12345678"

func main() {
	//类比接收缓冲区 net.Conn
	bytesBuffer := bytes.NewBuffer([]byte{})

	//发送
	if err := Encode(bytesBuffer, "hello world 0!!!"); err != nil {
		panic(err)
	}
	if err := Encode(bytesBuffer, "hello world 1!!!"); err != nil {
		panic(err)
	}

	//读取
	for {
		if bt, err := Decode(bytesBuffer); err == nil {
			fmt.Println(string(bt))
			continue
		}
		break
	}
}

func Encode(bytesBuffer io.Writer, content string) error {
	//msg_header+content_len+content
	//8			+4			+content
	if err := binary.Write(bytesBuffer, binary.BigEndian, []byte(Msg_Header)); err != nil {
		return err
	}
	clen := int32(len([]byte(content)))
	if err := binary.Write(bytesBuffer, binary.BigEndian, clen); err != nil {
		return err
	}
	if err := binary.Write(bytesBuffer, binary.BigEndian, []byte(content)); err != nil {
		return err
	}
	return nil
}

func Decode(bytesBuffer io.Reader) (bodyBuf []byte, err error) {
	MagicBuf := make([]byte, len(Msg_Header))
	if _, err = io.ReadFull(bytesBuffer, MagicBuf); err != nil {
		return nil, err
	}
	if string(MagicBuf) != Msg_Header {
		return nil, errors.New("msg_header error")
	}

	lengthBuf := make([]byte, 4)
	if _, err = io.ReadFull(bytesBuffer, lengthBuf); err != nil {
		return nil, err
	}

	length := binary.BigEndian.Uint32(lengthBuf)
	bodyBuf = make([]byte, length)
	if _, err = io.ReadFull(bytesBuffer, bodyBuf); err != nil {
		return nil, err
	}
	return bodyBuf, err
}
服务端和客户端代码
package main

import (
	"fmt"
	"github.com/e421083458/gateway_demo/demo/base/unpack/unpack"
	"net"
)

func main() {
	//simple tcp server
	//1.监听端口
	listener, err := net.Listen("tcp", "0.0.0.0:9090")
	if err != nil {
		fmt.Printf("listen fail, err: %v\n", err)
		return
	}

	//2.接收请求
	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Printf("accept fail, err: %v\n", err)
			continue
		}

		//3.创建协程
		go process(conn)
	}
}

func process(conn net.Conn) {
	defer conn.Close()
	for {
		bt, err := unpack.Decode(conn)
		if err != nil {
			fmt.Printf("read from connect failed, err: %v\n", err)
			break
		}
		str := string(bt)
		fmt.Printf("receive from client, data: %v\n", str)
	}
}

package main

import (
	"fmt"
	"github.com/e421083458/gateway_demo/demo/base/unpack/unpack"
	"net"

)

func main() {
	conn, err := net.Dial("tcp", "localhost:9090")
	defer conn.Close()
	if err != nil {
		fmt.Printf("connect failed, err : %v\n", err.Error())
		return
	}
	unpack.Encode(conn, "hello world 0!!!")
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/990531.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存