{"id":19489076,"url":"https://github.com/vladimirvivien/go-networking","last_synced_at":"2025-04-13T08:41:20.765Z","repository":{"id":57531814,"uuid":"95210649","full_name":"vladimirvivien/go-networking","owner":"vladimirvivien","description":"Code sample for Learning Network Programming with Go","archived":false,"fork":false,"pushed_at":"2020-06-04T18:01:41.000Z","size":1072,"stargazers_count":255,"open_issues_count":0,"forks_count":50,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-07T09:08:20.958Z","etag":null,"topics":["go","golang","network-programming"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vladimirvivien.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-23T10:33:14.000Z","updated_at":"2025-04-04T17:49:22.000Z","dependencies_parsed_at":"2022-09-06T16:30:34.477Z","dependency_job_id":null,"html_url":"https://github.com/vladimirvivien/go-networking","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladimirvivien%2Fgo-networking","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladimirvivien%2Fgo-networking/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladimirvivien%2Fgo-networking/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladimirvivien%2Fgo-networking/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vladimirvivien","download_url":"https://codeload.github.com/vladimirvivien/go-networking/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248686591,"owners_count":21145524,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","network-programming"],"created_at":"2024-11-10T21:07:15.681Z","updated_at":"2025-04-13T08:41:20.742Z","avatar_url":"https://github.com/vladimirvivien.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go Network Programming\nThis repository contains notes and samples source code for the video series, of the same name, published by Packt Publishing. \n\n## A quick network review\nBefore we jump headfirst into writing networked programs in Go, let us do a quick review of the concepts we will cover in this video series.  To be clear, when we say *network*, in the context of this discussion, we are referring to connected computers on a network communicating using protocols such UDP or TCP over IP.  Given the scope of this session, we are not going to have deep discussion about these protocols as it is assume that you have some familiarity with them.  However, it is worth reviewing the three main protocols that will impact our discussions for the remainder of this session.\n\n * *IP* - the ability of computers to communicate with other computers on the same network is specified by the Internet Protocol (or IP).  This connectionless protocol specifies concepts such as Addressing and Routing to enable it to send data packets (datagrams) from one host to another host connected on the same network or across network boundaries.  In the video session, we will explore the Go types and functions available in the net package to support IP.\n \n * *UDP* - The User Datagram Protocol (UDP) is a core tenant of the Internet protocols.  It is, what is known as, a connectionless transmission protocol designed to reduce latency of delivery.  To do this, UDP sends data packets (or datagrams) to hosts, on an IP network, with minimum reliability and delivery guarantee.  In this session, we will explore how to use the constructs provided by the Go API to work with UDP.\n \n * *TCP* - When the transmission of data, between hosts on a network, requires a more robust guarantees of delivery than, say UDP, the Transmission Control Protocol (or TCP) is used over an IP network.  The protocol uses a session between communicating parties which starts with a handshake to establish a durable connection between hosts that can handle transmission error, out-of-order packets, and delivery guarantee.  In this session we will explore how Go supports TCP and the types available in the API to work with the protocol.\n\n\n## The net Package\nAs mentioned in the opening, when writing programs that communicate over a network in Go, you will likely start with the *net* package (https://golang.org/pkg/net).  This package, and its sub-packages, provide a rich API that exposes low-level networking primitives as well as application-level protocols such as HTTP.  For this discussion, we will focus on protocols such IP, UDP, and TCP.\n\nBefore we dive head-first into our discussion, it is worth taking a high-level look at the `net` package.  There are some critical themes represented in the package that should be discussed before we dive into the details.  For instance, all logical components that makes up network communications are abstracted as types and supporting functions.  Let us take a look at some of these.\n\n### Addressing\nOne of the most basic primitives, when doing IP-based network programming, is the address.  Addresses are used to identify networks and network nodes interconnected together.  In the `net` package `IP` addresses can be represented using string literals with the dot notation for IPv4 and colon-delimited for IPv6 addresses as shown below:\n```go\nvar localIP = \"127.0.0.1\"\nvar remIP = \"2607:f8b0:4002:c06::65\"\n```\nWhen dealing with an UDP or TCP, the address can also include a port number separated by a colon.  For IPv6 addresses, the IP address is enclosed within a bracket then followed by the port.\n```go\nvar webAddr = \"127.0.0.1:8080\"\nvar sshAddr = \"[2607:f8b0:4002:c06::65]:22\"\n```\nAs we explore the protocols in detail, we will see how each have their own typed representation of addresses such as `net.IPAddr`, `net.UDPAddr`, and `net.TCPAddr`.\n\n### Name and service resolution\nOne crucial function of a network API is the ability to resolve services, addresses, and names from a given network.  The net package provides several functions to query naming and service information such as host names, IP, reverse lookup, NS, MX, and CNAME records.\n\nFor instance the following program looks up the IP address for the given host. It uses\nfunction `net.LookupHost()` which returns a slice of string IP addresses.  \n\n```go\nfunc main() {\n\tflag.StringVar(\u0026host, \"host\", \"localhost\", \"host name to resolve\")\n\tflag.Parse()\n\n\taddrs, err := net.LookupHost(host)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\n\tfmt.Println(addrs)\n}\n```\nThe net package uses `resolver strategy` to determined how resolve network names \ndepending on the operatng system. By default, the resolver will attempt to use a pure Go \nmechanism that queries DNS directly to avoid OS-related thread penalties.  Given certain\nconditions and combinations, the resolver may fallback to using a C-implemented resolver\nto relies on OS system calls.\n\nThis behavior can be overridden using the `GODEBUG` environment variale as shown.\n\n```sh\nexport GODEBUG=netdns=go    # use Go resolver\nexport GODEBUG=netdns=cgo   # use C resolver\n```\n\n\n\n### Protocols\nAnother prominent theme in the net package is `protocol` representation.  Many functions and types, in the `net` package, use string literals to identify the protocol that is being used when communicating across the network.  The following lists the string identifier for the protocols that we will cover:\n```sh\n\"ip\",  \"ip4\",  \"ip6\"\n\"tcp\", \"tcp4\", \"tcp6\" \n\"udp\", \"udp4\", \"udp6\"                        \n```\nThe suffix `4` indicates a protocol for IPv4 only and the suffix `6` indicates a protocol using IPv6 only.  When the string literal omits the version, it targets IPv4 by default.  We see this used many times during the video series when invoking functions and methods.\n\n### Network communication\nWhen building networked programs, you will certainly need a way to connect nodes together so they can communicate to exchange data. Depending on the nature of the network protocol you may also need: \n\n- the ability to announce the service on an available port\n- the ability to listen, accept, and handle incoming client connections\n\nLet us look at how the `net` package provides support for creating programs that can communicate on the network:\n\n* *net.Conn* - this interface represents communication between two nodes on a network.  When writing networked application, eventually you will use an implementation of that interface to exchange data.  The net package comes with several implementations including `net.IPConn`, `net.UDPConn`, and `net.TCPConn` for low-level and protocol-specific functionalities.  For instance, streaming protocols such as TCP, exposes streaming IO semantics from `io.Reader` and `io.Writer` interfaces.  We will see how this is done as we get deeper into our sessions.\n\n* *Listening for connections* - the `net` package provides several functions that can be used to listen for incoming connections depending on the protocol that you want to use.  These functions include `net.ListenIP()` and `net.ListenUDP()` which return a `net.IPConn` and `net.UDPConn` respectively.  To listen for TCP connections, we use `net.ListenTCP()` which returns `net.Listener` implementation.  \n\n* *Dialing a connection* - to establish a connection from one network node to another, the `net` package uses the notion of dialing a connection provided by functions `net.IPDial()`, `net.UDPDial()`, and `net.TCPDial()` which return their respective connection implementations of `net.IPConn`, `net.UDPConn`, and `net.TCPConn`.  The wrapper function:\n```go\nfunc Dial(network, address string) (Conn, error)\n```\nis often used to create a connection.  It automatically returns the proper `net.Conn` implementation based on the network protocol specified in parameter `network`.  For instance, the following will open a TCP connection to the indicated address and port:\n```go\nnet.Dial(\"tcp\", \"64.233.177.102\")\n```\nWe will see more examples of the Dial functions as we continue the video series.\n\n* *Unix socket* - Lastly for completeness, it is worth mentioning that the `net` package also supports *Unix domain socket* protocol for doing both streaming and packet based inter-process communications.  The protocols are identified as \"unix\", \"unixgram\", and \"unixpacket\" and uses type `net.UnixConn` to represent a connection.  This video series does not discuss detail about these protocols.  However, they use similar interfaces and follow the same idioms as the TCP and UDP protocol implementations.  This should make them fairly easy to learn and use. \n\n## IP\nHere is a n example of how IP addresses can be represented as string literals.  In the string literal value, the IPv4 uses dot notation to separate address bytes while IPv6 uses colon separator.  In both call to `net.ParseIP()`, the function parses the address and return a typed representation of the address or `nil` if the address is invalid.\n\n```go\nfunc main() {\n\tlocalIP := net.ParseIP(\"127.0.0.1\")\n\tremoteIP := net.ParseIP(\"2607:f8b0:4002:c06::65\")\n\n\tfmt.Println(\"local IP: \", localIP)\n\tfmt.Println(\"remote IP: \", remoteIP)\n}\n```\nWhen the addresses is for a service associated with TCP or UDP (which will be covered in later sessions), the string literal can also include a service port.  For IPv4 addresses, the port is separated by colon and IPv6 addresses are placed within brackets followed by a colon and the port.  For instance, the following string literal represents a host address along with a HTTP service accessible on port 80.  Also when the address is assumed to be the local host, the IP address can be omitted, leaving only the colon followed by the port.  All three representations are valid versions of string representations of IP addresses in Go.\n\n```go\nfunc main() {\n\taddr0 := \"74.125.21.113:80\"\n\tif ip, port, err := net.SplitHostPort(addr0); err == nil {\n\t\tfmt.Printf(\"ip=%s port=%s\\n\", ip, port)\n\t} else {\n\t\tfmt.Println(err)\n\t}\n\n\taddr1 := \"[2607:f8b0:4002:c06::65]:80\"\n\tif ip, port, err := net.SplitHostPort(addr1); err == nil {\n\t\tfmt.Printf(\"ip=%s port=%s\\n\", ip, port)\n\t} else {\n\t\tfmt.Println(err)\n\t}\n\t\n\tlocal := \":8080\"\n\tif ip, port, err := net.SplitHostPort(local); err == nil {\n\t\tfmt.Printf(\"ip=%s port=%s\\n\", ip, port)\n\t} else {\n\t\tfmt.Println(err)\n\t}\t\n}\n```\nFormally, the `net` package uses type `net.IP` to represent an IP address as a slice of bytes capable of storing both IPv4 and IPv6 addresses.  \n\n```go\ntype IP []byte\n```\nThe IP type exposes several methods that makes it easy to work and manipulate IP addresses. To illustrate this, the following code is a utility that validates then converts a given address to both IPv4 and IPv6 values.\n\n```go\n\u003csample code\u003e\n```\nThe working with the IP protocol directly, the net package in Go uses type `IPAddr` to provide a richer representation of an IP address which is used in several functions and methods.\n\n```go\ntype IPAddr struct {\n        IP   IP\n        Zone string \n}\n```\n\n\n# Topics \n\n- *Network interface information* [accessing hardware interface info]\n- Address Resolution [lookup and resolving addresses]\n- IP Communication\n- UDP Communication\n- TCP Communication\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladimirvivien%2Fgo-networking","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvladimirvivien%2Fgo-networking","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladimirvivien%2Fgo-networking/lists"}