基于UDP协议可靠传输协议QUIC协议和golang server代码和client代
一. QUIC 的基本特点基于UDP的多路传输(单连接下); 二. 为什么不用TCPTCP由于基于操作系统内核实现,发展速度极慢,现有的TCP Fast Open实现等等虽然早已存在于标准中但是实际应用情况及其落后,即便除非所有机器的操作系统都更新到最新,否则考虑到兼容性不太可能大范围采用新技术。 三. QUIC的发展路线QUIC成为一个独立的传输层方案,成为更多应用层的高性能选择; 四. 核心优势
下面是golang基于quic协议实现的server代码 package main
import (
"github.com/lucas-clemente/quic-go"
"io"
"fmt"
"crypto/tls"
"crypto/rsa"
"crypto/x509"
"math/big"
"encoding/pem"
"crypto/rand"
)
const saddr = "localhost:9999"
func main() {
listener,err := quic.ListenAddr(saddr,generateTLSConfig(),nil)
if err != nil {
fmt.Println(err)
}
for{
sess,err := listener.Accept()
if err != nil {
fmt.Println(err)
}else{
go dealSession(sess)
}
}
}
func dealSession(sess quic.Session){
stream,err := sess.AcceptStream()
if err != nil {
panic(err)
}else{
for{
_,err = io.Copy(loggingWriter{stream},stream)
}
}
}
type loggingWriter struct{ io.Writer }
func (w loggingWriter) Write(b []byte) (int,error) {
fmt.Printf("Server: Got '%s'n",string(b))
return w.Writer.Write(b)
}
// Setup a bare-bones TLS config for the server
func generateTLSConfig() *tls.Config {
key,err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
panic(err)
}
template := x509.Certificate{SerialNumber: big.NewInt(1)}
certDER,err := x509.CreateCertificate(rand.Reader,&template,&key.PublicKey,key)
if err != nil {
panic(err)
}
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY",Bytes: x509.MarshalPKCS1PrivateKey(key)})
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE",Bytes: certDER})
tlsCert,err := tls.X509KeyPair(certPEM,keyPEM)
if err != nil {
panic(err)
}
return &tls.Config{Certificates: []tls.Certificate{tlsCert}}
}
下面是golang基于quic协议实现的client代码 package main
import (
"github.com/lucas-clemente/quic-go"
"io"
"crypto/tls"
"fmt"
"time"
)
const addr = "localhost:9999"
const message = "ccc"
func main() {
session,err := quic.DialAddr(addr,&tls.Config{InsecureSkipVerify: true},nil)
if err != nil {
fmt.Println(err)
return
}
stream,err := session.OpenStreamSync()
if err != nil {
fmt.Println(err)
return
}
for{
fmt.Printf("Client: Sending '%s'n",message)
_,err = stream.Write([]byte(message))
if err != nil {
fmt.Println(err)
return
}
buf := make([]byte,len(message))
_,err = io.ReadFull(stream,buf)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Client: Got '%s'n",buf)
time.Sleep(2*time.Second)
}
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |