Giter Site home page Giter Site logo

awoodbeck / gnp Goto Github PK

View Code? Open in Web Editor NEW
187.0 9.0 55.0 224 KB

The code repository for No Starch Press' Network Programming with Go

Home Page: https://nostarch.com/networkprogrammingwithgo

License: MIT License

Go 99.05% HTML 0.41% CSS 0.34% Dockerfile 0.20%
book learning

gnp's Introduction

Network Programming with Go

Code repository for Network Programming with Go from No Starch Press.

Although this book was targeted for developers familiar with the Go programming language, it's reasonable to assume that you may have picked it up early in your journey of mastering Go. If you aren't comfortable running the tests and examples presented in the book you can either clone this repository and run it on your operating system's command line, or run them in a Docker container.

Running the examples on your command line:

Make sure you have git installed on your command line. If not, these instructions should get you started.

First, clone this repository by clicking on the green Code button near the top of this page and selecting the appropriate command. To clone the repository over HTTPS, run:

git clone https://github.com/awoodbeck/gnp.git

To clone the repository over SSH, run this command:

git clone [email protected]:awoodbeck/gnp.git

Once cloned, you can change into the gnp directory and run all of the tests, like so:

cd gnp
go test -timeout 300s -race -bench=. ./...

Alternatively, run the tests from a single chapter:

go test -v -timeout 300s -race -bench=. ./ch03/dial_fanout_test.go

Run examples in a Docker container:

First, ensure Docker is installed by following instructions for your operating system.

Next, install the latest docker-buildx release for your operating system.

Then, clone this repository and build the gnp docker container by running the following commands in the gnp directory:

git clone [email protected]:awoodbeck/gnp.git
cd gnp
docker-buildx build -t gnp .

Once finished, you should see a gnp image in the output of the docker image ls command, like this:

$ docker image ls                                                                                                                                                                                             ✗ master
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
gnp          latest    ce9980c7834f   8 minutes ago    1.07GB

Finally, you can run the container using the docker run --rm -it gnp bash command. You should find yourself at a bash prompt where you can run the tests by issuing the go test -race ./... command, for example, as seen below:

root@7f00d5d8ad21:/usr/src/gnp# go test -race ./...
?       github.com/awoodbeck/gnp/ch06/sha512-256sum     [no test files]
?       github.com/awoodbeck/gnp/ch06/tftp/tftp [no test files]
?       github.com/awoodbeck/gnp/ch07/creds     [no test files]
?       github.com/awoodbeck/gnp/ch07/creds/auth        [no test files]
ok      github.com/awoodbeck/gnp/ch03   21.764s
ok      github.com/awoodbeck/gnp/ch04   0.067s
ok      github.com/awoodbeck/gnp/ch05/echo      11.039s
ok      github.com/awoodbeck/gnp/ch06/tftp      0.030s
ok      github.com/awoodbeck/gnp/ch07/echo      0.021s
ok      github.com/awoodbeck/gnp/ch08   5.733s
ok      github.com/awoodbeck/gnp/ch09   0.019s
ok      github.com/awoodbeck/gnp/ch09/handlers  0.019s
ok      github.com/awoodbeck/gnp/ch09/middleware        1.038s
?       github.com/awoodbeck/gnp/ch10   [no test files]
?       github.com/awoodbeck/gnp/ch10/backend   [no test files]
?       github.com/awoodbeck/gnp/ch11/cert      [no test files]
?       github.com/awoodbeck/gnp/ch12/client    [no test files]
?       github.com/awoodbeck/gnp/ch12/cmd       [no test files]
?       github.com/awoodbeck/gnp/ch12/gob       [no test files]
?       github.com/awoodbeck/gnp/ch12/housework [no test files]
?       github.com/awoodbeck/gnp/ch12/housework/v1      [no test files]
?       github.com/awoodbeck/gnp/ch12/json      [no test files]
?       github.com/awoodbeck/gnp/ch12/protobuf  [no test files]
?       github.com/awoodbeck/gnp/ch12/server    [no test files]
?       github.com/awoodbeck/gnp/ch13/instrumentation   [no test files]
?       github.com/awoodbeck/gnp/ch13/instrumentation/metrics   [no test files]
?       github.com/awoodbeck/gnp/ch14/aws       [no test files]
?       github.com/awoodbeck/gnp/ch14/azure     [no test files]
?       github.com/awoodbeck/gnp/ch14/gcp       [no test files]
ok      github.com/awoodbeck/gnp/ch11   2.305s
ok      github.com/awoodbeck/gnp/ch13   1.076s

What's gnp in the context of this repository?

gnp was the acronym for the book's working name, "Go Network Programming." The book's name evolved while in development, but the repository did not. Before publishing, my energy was entirely focused on completing the book, and I couldn't justify renaming this repository and correcting all references to it while the book's deadline loomed. Perhaps in the second edition.

gnp's People

Contributors

awoodbeck avatar dependabot[bot] avatar noah-de avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gnp's Issues

Typo on Table 2-1: CIDR?

I've recently started to read GNP and I'm enjoying it. I'm wondering if there is a typo in the table 2-1 about CIDR. Specifically, for the row where CIDR network prefix length is 16. Shouldn't the available networks be 65536 for a 16 bit network mask and not 256? I looked at this row because the example was 192.168.156.97/16.

Thanks in advance for any clarifications.

There is no need to close response http request body from server/client as stated by book

Hi @awoodbeck, thanks for writing this book. I am reading it at the moment and really enjoying it!

I have found, however, some stale advice in the book about recommending the explicit close of http request/response body from http clients/servers via io.Copy(ioutil.Discard, resp.Body). According to this thread, it seems that doing this manually is no longer necessary as the standard library handles it for you if the body is less than 256KB.

