2017-10-11 1 views
0

ich dieses UDP-Client-Programm auf Ubuntu Linux lief 16.04:golang udp Verbindung abgelehnt, bei jeder Schreib

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

Es Diese Ausgabe erzeugt:

$ 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 

Aber ich diesen Ausgang erwartet statt:

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

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 

Warum passiert das jedes Mal conn.Write schreibt statt jedes Mal? Ich beschuldige nicht gehen, ich will nur wissen warum.

+0

können Sie teilen, wie Ihr Server Verbindungen behandelt? sieht so aus, als ob es blockiert wird oder so ähnlich –

+0

Sofern Sie keine Anforderung haben, ist es im Allgemeinen ratsam, einen angeschlossenen UDP-Socket zu vermeiden. – JimB

+0

@JimB Was ist dieser "verbundene UDP-Socket" Ich dachte UDP war verbindungslos? Woher raten sie generell, es zu vermeiden? – selden

Antwort

4

Wenn Sie genauer auf die Paketerfassung anschauen, werden Sie feststellen, dass es ist zu jedem Paket mit einem ICMP nicht erreichbar zu antworten, und Sie sind nur jedes andere Paket sendet. Wenn Sie den Rückgabewert von Write untersuchen, sehen Sie auch, dass auf keinem anderen Paket Daten geschrieben wurden.

Da UDP keine echte Verbindung hat und keine ACK für Pakete gesendet wird, ist es am besten, wenn ein "verbundener" UDP-Socket einen Sendefehler simulieren kann, indem er die ICMP-Antwort speichert und als Fehler zurückgibt als nächstes schreiben.

So wird das erste Paket gesendet, eine ICMP-unerreichbare Nachricht wird empfangen, der zweite Sendevorgang schlägt fehl und der Fehler wird zurückgegeben, sodass kein Paket gesendet wird und der Zyklus wiederholt wird.

Verwandte Themen