本篇是上一篇的 看点2
内容。本该放上篇,但是由于上篇内容已经不少,所以单独拆开。另外还是主动说明下:我使用quic-go版本是github.com/quic-go/quic-go v0.47.0
,
虽然我在上篇截图过程中就尽量带上了quic-go版本信息,但在此还是再次说明。
本篇分析代码如下:
for {
conn, err := listener.Accept(context.Background())
// ... use conn...
}
看下面官方源码和注释:Accept返回新的连接,本方法应该在循环中调用。
都给出使用说明了:
// Accept returns new connections. It should be called in a loop.
func (l *Listener) Accept(ctx context.Context) (Connection, error) {
return l.baseServer.Accept(ctx)
}
// Accept returns connections that already completed the handshake.
// It is only valid if acceptEarlyConns is false.
// 返回已完成握手的连接
// 只有当 acceptEarlyConns标识(上篇有说明)为false的时候,返回的连接才是有效的
func (s *baseServer) Accept(ctx context.Context) (Connection, error) {
return s.accept(ctx)
}
func (s *baseServer) accept(ctx context.Context) (quicConn, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
case conn := <-s.connQueue: // 从这个chan中读取连接
return conn, nil
case <-s.errorChan:
return nil, s.closeErr
}
}
在上篇我们知道connQueue是一个长度为32的quicConn chan,
那么问题来了,谁往baseServer的connQueue扔连接呢?
server.go第555行:
func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error
方法内的723行:
这个方法内容很多,回头我们分析,先看看是谁调用了它?
server.go第377行:
func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer still in use? */
方法内的第459行:
这个handlePacketImpl方法内容同样不少,那么是谁调用了它呢?
闭环了朋友们,在上篇提到了上图第299行代码很重要,但是没有解释为什么,现在~
在继续分析之前,我们先来一张粗略图:
流程清楚了后:知道了如何接收到数据包后,接下来就好说了,去看看
func (s *baseServer) handlePacketImpl(p receivedPacket) bool
里的逻辑:
客户端请求下,代码如下:
package main
import (
"context"
"crypto/tls"
"encoding/binary"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strconv"
"time"
"github.com/quic-go/quic-go"
)
const addr = "127.0.0.1:9000"
func main() {
tlsConf := &tls.Config{
InsecureSkipVerify: true,
NextProtos: []string{
"HLD"},
}
conn, err := quic.DialAddr(context.Background(), addr, tlsConf, nil)
if err != nil {
log.Fatalf("Error dialing address: %v", err)
}
defer conn.CloseWithError(0, "")
stream, err := conn.OpenStreamSync(context.Background())
if err != nil {
log.Fatalf("Error opening stream: %v", err)</