第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

Golang 學(xué)習(xí)筆記——網(wǎng)絡(luò)編程

標(biāo)簽:
Go

Golang 主要面向后端服务编程,网络通信是服务端程序必不可少的重点。主流通信协议有 udp 和 tcp,通过编程语言封装成 socket,简化编程。主要实现对应的服务端和客户端。

  • golang udp
  • golang tcp
  • golang kcp

Golang udp

server

import (
	"fmt"
	"net"
)

func main() {
	laddr, err := net.ResolveUDPAddr("udp", ":9000")
	if err != nil {
		fmt.Println("地址解析失败!", err)
		return
	}
	conn, err := net.ListenUDP("udp", laddr)
	if err != nil {
		fmt.Println("udp服务启动失败!", err)
		return
	}
	fmt.Println("udp服务启动成功")
	defer conn.Close()

	for {
		buf := make([]byte, 65535)
		num, remoteAddr, err := conn.ReadFromUDP(buf)
		if err != nil {
			fmt.Println("接收数据失败!", err)
			continue
		}

		fmt.Println("客户端地址:", remoteAddr)
		fmt.Printf("接收客户端数据长度:%d, 数据:%s", num, buf)

		send := []byte("receive success!")

		_, err = conn.WriteToUDP(send, remoteAddr)
		if err != nil {
			fmt.Println("发送数据失败!", err)
			continue
		}
	}
}

client

import (
	"fmt"
	"net"
)

func main() {

	laddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:9000")
	if err != nil {
		fmt.Println("地址解析失败!", err)
		return
	}
	conn, err := net.DialUDP("udp", nil, laddr)
	if err != nil {
		fmt.Println("连接服务失败!", err)
		return
	}

	send := []byte("hello world!")

	_, err = conn.Write(send)
	if err != nil {
		fmt.Println("发送数据失败!", err)
		return
	}
	buf := make([]byte, 65535)
	num, remoteAddr, err := conn.ReadFromUDP(buf)
	if err != nil {
		fmt.Println("接收数据失败!", err)
		return
	}

	fmt.Println("服务端地址:", remoteAddr)
	fmt.Printf("接收服务端数据长度:%d, 数据:%s", num, buf)
}

图片描述
图片描述

Golang tcp

server


import (
	"fmt"
	"net"
)

func main() {
	laddr, err := net.ResolveTCPAddr("tcp", ":9000")
	if err != nil {
		fmt.Println("地址解析失败!", err)
		return
	}
	listener, err := net.ListenTCP("tcp", laddr)
	if err != nil {
		fmt.Println("tcp服务启动失败!", err)
		return
	}
	fmt.Println("tcp服务启动成功")
	defer listener.Close()
	for {

		conn, err := listener.AcceptTCP()
		if err != nil {
			fmt.Println("建立连接失败!", err)
			continue
		}
		go handleTcpClient(conn)
	}
}

func handleTcpClient(conn *net.TCPConn) {
	buf := make([]byte, 4096)
	for {
		num, err := conn.Read(buf)
		if err != nil {
			fmt.Println("接收数据失败!", err)
			return
		}
		fmt.Println("客户端地址:", conn.RemoteAddr())
		fmt.Printf("接收客户端数据长度:%d, 数据:%s", num, buf[:num])

		if fmt.Sprintf("%s", buf[:num]) == "ByeBye" {
			// 接收到 ByeBye 就断线
			fmt.Println("客户端离线!")
			return
		}
		send := []byte("receive success!")
		_, err = conn.Write(send)
		if err != nil {
			fmt.Println("发送数据失败!", err)
			return
		}
	}
}

client

import (
	"fmt"
	"net"
)

func main() {

	laddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:9000")
	if err != nil {
		fmt.Println("地址解析失败!", err)
		return
	}
	conn, err := net.DialTCP("tcp", nil, laddr)
	if err != nil {
		fmt.Println("连接服务失败!", err)
		return
	}

	send := []byte("hello world!")
	buf := make([]byte, 65535)
	for i := 0; i < 10; i++ {
		_, err = conn.Write(send)
		if err != nil {
			fmt.Println("发送数据失败!", err)
			return
		}
		num, err := conn.Read(buf)
		if err != nil {
			fmt.Println("接收数据失败!", err)
			return
		}

		fmt.Println("服务端地址:", conn.RemoteAddr())
		fmt.Printf("接收服务端数据长度:%d, 数据:%s", num, buf[:num])
	}
	bye := []byte("ByeBye")
	_, err = conn.Write(bye)
	if err != nil {
		fmt.Println("发送数据失败!", err)
		return
	}
}

图片描述
图片描述

Golang kcp

简介:kcp是一个基于udp实现快速、可靠、向前纠错的的协议,能以比TCP浪费10%-20%的带宽的代价,换取平均延迟降低30%-40%,且最大延迟降低三倍的传输效果。
kcp-go是用go实现了kcp协议的一个库.

server

import (
	"fmt"
	"github.com/xtaci/kcp-go"
)

func main() {
	// 不加密,不设置
	listener, err := kcp.ListenWithOptions(":9000", nil, 0, 0)
	if err != nil {
		fmt.Println("udp服务启动失败!", err)
		return
	}
	fmt.Println("kcp服务启动成功")
	defer listener.Close()
	for {

		conn, err := listener.AcceptKCP()
		if err != nil {
			fmt.Println("建立连接失败!", err)
			continue
		}
		fmt.Println("客户端地址:", conn.RemoteAddr())
		go handleKcpClient(conn)
	}
}

func handleKcpClient(conn *kcp.UDPSession) {
	buf := make([]byte, 4096)
	for {
		num, err := conn.Read(buf)
		if err != nil {
			fmt.Println("接收数据失败!", err)
			return
		}
		fmt.Printf("接收客户端数据长度:%d, 数据:%s\n", num, buf[:num])

		if fmt.Sprintf("%s", buf[:num]) == "ByeBye" {
			// 接收到 ByeBye 就断线
			fmt.Println("客户端离线!")
			return
		}
		send := []byte("receive success!")
		_, err = conn.Write(send)
		if err != nil {
			fmt.Println("发送数据失败!", err)
			return
		}
	}
}

client

import (
	"fmt"
	"github.com/xtaci/kcp-go"
	"strconv"
	"time"
)

var data = []byte("hello world!")

func main() {

	conn, err := kcp.DialWithOptions("127.0.0.1:9000", nil, 0, 0)
	if err != nil {
		fmt.Println("连接服务失败!", err)
		return
	}
	fmt.Println("服务端地址:", conn.RemoteAddr())

	go handleKcpConn(conn)

	select {}
}

func handleKcpConn(conn *kcp.UDPSession) {
	buf := make([]byte, 65535)

	for {
		send := append(data, strconv.FormatInt(time.Now().Unix(), 10)...)
		num, err := conn.Write(send)
		if err != nil {
			fmt.Println("发送数据失败!", err)
			return
		}
		num, err = conn.Read(buf)
		if err != nil {
			fmt.Println("接收数据失败!", err)
			return
		}
		fmt.Printf("接收服务端数据长度:%d, 数据:%s\n", num, buf[:num])

		time.Sleep(time.Second)
	}
}

图片描述
图片描述

kcp-go实现的 kcp 编程看上去和 tcp 很相似,但是实际底层使用的是 udp 协议。kcp 头部占24个字节,kcp 发送数据会先分包,加装 kcp 头部,再通过 udp 发送数据到远端。远端需要返回 ack,根据返回的ack来判断数据段是否需要重传还是在队列里清除该数据段。用抓包工具抓包就会发现有很多24字节的 udp 包。

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消