-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathnet.slide
543 lines (369 loc) · 16.7 KB
/
net.slide
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
Network, Net package
16 May 2017
Ivan Kutuzov
https://discuss.7insyde.com
https://golang.org.ua
@arbrix
* License and Materials
This presentation is licensed under the [[https://creativecommons.org/licenses/by-sa/4.0/][Creative Commons Attribution-ShareAlike 4.0 International]] license.
You are encouraged to remix, transform, or build upon the material, providing you give appropriate credit and distribute your contributions under the same license.
If you have suggestions or corrections to this presentation, please raise [[https://github.com/GolangUA/go-training/issues][an issue on the GitHub project]].
* Agenda
- Recap
- Networking tasks
- Net package
- Net/http package
- Other net/... packages
- Testing Network
* Recap
- Goals of programming
* Recap
- Goals of programming
- Reduce costs
- Increase revenue
* Recap
- Goals of programming
- Reduce costs
- Increase revenue
How to achieve this goals?
* How to achieve programming goals
- Understanding the problem (problem defenition)
* How to achieve programming goals
- Understanding the problem (problem defenition)
- Understanding the domain (all related technologies and existing solutions)
* How to achieve programming goals
- Understanding the problem (problem defenition)
- Understanding the domain (all related technologies and existing solutions)
- Understanding general theory (data structures and algorithms / patterns)
* How to achieve programming goals
- Understanding the problem (problem defenition)
- Understanding the domain (all related technologies and existing solutions)
- Understanding general theory (data structures and algorithms / patterns)
- Understanding toolset (programmin language)
* Network
* Concepts in web principles
- Request: request data from users, including POST, GET, Cookie and URL.+
- Response: response data from server to clients.
- Conn: connections between clients and servers.
- Handler: Request handling logic and response generation.
* Standard http workflow
.image ./img/how-web-works.png _ 800
* Two general tasks
- Client
resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
url.Values{"key": {"Value"}, "id": {"123"}})
- Server
http.Handle("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))
* Net package
Package net provides a portable interface for network I/O, including TCP/IP, UDP, domain name resolution, and Unix domain sockets.
Let's go deeply.
* Net general
Although the package provides access to low-level networking primitives, most clients will need only the basic interface provided by the Dial, Listen, and Accept functions and the associated Conn and Listener interfaces. The crypto/tls package uses the same interfaces and similar Dial and Listen functions.
* Net Dial
The Dial function connects to a server:
conn, err := net.Dial("tcp", "golang.org:80")
if err != nil {
// handle error
}
fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
status, err := bufio.NewReader(conn).ReadString('\n')
// ...
* Net Listen
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)
}
* Net IP
An IP is a single IP address, a slice of bytes. Functions in this package accept either 4-byte (IPv4) or 16-byte (IPv6) slices as input.
type IP []byte
func IPv4(a, b, c, d byte) IP
* net/url
Package url parses URLs and implements query escaping. [[https://golang.org/pkg/net/url/][link]]
u, err := url.Parse("http://bing.com/search?q=dotnet")
if err != nil {
log.Fatal(err)
}
u.Scheme = "https"
u.Host = "google.com"
q := u.Query()
q.Set("q", "golang")
u.RawQuery = q.Encode()
fmt.Println(u)
* net/http
Package http provides HTTP client and server implementations. [[https://golang.org/pkg/net/http/][link]]
Get, Head, Post, and PostForm make HTTP (or HTTPS) requests:
resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
url.Values{"key": {"Value"}, "id": {"123"}})
The client must close the response body when finished with it:
resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...
* net/http (continue)
For control over HTTP client headers, redirect policy, and other settings, create a Client:
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
resp, err := client.Get("http://example.com")
// ...
req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...
* net/http (continue 2)
For control over proxies, TLS configuration, keep-alives, compression, and other settings, create a Transport:
tr := &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: pool},
DisableCompression: true,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")
// ...
*Important* Clients and Transports are safe for concurrent use by multiple goroutines and for efficiency should only be created once and re-used.
* net/http (continue 3)
ListenAndServe starts an HTTP server with a given address and handler. The handler is usually nil, which means to use DefaultServeMux. Handle and HandleFunc add handlers to DefaultServeMux:
http.Handle("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))
More control over the server's behavior is available by creating a custom Server:
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())
* net/http (handler)
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
A Handler responds to an HTTP request.
ServeHTTP should write reply headers and data to the ResponseWriter and then return. Returning signals that the request is finished; it is not valid to use the ResponseWriter or read from the Request.Body after or concurrently with the completion of the ServeHTTP call.
* net/http (handler continue)
func FileServer(root FileSystem) Handler
FileServer returns a handler that serves HTTP requests with the contents of the file system rooted at root.
To use the operating system's file system implementation, use http.Dir
func NotFoundHandler() Handler
NotFoundHandler returns a simple request handler that replies to each request with a “404 page not found” reply.
func RedirectHandler(url string, code int) Handler
RedirectHandler returns a request handler that redirects each request it receives to the given url using the given status code.
* net/http (handler continue2)
func StripPrefix(prefix string, h Handler) Handler
StripPrefix returns a handler that serves HTTP requests by removing the given prefix from the request URL's Path and invoking the handler h.
func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler
TimeoutHandler returns a Handler that runs h with the given time limit.
* net/http type ServeMux
ServeMux is an HTTP request multiplexer. It matches the URL of each incoming request against a list of registered patterns and calls the handler for the pattern that most closely matches the URL.
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.
Note that since a pattern ending in a slash names a rooted subtree, the pattern "/" matches all paths not matched by other registered patterns, not just the URL with Path == "/".
Third party packages
- [[http://github.com/gorill/mux][gorilla mux]]
- [[https://github.com/julienschmidt/httprouter][HttpRouter]]
* A web server
[[https://golang.org/doc/effective_go.html#web_server][Effective Go]]
var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
var templ = template.Must(template.New("qr").Parse(templateStr))
func main() {
flag.Parse()
http.Handle("/", http.HandlerFunc(QR))
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}
func QR(w http.ResponseWriter, req *http.Request) {
templ.Execute(w, req.FormValue("s"))
}
const templateStr = `...
* Variety of techniques
- TCP / UDP
- HTTP / HTTP/2
- Socket
- RPC
- REST
* WebSockets
- Only one TCP connection for a single web client.
- WebSocket servers can push data to web clients.
- Lightweight header to reduce data transmission overhead.
.link https://astaxie.gitbooks.io/build-web-application-with-golang/en/08.2.html Build web application with Golang
* REST
REpresentational State Transfer
- Every URI represents a resource.
- There is a representation layer for transferring resources between clients and servers.
- Clients use four HTTP methods to implement "Presentation Layer State Transfer", allowing them to operate on remote resources.
* RPC
RPC is based around the idea of defining a service, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a RPC server to handle client calls. On the client side, the client has a stub (referred to as just a client in some languages) that provides the same methods as the server.
- Functions are exported (capitalized).
- Functions must have two arguments with exported types.
- The first argument is for receiving from the client, and the second one has to be a pointer and is for replying to the client.
- Functions must have a return value of error type.
func (t *T) MethodName(argType T1, replyType *T2) error
* Not only existing protocol
We are able to create a new ones.
* net/textproto
Package textproto implements generic support for text-based request/response protocols in the style of HTTP, NNTP, and SMTP.
The package provides:
- Error, which represents a numeric error response from a server.
- Pipeline, to manage pipelined requests and responses in a client.
- Reader, to read numeric response code lines, key: value headers, lines wrapped with leading spaces on continuation lines, and whole text blocks ending with a dot on a line by itself.
- Writer, to write dot-encoded text blocks.
- Conn, a convenient packaging of Reader, Writer, and Pipeline for use with a single network connection.
* net/textproto Conn
A Conn represents a textual network protocol connection. It consists of a Reader and Writer to manage I/O and a Pipeline to sequence concurrent requests on the connection. These embedded types carry methods with them; see the documentation of those types for details.
type Conn struct {
Reader
Writer
Pipeline
// contains filtered or unexported fields
}
* net/textproto Cmd
Cmd is a convenience method that sends a command after waiting its turn in the pipeline. The command text is the result of formatting format with args and appending \r\n. Cmd returns the id of the command, for use with StartResponse and EndResponse.
For example, a client might run a HELP command that returns a dot-body by using:
id, err := c.Cmd("HELP")
if err != nil {
return nil, err
}
c.StartResponse(id)
defer c.EndResponse(id)
if _, _, err = c.ReadCodeLine(110); err != nil {
return nil, err
}
text, err := c.ReadDotBytes()
if err != nil {
return nil, err
}
return c.ReadCodeLine(250)
* net/textproto Pipeline
A Pipeline manages a pipelined in-order request/response sequence.
To use a Pipeline p to manage multiple clients on a connection, each client should run:
id := p.Next() // take a number
p.StartRequest(id) // wait for turn to send request
«send request»
p.EndRequest(id) // notify Pipeline that request is sent
p.StartResponse(id) // wait for turn to read response
«read response»
p.EndResponse(id) // notify Pipeline that response is read
A pipelined server can use the same calls to ensure that responses computed in parallel are written in the correct order.
* Network Summary
- Standard packages in Go provide all necessaries for working with network
- as client
- as server
- using TCP or UDP
- using WebSockets
- using REST
- using RPC
- using HTTP or HTTP/2
- possability of control on each level
- transport
- client
- listener
- connection
- server
* Testing & Profiling
* net/http/httptest
Package httptest provides utilities for HTTP testing. [[https://golang.org/pkg/net/http/httptest][link]]
Constants
func NewRequest(method, target string, body io.Reader) *http.Request
type ResponseRecorder
func NewRecorder() *ResponseRecorder
func (rw *ResponseRecorder) Flush()
func (rw *ResponseRecorder) Header() http.Header
func (rw *ResponseRecorder) Result() *http.Response
func (rw *ResponseRecorder) Write(buf []byte) (int, error)
func (rw *ResponseRecorder) WriteHeader(code int)
func (rw *ResponseRecorder) WriteString(str string) (int, error)
type Server
func NewServer(handler http.Handler) *Server
func NewTLSServer(handler http.Handler) *Server
func NewUnstartedServer(handler http.Handler) *Server
func (s *Server) Close()
func (s *Server) CloseClientConnections()
func (s *Server) Start()
func (s *Server) StartTLS()
* net/http/httptest ResponseRecorder
handler := func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "something failed", http.StatusInternalServerError)
}
req := httptest.NewRequest("GET", "http://example.com/foo", nil)
w := httptest.NewRecorder()
handler(w, req)
fmt.Printf("%d - %s", w.Code, w.Body.String())
* net/http/httptest Server
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, client")
}))
defer ts.Close()
res, err := http.Get(ts.URL)
if err != nil {
log.Fatal(err)
}
greeting, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", greeting
* net/http/pprof
Package pprof serves via its HTTP server runtime profiling data in the format expected by the pprof visualization tool.
The package is typically only imported for the side effect of registering its HTTP handlers. The handled paths all begin with /debug/pprof/.
To use pprof, link this package into your program:
import _ "net/http/pprof"
If your application is not already running an http server, you need to start one. Add "net/http" and "log" to your imports and the following code to your main function:
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
* net/http/pprof how to use
Then use the pprof tool to look at the heap profile:
go tool pprof http://localhost:6060/debug/pprof/heap
Or to look at a 30-second CPU profile:
go tool pprof http://localhost:6060/debug/pprof/profile
Or to look at the goroutine blocking profile, after calling runtime.SetBlockProfileRate in your program:
go tool pprof http://localhost:6060/debug/pprof/block
Or to collect a 5-second execution trace:
wget http://localhost:6060/debug/pprof/trace?seconds=5
To view all available profiles, open http://localhost:6060/debug/pprof/ in your browser.
* Tasks
1. Create TCP Proxy server
2. Create HTTP Proxy server
3. Create simple CRUD server (with saving data in DB (PostgreSQL, MySQL, MongoDB))
4. Create simple chat server on TCP base
* Resources
- [[http://thenewstack.io/understanding-golang-packages/][Understanding Golang Packages]]
- [[https://golang.org/pkg/][Golang std pkg]]
- [[https://golang.org/src][Golang std src]]
- Alan A. A. Donovan and Brian W. Kernighan 'The Go Programming Language'
- [[http://networkstatic.net/golang-network-ops/][Golang for Network Ops]]
- [[http://www.golang-book.com/books/intro][An Introduction to Programming in Go]]
- [[http://blog.scottlowe.org/2015/01/26/using-git-with-github/][Using Git with Github]]
- [[http://www.minaandrawos.com/2016/05/14/udp-vs-tcp-in-golang/][UDP vs TCP in Go]]
- [[https://astaxie.gitbooks.io/build-web-application-with-golang/en/03.1.html][Web App with Golang]]
- [[http://soryy.com/blog/2014/not-another-go-net-http-tutorial/][Not Another Go/Golang net/http Tutorial]]
* Questions?