Go networking

  • View
    61

  • Download
    0

Embed Size (px)

DESCRIPTION

Go networking. Peter Borovansk , KAI, I-18, borovan (a)ii.fmph.uniba.sk. Prejdeme si v Go tri rovne tzv. TCP Stacku, a naprogramujeme klient/server aplikciu cez sockety, prklad chat sntp udp klient (time server klient) f tp server & ftp klient w ebcrawler - PowerPoint PPT Presentation

Transcript

  • Klobky ako predjedlo(o to m s programovanm pochopte dnes)3 biele a 2 ierneA, B, C si navzjom vidia farby klobkovnesm komunikova, ale (aj tak) s inteligentn vyhrvaj, ak vetci uhdnu farbu svojho klobkaresp. ak sa jeden pomli, prehrali vetci.

    Hint: A,B,C s spoluhri, preto predpokladaj, e s chytr a mysli aj za nich

    Hint: loha nie je o ast=hdan sprvneho rieenia

  • Do 10 sekndak vidm dva ierne, urite mm biely, a preto sa hne ozvem, e "mm biely".ak sa niekto do 10s ozval, e m biely, mus vidie dva ierne, preto ja mm ierny, tak hne krim "mm ierny". inak akm 10s, nikto neozval, e mm biely", preto urite nie s v hre 2 ierne, ale najviac jeden ierny !!!

  • 10 a 20 sekndak teda vidm ierny, ja musm ma biely, tak sa ozvem hne, e mm "mm biely".

    inak, ak sa ozv dvaja (do 10 s), e biely, ja mm ierny, tak krim "mm ierny". inak, nevidm ierny a nikto sa neozval, akm alch 10s,v hre je najviac jeden ierny

  • po 20 sekundchkee sa nikto neozval, tak nie je iaden ierny, tak krim "mm biely" a ostatn tiev hre nie je iaden ierny

  • Cel algoritmus(bez vysvetlenia, u pre cvien opicu)ak vidm dva ierne, hne ozvem, e "mm biely".ak sa niekto do 10 s ozval, tak krim "mm ierny". inak akm 10s.ak vidm ierny, tak hne krim "mm biely".inak, ak sa ozv dvaja do 10 s, tak krim "mm ierny". Po 10 sek:inak akm alch 10s,krim "mm bielyPo 20 sek:Hne:

  • Na zamyslenieje podstatn, i krim mm biely/mm ierny, nesta len u viem ?!

    Dalo by sa to pre 3 biele, 3 ierne, 3 udia ?

    Dalo by sa to pre 2 biele, 1 ierne, 2 udia ?

    Dalo by sa to pre N biele, (N-1) ierne, N udia ? (napr.6,5,6)

    Dalo by sa to pre >N biele, (N-1) ierne, N udia ? (napr. 8,5,6)

    Dalo by sa to pre N biele,

  • Komunikciakad s kadm

  • Sprva, kanly, agentitype Message struct { who int // od koho, odosielate what int } // o, obsah sprvyfunc makeChannels(n int) []chan Message { chArray := make([]chan Message, n)for i:= 0; i < n; i++ {// kanl,na ktorom pova i-ty agentchArray[i] = make(chan Message) } return chArray } func main() { chArray := makeChannels(numb) for a:= 0; a
  • Agenti napriamofunc runAgent(agent int, channels []chan Message) { go func() { // ID agenta, kanaly na vsetkych agentov i := 1 // inicilny stav agenta for { // loop forevertimeout := time.After(...) select { case msg :=
  • Agenti napriamofunc runAgent(agent int, channels []chan Message) { go func() { // ID agenta, kanaly na vsetkych agentov i := 1 // inicilny stav agenta for { // loop forevertimeout := time.After(...) select { case msg :=
  • Prklad komunikcie 3 agentov1: povedal 1agentovi 2: prisla sprava:"1: povedal 1"agentovi 0: prisla sprava:"1: povedal 1"0: povedal 1agentovi 2: prisla sprava:"0: povedal 1"agentovi 1: prisla sprava:"0: povedal 1"1: povedal 2agentovi 2: prisla sprava:"1: povedal 2"0: povedal 21: povedal 3agentovi 0: prisla sprava:"1: povedal 2"agentovi 0: prisla sprava:"1: povedal 3"agentovi 1: prisla sprava:"0: povedal 2"agentovi 2: prisla sprava:"0: povedal 2"agentovi 2: prisla sprava:"1: povedal 3

  • Aplikcia na klobky(domca loha)[0s] A: vidim 1 biele a 1 cierne[0s] A: cakam 10 sek[0s] C: vidim 1 biele a 1 cierne[0s] C: cakam 10 sek[0s] B: vidim 2 biele a 0 cierne[0s] B: cakam 10 sek

    [10s] B: cakam dalsich 10 sek[11s] A: mam biely !!! true[11s] C: mam biely !!! true[11s] B:: prisla sprava, ze [11s] A: mam biely !!! true[12s] B: mam cierny !!! truefinitofunc vidim(name String) (int, int) {

  • Komunikcia s dispeerom

  • Dispatcher o poujte to prepolefunc runDispatcher(channels []chan Message) chan Message { dispch := make(chan Message)// kanl na komunikciu s dispatcherom go func() { for { msg :=
  • Agenti cez dispeerafunc runAgentCommunicatingWithDispatcher(agent int, dispch chan Message, input chan Message) { go func() { i := 0// stav agenta for { timeout := time.After(...) // nhodny delay select { case msg :=
  • Agenti cez dispeerafunc runAgentCommunicatingWithDispatcher(agent int, dispch chan Message, input chan Message) { go func() { i := 0// stav agenta for { timeout := time.After(...) // nhodny delay select { case msg :=
  • Prklad komunikcie 3 agentov1: povedal 0dispecer sa dozvedel: 1: povedal 0agentovi 2: prisla sprava:"1: povedal 0"agentovi 0: prisla sprava:"1: povedal 0"agentovi 1: prisla sprava:"1: povedal 0"0: povedal 0dispecer sa dozvedel: 0: povedal 0agentovi 2: prisla sprava:"0: povedal 0"agentovi 0: prisla sprava:"0: povedal 0"agentovi 1: prisla sprava:"0: povedal 0"0: povedal 1dispecer sa dozvedel: 0: povedal 1agentovi 2: prisla sprava:"0: povedal 1"agentovi 0: prisla sprava:"0: povedal 1"agentovi 1: prisla sprava:"0: povedal 1

  • Aplikcia na klobky(domca loha)[0s] A: vidim 1 biele a 1 cierne[0s] A: cakam 10 sek[0s] B: vidim 2 biele a 0 cierne[0s] B: cakam 10 sek[0s] C: vidim 1 biele a 1 cierne[0s] C: cakam 10 sek[10s] B: cakam dalsich 10 sek[11s] A: mam biely !!! trueod A prisla sprava, ze [11s] A: mam biely !!! true[11s] C: mam biely !!! true[11s] B:: prisla sprava, ze [11s] A: mam biely !!! Trueod C prisla sprava, ze [11s] A: mam biely !!! trueod B prisla sprava, ze [11s] A: mam biely !!! trueod B prisla sprava, ze [11s] C: mam biely !!! true[12s] B: mam cierny !!! Truefinitofunc vidim(name String) (int, int) {

  • Go networkingPeter Borovansk, KAI, I-18, borovan(a)ii.fmph.uniba.skPrejdeme si v Go tri rovne tzv. TCP Stacku, a naprogramujemeklient/server aplikciu cez sockety, prklad chatsntp udp klient (time server klient)Webcrawler

    Zdroje:http://golang.org/doc/articles/wiki/http://jan.newmarch.name/go

  • Client socketimport ( "bufio" "fmt" "io" "net" ) func main() { // vytvorenie spojenia socket-socket conn, err := net.Dial("tcp", "google.com:80") if err != nil { fmt.Println("connection error: " + err.Error()) } else { // psanie do conn : net.Connfmt.Fprintf(conn, "HEAD/ HTTP/1.0\r\n\r\n") r := bufio.NewReader(conn) // bufio wrapperfor { line, _, err := r.ReadLine() // tanie z connif err == io.EOF { break } fmt.Printf("%s\n", line) } } } net1/netclient1.go

  • Pomocou putty

  • Sntp klient conn, err := net.Dial("udp","0.sk.pool.ntp.org:123") if err != nil { return } r := bufio.NewReader(conn) w := bufio.NewWriter(conn) data := make([]byte, 48) data[0] = 3
  • Jednovlknov serverimport ( "bufio" "fmt" "io" "net" )

    func main() { // porty

  • HandleConnectionfunc handleConnection(conn net.Conn) { fmt.Println("handleConnection") r := bufio.NewReader(conn)// wrapper na conn read streamfor { line, _, err := r.ReadLine() // taj a do koncaif err == io.EOF { break } // a p na konzolufmt.Printf("%s\n", line) } }net2/netserver.go

  • Viacvlknov serverfunc main() { ln, err := net.Listen("tcp", ":8080") if err != nil { fmt.Println("connection error: " + err.Error()) } else { for { conn, err := ln.Accept() if err != nil { // server by mal prei !!!fmt.Println("error: " + err.Error()) continue } // obslenie konekcie spustme v nezvislejgo handleConnection(conn) // gorutine} } }net3/netserver.go

  • ChatClienttype ChatClient struct { clientID int // poradov slo klientareader *bufio.Reader // reader a writer z/do konekciewriter *bufio.Writer // klienta}

    func New_ChatClient(clientID int, conn net.Conn) *ChatClient { return &ChatClient{// kontruktor vytvor z ID a konekcieclientID: clientID, // ChatClientreader: bufio.NewReader(conn), writer: bufio.NewWriter(conn), } } Ke poznme zklady, sksime vytvori jednoduch chat-server umonujci: viacero pripojen, broadcastuje status vetkmnet4/chatroom.go

  • ChatRoomtype ChatRoom struct { // vetci ChatClienticlients []*ChatClient } func NewChatRoom() *ChatRoom {// przdny ChatRoomchatRoom := &ChatRoom{ clients: make([]*ChatClient, 0), } return chatRoom }func (chr *ChatRoom) NewChatClient(conn net.Conn) *ChatClient { chatclient := New_ChatClient(len(chr.clients)+1, conn) fmt.Printf("new client: %d\n", chatclient.clientID) chr.clients = append(chr.clients, chatclient) return chatclient } net4/chatroom.go

  • ChatRoomfunc (chr *ChatRoom) handleConnection(conn net.Conn) { chclient := chr.NewChatClient(conn) for { line, _, err := chclient.reader.ReadLine() if err == io.EOF { break } msg := fmt.Sprintf("%d>%s\r\n", chclient.clientID,line) fmt.Print(msg)// vpis na konzolu chatroomu for _, client := range chr.clients { if client.clientID != chclient.clientID { client.writer.WriteString(msg) client.writer.Flush() } } } } net4/chatroom.go

  • ChatRoom v akciinet4/chatroom.go

  • HTTP clientGET Request-URI CRLF[GET | HEAD | POST ] Request-URI HTTP-Version CRLFGET http://google:80 HTTP/1.0url := "http://google.com" response, err := http.Head(url) fmt.Println(response.Status) // 200 OKfor k, v := range response.Header { // Content-Type:fmt.Println(k+":", v) } // [text/html; charset=ISO-8859-2]response, err = http.Get(url) fmt.Println("\nbody:") reader := bufio.NewReader(response.Body) for { line, _, err := reader.ReadLine() if err == io.EOF { break httpclient.go

  • o s telom ?for { line, _, err := reader.ReadLine() if err == io.EOF { break } strline := string(line) var httpRef = regexp.MustCompile( `(?i)href\s*=\s*(\"([^"]*\")|'[^']*'|([^'">\s]+))`) matches := httpRef.FindAllString(strline, -1) for _, match := range matches { fmt.Println(match) } }

    body:href="/search?"href="http://www.google.sk/imghp?hl=sk&tab=wi"href="http://maps.google.sk/maps?hl=sk&tab=wl"href="http://www.youtube.com/?gl=SK&tab=w1"href="https://mail.google.com/mail/?tab=wm"href="https://drive.google.com/?tab=wo"href="https://www.google.com/calendar?tab=wc"...httpclient.go

  • WebCrawlerfunc Crawl71(url string, depth int, fetcher Fetcher) { if depth
  • WebCrawlingvar fetcher = &fakeFetcher{"http://gol