Lecture 09 – Network Programming using Golang
Lecture 09
 Network Programming using Golang
Lecture 09 – Network Programming using Golang
 The net package
 • Package net provides a portable interface for network I/O, including
 TCP/IP, UDP, domain name resolution…
 package main
 import (
 "net“
 //...
 )
Lecture 09 – Network Programming using Golang
 The net package
 • The package provides access to low-level networking primitives but
 most clients would use some basic functions
 • The Dial function connects to a server:
 conn, err := net.Dial("tcp", "google.com:80")
 if err != nil {
 // handle error
 }
 fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
 // ...
Lecture 09 – Network Programming using Golang
 The net package
 • The package provides access to low-level networking primitives but
 most clients would use some basic functions
 • The Listen function creates servers:
 ln, err := net.Listen("tcp", ":8080")
 if err != nil {
 // handle error
 }
 for {
 conn, err := ln.Accept()
 if err != nil {
 // handle error
 }
 go handleConnection(conn)
 }
Lecture 09 – Network Programming using Golang
 What does the following code do?
 package main
 import (
 "log"
 "net"
 )
 func main() {
 ln, err := net.Listen("tcp", ":6000")
 if err != nil {
 log.Fatal(err)
 }
 for {
 conn, err := ln.Accept()
 if err != nil {
 log.Println(err)
 continue
 }
 go handleConnection(conn)
 }
 }
 func handleConnection(c net.Conn) {
 log.Println("A client has connected", c.RemoteAddr())
 c.Write([]byte("Hello world"))
 }
Lecture 09 – Network Programming using Golang
 What does the following code do?
 package main
 import (
 "fmt"
 "net"
 )
 func main() {
 conn, err := net.Dial("tcp", "localhost:6000")
 if err != nil {
 // handle error
 }
 recvdSlice := make([]byte, 11)
 conn.Read(recvdSlice)
 fmt.Println(string(recvdSlice))
 }
Lecture 09 – Network Programming using Golang
 What does the following code do?
 func main() {
 ln, err := net.Listen("tcp", ":6000")
 if err != nil {
 log.Fatal(err)
 }
 for {
 conn, err := ln.Accept()
 if err != nil {
 log.Println(err)
 continue
 }
 go handleConnection(conn)
 }
 }
Lecture 09 – Network Programming using Golang
 What does the following code do?
 func handleConnection(c net.Conn) {
 buf := make([]byte, 4096)
 for {
 n, err := c.Read(buf)
 if err != nil || n == 0 {
 c.Close()
 break
 }
 n, err = c.Write(buf[0:n])
 if err != nil {
 c.Close()
 break
 }
 }
 log.Printf("Connection from %v closed.", c.RemoteAddr())
 }
Lecture 09 – Network Programming using Golang
 Goroutines
 package main
 import (
 "fmt"
 "time"
 )
 func say(s string) {
 for i := 0; i < 5; i++ {
 time.Sleep(100 * time.Millisecond)
 fmt.Println(s)
 }
 }
 func main() {
 go say("world")
 say("hello")
 }
Lecture 09 – Network Programming using Golang
 Channels
 package main
 import "fmt"
 func sendValues(myIntChannel chan int){
 for i:=0; i<5; i++ {
 myIntChannel <- i
 }
 }
 func main() {
 myIntChannel := make(chan int)
 go sendValues(myIntChannel) // function sending value
 for i:=0; i<5; i++ {
 fmt.Println(<-myIntChannel) //receiving value
 }
 }
Lecture 09 – Network Programming using Golang
 Channels
 package main
 import "fmt"
 func sendValues(myIntChannel chan int){
 for i:=0; i<5; i++ {
 myIntChannel <- i //sending value
 }
 }
 func main() {
 myIntChannel := make(chan int)
 go sendValues(myIntChannel)
 for i:=0; i<6; i++ {
 fmt.Println(<-myIntChannel) //receiving value
 }
 }
Lecture 09 – Network Programming using Golang
 Channels
 package main
 import "fmt"
 func sum(s []int, c chan int) {
 sum := 0
 for _, v := range s {
 sum += v
 }
 c <- sum // send sum to c
 }
 func main() {
 s := []int{7, 2, 8, -9, 4, 0}
 c := make(chan int)
 go sum(s[:len(s)/2], c)
 go sum(s[len(s)/2:], c)
 x, y := <-c, <-c // receive from c
 fmt.Println(x, y, x+y)
 }
Lecture 09 – Network Programming using Golang
 Channels Usage
 // Declare a channel
 ch := make(chan int) // working channel
 // or
 var ch chan int // has to be initialized
 // or
 c := make(chan Type, n) // channel with buffer capacity n
 // Add a value to a channel
 ch <- 5 // arrow pointing to channel
 // Retrieve a value from channel
 value := <- ch // arrow pointing away from channel
 // Close a channel
 close(channel)
 // Declare uni directional channels
 r := make(<-chan int) // read only channel
 w := make(chan<- int) // write only channel
Lecture 09 – Network Programming using Golang
 Network Serialization
 • How to send a block over the network to
 other peers.
 • One option, do it all ourselves.
 – Define a protocol, delimiters
 – write/read to/from connections.
 – Fix previousPointers ourselves
Lecture 09 – Network Programming using Golang
 Network Serialization
 • Alternatively, use gob package.
 • Package gob manages streams of gobs -
 binary values exchanged between an
 Encoder (transmitter) and a Decoder
 (receiver).
Lecture 09 – Network Programming using Golang
 An example would help server.go
 import (
 "encoding/gob"
 ...
 )
 type Block struct {
 Transaction string
 PrevPointer *Block
 }
 func main() {
 ln, err := net.Listen("tcp", ":6000")
 if err != nil {
 log.Fatal(err)
 }
 for {
 conn, err := ln.Accept()
 if err != nil {
 log.Println(err)
 continue
 }
 go handleConnection(conn)
 }
 }
Lecture 09 – Network Programming using Golang
 server.go
 func handleConnection(c net.Conn) {
 log.Println("A client has connected", c.RemoteAddr())
 block1 := &Block{"Satoshis100", nil}
 block2 := &Block{"Satoshi50Alice50", block1}
 gobEncoder := gob.NewEncoder(c)
 err := gobEncoder.Encode(block2)
 if err != nil {
 log.Println(err)
 }
 }
Lecture 09 – Network Programming using Golang
 client.go
 type Block struct {
 Transaction string
 PrevPointer *Block
 }
 func main() {
 conn, err := net.Dial("tcp", "localhost:6000")
 if err != nil {
 //handle error
 }
 var recvdBlock Block
 dec := gob.NewDecoder(conn)
 err = dec.Decode(&recvdBlock)
 if err != nil {
 //handle error
 }
 fmt.Println(recvdBlock.Transaction)
 fmt.Println(recvdBlock.PrevPointer.Transaction)
 }
Lecture 09 – Network Programming using Golang
 Putting it all together
 • Send blockChain to other peer once they
 connect !!