Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Gunosy.go #6 net, net/mail, net/smtp, net/textp...

Gunosy.go #6 net, net/mail, net/smtp, net/textproto, net/rpc

Hiroshi Kurokawa

July 17, 2014
Tweet

More Decks by Hiroshi Kurokawa

Other Decks in Programming

Transcript

  1. લޱ্ w ࠓ೔঺հ͢Δύοέʔδ w OFU w OFUNBJM w OFUTNUQ w

    OFUUFYUQSPUP w OFUSQD w OFUSQDKTPOSQD w ஫ҙ఺ w ࡌ͍ͤͯΔίʔυྫͰ͸ΤϥʔॲཧͳͲΛলུ͍ͯ͠·͢ w ίϐϖʹ͸஫ҙ
  2. OFUύοέʔδ w IUUQHPMBOHKQQLHOFU w ωοτϫʔΫ*0Λߦ͏جຊతͳϝιου΍ܕ͕ἧ͍ͬͯΔ w 5$1*1 6%1 %/4 6OJYEPNBJOTPDLFUT

    w جຊతͳΠϯλʔϑΣʔε͚ͩͰྑ͚Ε͹ɺ%JBM -JTUFO "DDFQUΛ࢖͓͚ͬͯ͹ɺ0, conn,  err  :=  net.Dial("tcp",  "google.com:80")   fmt.Fprintf(conn,  "GET  /  HTTP/1.0\r\n\r\n")   status,  err  :=  bufio.NewReader(conn).ReadString('\n')   //  ... ΫϥΠΞϯτଆɿ αʔόʔଆɿ ln,  err  :=  net.Listen("tcp",  ":8080")   for  {     conn,  err  :=  ln.Accept()     go  handleConnection(conn)   }
  3. OFUύοέʔδ  w جຊ w UZQF$POO w GVOD%JBM OFUXPSL BEESFTTTUSJOH

     $POO FSSPS  w GVOD%JBM5JNFPVU OFUXPSL BEESFTTTUSJOH UJNFPVUUJNF%VSBUJPO  $POO FSSPS  w GVOD'JMF$POO G PT'JMF  D$POO FSSFSSPS  w GVOD1JQF  $POO $POO  w UZQF%JBMFS w GVOD E %JBMFS %JBM OFUXPSL BEESFTTTUSJOH  $POO FSSPS  w UZQF-JTUFOFS w GVOD'JMF-JTUFOFS G PT'JMF  M-JTUFOFS FSSFSSPS  w GVOD-JTUFO OFU MBEESTUSJOH  -JTUFOFS FSSPS
  4. OFUύοέʔδ  w γεςϜ৘ใ w GVOD*OUFSGBDF"EEST  <>"EES FSSPS 

    w GVOD*OUFSGBDFT  <>*OUFSGBDF FSSPS  w UZQF"EES w UZQF*OUFSGBDF w UZQF)BSEXBSF"EES
  5. OFUύοέʔδ  w ϗετɾϙʔτͱจࣈྻͷม׵ w GVOD+PJO)PTU1PSU IPTU QPSUTUSJOH TUSJOH w

    GVOD4QMJU)PTU1PSU IPTUQPSUTUSJOH  IPTU QPSUTUSJOH FSSFSSPS  w ໊લղܾ w GVOD-PPLVQ"EES BEESTUSJOH  OBNF<>TUSJOH FSSFSSPS  w GVOD-PPLVQ$/".& OBNFTUSJOH  DOBNFTUSJOH FSSFSSPS  w GVOD-PPLVQ)PTU IPTUTUSJOH  BEEST<>TUSJOH FSSFSSPS  w GVOD-PPLVQ*1 IPTUTUSJOH  BEEST<>*1 FSSFSSPS  w GVOD-PPLVQ.9 OBNFTUSJOH  NY<> .9 FSSFSSPS  w GVOD-PPLVQ/4 OBNFTUSJOH  OT<> /4 FSSFSSPS  w GVOD-PPLVQ1PSU OFUXPSL TFSWJDFTUSJOH  QPSUJOU FSSFSSPS  w GVOD-PPLVQ437 TFSWJDF QSPUP OBNFTUSJOH  DOBNFTUSJOH BEEST<> 437 FSSFSSPS  w GVOD-PPLVQ595 OBNFTUSJOH  UYU<>TUSJOH FSSFSSPS
  6. OFUNBJMύοέʔδ w ϝʔϧͷϝοηʔδΛಡΉͨΊͷύοέʔδɻ3'$ʹै͏ɻ w GVOE1BSTF"EESFTT-JTU MJTUTUSJOH  <> "EESFTT FSSPS

     w UZQF"EESFTT w GVOD1BSTF"EESFTT BEESFTTTUSJOH  "EESFTT FSSPS  w GVOD B "EESFTT 4USJOH TUSJOH w UZQF)FBEFS w GVOD I)FBEFS "EESFTT-JTU LFZTUSJOH  <> "EESFTT FSSPS  w GVOD I)FBEFS %BUF  UJNF5JNF FSSPS  w GVOD I)FBEFS (FU LFZTUSJOH TUSJOH w UZQF.FTTBHF w GVOD3FBE.FTTBHF SJP3FBEFS  NTH .FTTBHF FSSFSSPS  w جຊతͳྲྀΕ͸NBJM3FBE.FTTBHFͰϝοηʔδΛಡΈࠐΜͰɺ.FTTBHF#PEZͰຊจʹɺ.FTTBHF)FBEFSͰϔομ ʹΞΫηε͢Δɻ
  7. OFUTNUQύοέʔδ w 3'$Ͱఆٛ͞Ε͍ͯΔ4.51 4JNQMF.BJM 5SBOTGFS1SPUPDPM Λ࣮૷͍ͯ͠Δ w ࢖͍ํ Τϥʔॲཧ͸Ұ෦লུ͍ͯ͠·͢  

         //  Connect  to  the  remote  SMTP  server.          c,  err  :=  smtp.Dial("mail.example.com:25")   !        //  Set  the  sender  and  recipient  first          if  err  :=  c.Mail("[email protected]");  err  !=  nil  {                          log.Fatal(err)          }          if  err  :=  c.Rcpt("[email protected]");  err  !=  nil  {                          log.Fatal(err)          }   !        //  Send  the  email  body.          wc,  err  :=  c.Data()          _,  err  =  fmt.Fprintf(wc,  "This  is  the  email  body")          err  =  wc.Close()   !        //  Send  the  QUIT  command  and  close  the  connection.          err  =  c.Quit()
  8. OFUUFYUQSPUPύοέʔδ w )551 //51 4.51ͱ͍ͬͨςΩετϕʔεͷϓϩτίϧʹศརͳϢʔςΟϦςΟΛूΊͨύοέʔδ w &SSPS
 ͷΑ͏ͳ਺ࣈͰද͞ΕΔΤϥʔ w 1JQFMJOF


    ෳ਺ͷΫϥΠΞϯτ͕ίωΫγϣϯΛڞ༗͢ΔͨΊͷ࢓૊Έ w 3FBEFS
 ελʔλείʔυɺϔομɺޙଓߦ͕ۭനͰΠϯσϯτ͞ΕͯυοτͰऴΘΔຊจΛѻ͑Δ w 8SJUFS
 ্هͷϑΥʔϚοτʹैͬͯϝοηʔδΛॻ͚Δ 1JQFMJOFͷ࢖͍ํɿ 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
  9. OFUXPSLSQDύοέʔδ w 31$ 3FNPUF1SPDFEVSF$BMM Λߦ͏ͨΊͷύοέʔδ w αʔόʔଆͰొ࿥ͨ͠ΦϒδΣΫτͷϝιουΛωοτϫʔΫӽ͠ʹݺ΂ΔΑ͏ʹͳΔ w ొ࿥ͨ͠ΦϒδΣΫτͷܕ໊͕αʔϏε໊ʹͳΔ w

    ෳ਺ͷಉҰܕͷΦϒδΣΫτΛొ࿥͢Δ͜ͱ͸Ͱ͖ͳ͍ w ొ࿥ͨ͠ΦϒδΣΫτͷϝιουͷ͏ͪɺҎԼͷ৚݅Λຬͨͨ͠ϝιου͕ެ։͞ΕΔ w ϝιου͕ެ։͞Ε͍ͯΔ େจࣈͰ࢝·͍ͬͯΔ  w ͭͷҾ਺Λ࣋ͪɺͲͪΒͷܕ΋ެ։͞Ε͍ͯΔ͔ϏϧτΠϯܕͰ͋Δ w ൪໨ͷҾ਺͸ϙΠϯλܕͰ͋Δ w ໭Γ஋͕FSSPSܕͰ͋Δ w ཁ͢ΔʹɺҎԼͷܗࣜͰ͋Ε͹ྑ͍ɻ ! w ஫ҙɿ5 5 5͸FODPEJOHHPCͰγϦΞϥΠζσγϦΞϥΠζͰ͖ͳ͚Ε͹ͳΒͳ͍ কདྷ͸؇࿨͞ΕΔ͔΋  w +40/ͳΒOFUXPSLSQDKTPOSQDύοέʔδ͕͋Δ w ࠷ॳͷҾ਺͕ϦΫΤετͷύϥϝʔλͰɺ൪໨ͷҾ਺͕Ϩεϙϯεʹ૬౰͢Δ func  (t  *T)  MethodName(argType  T1,  replyType  *T2)  error
  10. ࢖͍ํ w αʔόʔଆ w ΦϒδΣΫτΛొ࿥ͨ͠ޙʹ4FSWF$POOΛݺͿɻίʔσοΫ͸HPC͕࢖ΘΕΔ w HPCҎ֎Λ࢖͏ͳΒɺ4FSWF$PEFDΛ࢖͏ɻ w )551Λ࢖͏ͳΒɺ)BOEMF)551ΛݺΜͰϋϯυϥΛొ࿥ͨ͠ޙʹɺIUUQ4FSWFΛݺ Ϳ

    w ΫϥΠΞϯτଆ w ίωΫγϣϯΛཱ֬ͨ͋͠ͱʹ/FX$MJFOUΛݺͿɻ%JBMϝιουΛ࢖͏ͱ྆ํ͕ग़དྷ ͯศརɻ w $MJFOUΦϒδΣΫτͷ$BMMϝιουΛݺͿͱಉظతʹɺ(PϝιουΛݺͿͱඇಉظత ʹϨεϙϯεΛॲཧ͢Δ w ໌ࣔతʹίʔσοΫ͕ࢦఆ͞Ε͍ͯͳ͍ͳΒɺFODPEJOHHPC͕࢖ΘΕΔ
  11. αϯϓϧ  αʔόʔଆɿ type  Args  struct  {     A,

     B  int   }   type  Quotient  struct  {     Quo,  Rem  int   }   type  Arith  int   func  (t  *Arith)  Multiply(args  *Args,  reply  *int)  error  {     *reply  =  args.A  *  args.B     return  nil   }   func  (t  *Arith)  Divide(args  *Args,  quo  *Quotient)  error  {     if  args.B  ==  0  {       return  errors.New("divide  by  zero")     }     quo.Quo  =  args.A  /  args.B     quo.Rem  =  args.A  %  args.B     return  nil   } arith  :=  new(Arith)   rpc.Register(arith)   rpc.HandleHTTP()   l,  e  :=  net.Listen("tcp",  ":1234")   if  e  !=  nil  {     log.Fatal("listen  error:",  e)   }   go  http.Serve(l,  nil)
  12. αϯϓϧ  ΫϥΠΞϯτଆɿ client,  err  :=  rpc.DialHTTP("tcp",  serverAddress  +  ":1234")

      if  err  !=  nil  {     log.Fatal("dialing:",  err)   } args  :=  &server.Args{7,8}   var  reply  int   err  =  client.Call("Arith.Multiply",  args,  &reply)   if  err  !=  nil  {     log.Fatal("arith  error:",  err)   }   fmt.Printf("Arith:  %d*%d=%d",  args.A,  args.B,  reply) //  Asynchronous  call   quotient  :=  new(Quotient)   divCall  :=  client.Go("Arith.Divide",  args,  quotient,  nil)   replyCall  :=  <-­‐divCall.Done  //  will  be  equal  to  divCall   //  check  errors,  print,  etc.   ಉظॲཧɿ ඇಉظॲཧɿ
  13. OFUSQDKTPOSQDύοέʔδ w ίʔσοΫʹHPCͰ͸ͳ͘ɺKTPOΛ࢖͏ͨΊͷύοέʔδ w +40/31$ͷ࢓༷ͱ͸ؔ܎ͳ͍ɻͨ·ͨ·໊લ͕KTPOSQDͳ͚ͩɻ
 “jsonrpc was designed to work

    with net/rpc not the other way around.”
 “the only thing they did wrong was call it "jsonrpc". :-)”
 - Andre Moraes (https://groups.google.com/forum/#!topic/golang-nuts/SGXmAvzD7DM) w (PSJMMB͸+40/31$ʹ४ڌ͍ͯ͠ΔΒ͍͠
 IUUQXXXHPSJMMBUPPMLJUPSHQLHSQDKTPO arith  :=  new(data.Arith)   ! rpc.Register(arith)   rpc.HandleHTTP()   ! l,  err  :=  net.Listen("tcp",  ":1234")   for  {     conn,  err  :=  l.Accept()     if  err  !=  nil  {       log.Fatal(err)     }     go  jsonrpc.ServeConn(conn)   } αʔόʔଆɿ ΫϥΠΞϯτଆɿ conn,  err  :=  net.Dial("tcp",  ":1234")   defer  conn.Close()   client  :=  jsonrpc.NewClient(conn)   ! //  Synchronous  call   args  :=  &data.Args{7,  8}   var  reply  int   err  =  client.Call("Arith.Multiply",  args,  &reply)   fmt.Printf("Arith:  %d*%d=%d",  args.A,  args.B,  reply)