I would be grateful if you could double-check this discussion & verify that my understanding is correct for the benefits of me & others reading through the book.

Thanks!

Issue in Chapter12 GRPC example

Hi,

Firstly want to let you know how much I have learned from your book it is great :-)

I ran into an issue on listing 12-21. I found that the protoc compiler was not generating the RobotMaidService from the proto file.

I therefore made the following work-around.

I changed the Rosie struct to embed housework.UnimplementedRobotMaidServer in listing 12-21.

type Rosie struct {
	housework.UnimplementedRobotMaidServer
	mu     sync.Mutex
	chores []*housework.Chore
}

I also removed the Service function from listing 12-21.

Then in listing 12-22 I changed the way that the server was instantiated in the main function.

server := grpc.NewServer()
rosie := new(Rosie)
housework.RegisterRobotMaidServer(server, rosie)

After making these changes the example worked great.

Many thanks

Dan

"Use of closed Network Connection" in TestDial

Hello! Thank you for these exercises!

When running the test suite both from a clone of this repository and on my own, I'm getting the following message from the TestDial suite:

 accept tcp 127.0.0.1:64792: use of closed network connection

This appears to be happening inside of the error checks within the goroutine that is spun off to handle each connection, specifically after attempting to read an established connection into the local buffer. Additionally, the following line never logs anything to standard output:

t.Logf("Received: %q", buf[:n])

Is this the expected behavior of this test, or am I doing something wrong? Thank you, I'm very new to Golang and very much appreciate any guidance.

Guide to compiling the examples?

Greetings,

I just started working through this book, and it looks great. I know that the book assumes a working knowledge of Golang, but it might be helpful to have a page or two (or part of the README.md file) explaining how to build/run the examples.

I ask because I teach a class using Go, and we use the original Go book, which is a pre-module book, and so between that book and this one, there isn't any info on how to run the tests.

Issue with Chapter03 dial_context_test.go

Hi Adam,

Thanks for your efforts and energy on writing this book :)

I am going through the book, having a problem with the test dia_context_test.go:

Code

package main

// A context is an object that you can use to send cancellation signals to your
// asynchronous processes. Also allows to send a cancellation signal after it
// reaches a deadline or after its timer expires.

// Use case: Monitor for specific signals from the operating system, such as the
// one sent to the application when a user presses the CTRL-C key combination,
// to gracefully abort connection attempts and tear down existing connections
// before terminating the application

import (
	"context"
	"net"
	"syscall"
	"testing"
	"time"
)

func TestDialContext(t *testing.T) {
	// create a deadline of five seconds into the future
	dl := time.Now().Add(5 * time.Second)

	// create a context with a 5 seconds deadline into the future
	// and get the cancel function
	ctx, cancel := context.WithDeadline(context.Background(), dl)

	// it's a good practice to defer the cancel function to make sure the
	// context is garbage collected as soon as possible.
	defer cancel()

	var d net.Dialer

	// overrides the Control function of the dialer
	// delays the connection long enough to ensure we exceed the
	// context deadline (5.001s)
	d.Control = func(_, _ string, _ syscall.RawConn) error {
		// sleep long enough to reach the context deadline
		time.Sleep(5*time.Second + time.Millisecond)
		return nil
	}

	// pass the context (ctx) to the DialContext function
	// of the dialer
	conn, err := d.DialContext(ctx, "tcp", "10.0.0.0:80")
	if err != nil {
		if conn != nil {
			conn.Close()
		}
		t.Fatal("connection did not time out")
	}
	nErr, ok := err.(net.Error)
	if !ok {
		t.Error(err)
	} else {
		if !nErr.Timeout() {
			t.Errorf("error is not a timeout: %v", err)
		}
	}

	if ctx.Err() != context.DeadlineExceeded {
		t.Errorf("expected deadline exceeded; actual: %v", ctx.Err())
	}
}

Error

λ walter [workspace/npgo/ch03] → go test -run TestDialContext                                                      
--- FAIL: TestDialContext (5.00s)
    dial_context_test.go:50: connection did not time out
FAIL
exit status 1
FAIL    github.com/walterbio/npgo/ch03  5.004s

The conn reference returned by d.DialContext(ctx, "tcp", "10.0.0.0:80") is nil.

(dlv) l
> github.com/walterbio/npgo/ch03.TestDialContext() ./dial_context_test.go:46 (PC: 0x5998ce)
    41:         }
    42: 
    43:         // pass the context (ctx) to the DialContext function
    44:         // of the dialer
    45:         conn, err := d.DialContext(ctx, "tcp", "10.0.0.0:80")
=>  46:         if err != nil {
    47:                 if conn != nil {
    48:                         conn.Close()
    49:                 }
    50:                 t.Fatal("connection did not time out")
    51:         }
(dlv) p conn
net.Conn nil
(dlv) p err
error(*net.OpError) *{
        Op: "dial",
        Net: "tcp",
        Source: net.Addr nil,
        Addr: net.Addr(*net.TCPAddr) *{
                IP: net.IP len: 16, cap: 16, [0,0,0,0,0,0,0,0,0,0,255,255,10,0,0,0],
                Port: 80,
                Zone: "",},
        Err: error(*net.timeoutError) *{},}
(dlv) 

Thanks for your help or advice here :)

Kind Regards

Why compare the given request Method to http.MethodOptions?

w.Header().Add("Allow", h.allowedMethods())
if r.Method != http.MethodOptions {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}

I thought the purpose of Adding the "Allow" header with acceptable methods was to validate that the given request method matches the acceptable methods for the given endpoint/handlers.

In my case, this will ALWAYS append the error to the response, because my API never takes an "OPTIONS" method.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.