duan117890 2017-10-11 21:24
浏览 260
已采纳

golang 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)
    }
}

It produces this output:

$ 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

But I expected this output instead:

$ 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 says:

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

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.

  • 写回答

2条回答

  • douhui1630 2017-10-11 21:37
    关注

    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.

    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.

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换