首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是什么导致了Go服务器中的“由对等方重置连接”错误?

是什么导致了Go服务器中的“由对等方重置连接”错误?
EN

Stack Overflow用户
提问于 2022-01-29 21:57:18
回答 1查看 724关注 0票数 -2

我已经在Go中编写了一个基本的web服务器,但是它似乎不能正确地处理任何请求,相反,我得到的只是"Recv failure: Connection reset by peer“。

我很高兴服务器确实正确地启动和停止,我可以看到它监听我已经配置的端口8080。我还排除了解析YAML配置文件的问题--它肯定会被解析为http.Server{}。

我不知道还能查些什么,也很难找到任何能指向我正确方向的东西。

我也会事先道歉,因为我知道我正在粘贴大量的代码,但我真的不知道错误的来源和来源。

考虑到服务器正在运行,当我到达"/“端点/路由时,我希望得到"Hello from Go!”又回来了。

目录结构

代码语言:javascript
运行
复制
❯ tree . | grep -iE 'cmd|server.go|go.mod|go.sum|server.yaml'
├── cmd
│   └── server.go
├── go.mod
├── go.sum
└── server.yaml

server.go

代码语言:javascript
运行
复制
package main

import (
    "context"
    "errors"
    "fmt"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"

    "gopkg.in/yaml.v3"
)

type Config struct {
    Port            string `yaml:"Port"`
    ReadTimeout     int    `yaml:"ReadTimeout"`
    WriteTimeout    int    `yaml:"WriteTimeout"`
    IdleTimeout     int    `yaml:"IdleTimeout"`
    ShutdownTimeout int    `yaml:"ShutdownTimeout"`
    ErrorLog        string `yaml:"ErrorLog"`
}

func main() {
    if len(os.Args) != 2 {
        log.Fatal("Missing arguments")
    }

    configFile, err := os.Open(os.Args[1])
    if err != nil {
        log.Fatal(err)
    }
    defer configFile.Close()

    // TODO: Implement a custom ServeMux + routes

    serverConfig := Config{}
    yamlDecoder := yaml.NewDecoder(configFile)
    err = yamlDecoder.Decode(&serverConfig)
    if err != nil {
        log.Fatal(err)
    }

    errorLogFile, err := os.OpenFile(serverConfig.ErrorLog, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        log.Fatal(err)
    }
    defer errorLogFile.Close()
    errorLog := log.New(errorLogFile, "ERROR : ", log.LstdFlags|log.Lshortfile)

    server := &http.Server{
        Addr:         fmt.Sprintf(":%s", serverConfig.Port),
        ReadTimeout:  time.Duration(serverConfig.ReadTimeout),
        WriteTimeout: time.Duration(serverConfig.WriteTimeout),
        IdleTimeout:  time.Duration(serverConfig.IdleTimeout),
        ErrorLog:     errorLog,
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello from Go!")
    })

    log.Println("Starting the server...")
    go func() {
        err := server.ListenAndServe()
        if !errors.Is(err, http.ErrServerClosed) {
            log.Fatal(err)
        }
        log.Println("Stopped serving new connections")
    }()
    log.Println("Server started")

    sigChan := make(chan os.Signal, 1)
    signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
    <-sigChan

    ctx, shutdown := context.WithTimeout(context.Background(), time.Duration(serverConfig.ShutdownTimeout)*time.Second)
    defer shutdown()

    err = server.Shutdown(ctx)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Server gracefully stopped")
}

错误信息

代码语言:javascript
运行
复制
❯ curl -v localhost:8080/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
* Recv failure: Connection reset by peer
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-29 22:50:09

正如注释中提到的,这个问题与超时值如此之短有关--每个值为5纳秒。这是因为time.Duration被表示为两个瞬间之间的经过时间,表示为一个int64纳秒计数。所以我需要把它转换成秒,才能得到我所期望的。

从医生那里:

持续时间以int64 纳秒计数表示两个瞬间之间的时间。表示将最大可表示的持续时间限制在大约290年。

参考文献

解决方案:

代码语言:javascript
运行
复制
server := &http.Server{
    Addr:         fmt.Sprintf(":%s", serverConfig.Port),
    ReadTimeout:  time.Duration(serverConfig.ReadTimeout) * time.Second,
    WriteTimeout: time.Duration(serverConfig.WriteTimeout) * time.Second,
    IdleTimeout:  time.Duration(serverConfig.IdleTimeout) * time.Second,
    ErrorLog:     errorLog,
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70910073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档