go语言学习(八)

1.socket编程

2.并发爬虫

3.web服务器编程

一、socket编程

服务端代码:

package main

import "net"
import "fmt"

func main() {
    //1.设置监听
    listener, _ := net.Listen("tcp", "127.0.0.1:8888")
    //2.建立连接
    conn, _ := listener.Accept()
    //3.接受数据
    buf := make([]byte, 1024)
    n, _ := conn.Read(buf)

    fmt.Println(string(buf[:n]))

}

客户端代码:

package main

import "net"
import "fmt"

func main() {
    //1.建立连接
    conn, _ := net.Dial("tcp", "127.0.0.1:8888")
    //2.发送数据
    var str string
    fmt.Scan(&str)
    conn.Write([]byte(str))
}

多客户端与服务器交互版本

服务器端:

package main

import "net"
import "fmt"

func main() {
    //1.设置监听
    listener, _ := net.Listen("tcp", "127.0.0.1:8888")

    for {
        //2.建立连接
        conn, _ := listener.Accept()
        //3.接受数据
        go func() {
            buf := make([]byte, 1024)

            for {
                n, _ := conn.Read(buf)
                fmt.Println(conn.RemoteAddr(), ":", string(buf[:n]))
            }
        }()

    }

}

客户端:

package main

import "net"
import "fmt"

func main() {
    //1.建立连接
    conn, _ := net.Dial("tcp", "127.0.0.1:8888")
    //2.发送数据
    var str string
    for {
        fmt.Scan(&str)
        conn.Write([]byte(str))
    }

}

udp版服务器:

package main

import "fmt"
import "net"

func main() {
    udp_addr, _ := net.ResolveUDPAddr("udp", ":8000")
    c, _ := net.ListenUDP("udp", udp_addr)
    buf := make([]byte, 1024)
    for {
        n, _ := c.Read(buf)
        fmt.Println("====>", string(buf[:n]))
    }
}

udp版客户端:

package main

import "fmt"
import "net"

func main() {
    c, _ := net.Dial("udp", "127.0.0.1:8000")

    var str string

    for {
        fmt.Scan(&str)
        c.Write([]byte(str))
    }
}

二、爬虫

使用net/http包爬去百度贴吧,go语言吧内容

package main

import (
    "fmt"
    "net/http"
)

func getHtml(path string) {
    res, err := http.Get(path)
    if err != nil {
        fmt.Println(err)
        return
    }

    var html string
    buf := make([]byte, 1024*4)

    for {
        n, _ := res.Body.Read(buf)
        if n == 0 {
            break
        }
        html += string(buf[:n])
    }

    fmt.Println(html)
}

func main() {
    getHtml("http://tieba.baidu.com/f?kw=go%E8%AF%AD%E8%A8%80&ie=utf-8&pn=50")
}

使用goroutine并发爬取,将爬到的内容写入文件

package main

import (
    "fmt"
    "net/http"
    "os"
    "strconv"
)

func getHtml(pageNum int, ch chan<- int) {

    path := "http://tieba.baidu.com/f?kw=go%E8%AF%AD%E8%A8%80&ie=utf-8&pn=50" + strconv.Itoa(pageNum*50)

    res, err := http.Get(path)
    if err != nil {
        fmt.Println(err)
        return
    }
    var html string
    buf := make([]byte, 1024*4)
    for {
        n, _ := res.Body.Read(buf)
        if n == 0 {
            break
        }
        html += string(buf[:n])
    }
    htmlWrite(strconv.Itoa(pageNum)+".html", html)

    ch <- pageNum
}

func htmlWrite(fileName, content string) {
    file, err := os.Create(fileName)
    defer file.Close()
    if err != nil {
        fmt.Println("Open file error :", err)
        return
    }
    n, err := file.WriteString(content)
    if n == 0 {
        fmt.Println("Write file error :", err)
        return
    }

}

func main() {

    ch := make(chan int)

    for i := 0; i < 5; i++ {
        go getHtml(i, ch)
    }
    for i := 0; i < 5; i++ {
        fmt.Printf("第%d个爬取成功\n", <-ch)
    }
}

(这里有个问题:在main()函数的最后使用死循环,程序无法执行。。。。。)

三、搭建简单web服务器

web版Hello go!!

package main

import "net/http"

func main() {

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello go!!!!"))
    })

    http.ListenAndServe(":8080", nil)
}

使用浏览器访问http://127.0.0.1:8080/

go语言学习(八)

使用http.handle

package main

import "net/http"

type indexHandler struct{}

func (i *indexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello go!!!!"))
}

func main() {

    http.Handle("/", &indexHandler{})

    http.ListenAndServe(":8080", nil)
}