golang udp连接每隔写入一次就被拒绝 [英] golang udp connection refused on every other write

查看:63
本文介绍了golang udp连接每隔写入一次就被拒绝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ubuntu linux 16.04上运行了该UDP客户端程序:

I ran this UDP client program on ubuntu linux 16.04:

package main

import (
    "fmt"
    "net"
    "time"
    "strconv"
)

func CheckError(err error) {
    if err  != nil {
        fmt.Println("Error: " , err)
    }
}

func main() {
    ServerAddr,err := net.ResolveUDPAddr("udp","127.0.0.1:10001")
    CheckError(err)

    LocalAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
    CheckError(err)

    Conn, err := net.DialUDP("udp", LocalAddr, ServerAddr)
    CheckError(err)

    defer Conn.Close()
    i := 0
    for {
        msg := strconv.Itoa(i)
        i++
        buf := []byte(msg)
        _,err := Conn.Write(buf)
        if err != nil {
            fmt.Println(msg, err)
        }
        time.Sleep(time.Second * 1)
    }
}

它产生以下输出:

$ go run server.go 
1 write udp 127.0.0.1:58703->127.0.0.1:10001: write: connection refused
3 write udp 127.0.0.1:58703->127.0.0.1:10001: write: connection refused
5 write udp 127.0.0.1:58703->127.0.0.1:10001: write: connection refused

但我希望此输出相反:

$ go run server.go 
1 write udp 127.0.0.1:58703->127.0.0.1:10001: write: connection refused
2 write udp 127.0.0.1:58703->127.0.0.1:10001: write: connection refused
3 write udp 127.0.0.1:58703->127.0.0.1:10001: write: connection refused
4 write udp 127.0.0.1:58703->127.0.0.1:10001: write: connection refused
5 write udp 127.0.0.1:58703->127.0.0.1:10001: write: connection refused

tcpdump说:

15:28:46.453313 IP localhost.47993 > localhost.10001: UDP, length 1
15:28:46.453338 IP localhost > localhost: ICMP localhost udp port 10001 unreachable, length 37
15:28:48.453821 IP localhost.47993 > localhost.10001: UDP, length 1
15:28:48.453852 IP localhost > localhost: ICMP localhost udp port 10001 unreachable, length 37
15:28:50.454242 IP localhost.47993 > localhost.10001: UDP, length 1
15:28:50.454271 IP localhost > localhost: ICMP localhost udp port 10001 unreachable, length 37

为什么这种情况每隔一遍就发生一次conn.Write写而不是每次写?我不怪我走,我只是想学习为什么.

Why does this happen every other time conn.Write writes instead of every time? I'm not blaming go, I just want to learn why.

推荐答案

如果您仔细观察数据包捕获,您会发现它 答复每个无法访问ICMP的数据包,并且您只隔着其他包发送.如果检查 Write 的返回值,您还将看到没有数据写入其他所有数据包.

If you look more closely at the packet capture, you'll notice that it is replying to every packet with an ICMP unreachable, and you are only sending every other packet. If you inspect the return value from Write, you'll also see that no data was written on every other packet.

由于UDP没有真正的连接,并且对于任何发送的数据包都没有ACK,因此连接的" UDP套接字模拟发送失败的最佳方法是保存ICMP响应,并在下一次将其作为错误返回.写.

Because UDP has no real connection and there is no ACK for any packets sent, the best a "connected" UDP socket can do to simulate a send failure is to save the ICMP response, and return it as an error on the next write.

因此,发送第一个数据包,接收到ICMP不可达消息,第二个发送操作失败并返回错误,因此没有数据包被发送,并且循环重复.

So the first packet is sent, an ICMP unreachable message is received, the second send operation fails and returns the error, so no packet is sent, and the cycle repeats.

这篇关于golang udp连接每隔写入一次就被拒绝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