Toy UDP-Server und -Client in Go. Ich habe dies getan, um mich mit dem Standardpaket net
von Go vertraut zu machen, insbesondere mit den UDP-bezogenen Funktionen.
Weil ich beim Schreiben gelernt habe, dass hier eine seltsame stilistische Diskrepanz zwischen der Art und Weise besteht, wie server.go UDP-Sockets ausführt, und wie client.go eine „allgemeine“ Socket-Sache macht. Um diese Diskrepanz auszugleichen, habe ich client2.go nur mit UDP-Funktionen erstellt, die mit server.go übereinstimmen.
Ich habe auch einen Python 3-Client hinzugefügt, da ich keinen anderen Ort habe, an dem ich ihn unterbringen kann.
Der Server lauscht auf einer bestimmten Portnummer auf UDP-Pakete. Es blockiert den Aufruf net.ReadFromUDP()
-Methode.
Sollte der Server jemals Bytes empfangen, druckt er aus, wie viele Bytes er von wo empfangen hat, und schreibt dann die gleiche Anzahl an Bytes dorthin zurück, wo er sie empfangen hat.
Der Client erstellt basierend auf Befehlszeileninformationen eine UDP-Verbindung zu einer IP-Adresse (v4 oder v6) oder einem Hostnamen und einer Portnummer. Dann schreibt es Bytes eines Strings, ebenfalls von der Kommandozeile aus, auf die UDP-Verbindung. Es wartet, bis einige Bytes zurückkommen oder ein Fehler auftritt. Dann existiert es.
Einfach und doch voller Probleme. Keine Zeitüberschreitungen, keine festgelegte Anzahl von Bytes. Client oder Server könnten ewig hängen bleiben und auf ein Paket warten, das nie ankommt.
$ go build server.go
$ go build client.go
$ go build client2.go
Der Python-3-Client wird interpretiert und muss nicht „erstellt“ werden.
In Fenster 1:
$ ./server :: 7890
Accepting a new packet
In Fenster 2:
$ ./client udp localhost 7890 'some string'
Oder:
$ ./client2 fe80::a11:96ff:fe7f:6d74 7890 'some string' [eth0]
Oder:
$ ./client1.py localhost 7890 'some string'
Das letzte Argument von ./client2
ist optional. Dies ist der Name der Netzwerkschnittstelle, über die die Pakete weitergeleitet werden. Beachten Sie den Inhalt von net.UDPAddr
:
type UDPAddr struct {
IP IP
Port int
Zone string // IPv6 scoped addressing zone
}
Das Zonenelement wird zum Routing von Link-Local-Adressen verwendet (fe80: Präfix). Der Schnittstellenname fungiert als Zone. client2
wird mit einem vierten Argument aufgerufen und verwendet dieses Argument als „Zone“.