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 !!