加 Golang 学习 QQ 群共同学习进步成家立业工作 ^-^ 群号:96933959
import "net"
net 包提供了可移植的网络 I/O 接口,包括 TCP/IP、UDP、域名解析和 Unix 域 socket。
虽然本包提供了对网络原语的访问,大部分使用者只需要 Dial、Listen 和 Accept 函数提供的基本接口;以及相关的 Conn 和 Listener 接口。crypto/tls 包提供了相同的接口和类似的 Dial 和 Listen 函数。
Listen 函数创建的服务端:
- ln, err := net.Listen("tcp", ":8080")
- if err != nil {
- // handle error
- }
- for {
- conn, err := ln.Accept()
- if err != nil {
- // handle error
- continue
- }
- go handleConnection(conn)
- }
Dial 函数和服务端建立连接:
- conn, err := net.Dial("tcp", "google.com:80")
- if err != nil {
- // handle error
- }
- fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
- status, err := bufio.NewReader(conn).ReadString('\n')
- // ...
TCPConn 代表一个 TCP 网络连接,实现了 Conn 接口。
Conn 接口代表通用的面向流的网络连接。多个线程可能会同时调用同一个 Conn 的方法。
- type Conn interface {
- // Read从连接中读取数据
- // Read方法可能会在超过某个固定时间限制后超时返回错误,该错误的Timeout()方法返回真
- Read(b []byte) (n int, err error)
- // Write从连接中写入数据
- // Write方法可能会在超过某个固定时间限制后超时返回错误,该错误的Timeout()方法返回真
- Write(b []byte) (n int, err error)
- // Close方法关闭该连接
- // 并会导致任何阻塞中的Read或Write方法不再阻塞并返回错误
- Close() error
- // 返回本地网络地址
- LocalAddr() Addr
- // 返回远端网络地址
- RemoteAddr() Addr
- // 设定该连接的读写deadline,等价于同时调用SetReadDeadline和SetWriteDeadline
- // deadline是一个绝对时间,超过该时间后I/O操作就会直接因超时失败返回而不会阻塞
- // deadline对之后的所有I/O操作都起效,而不仅仅是下一次的读或写操作
- // 参数t为零值表示不设置期限
- SetDeadline(t time.Time) error
- // 设定该连接的读操作deadline,参数t为零值表示不设置期限
- SetReadDeadline(t time.Time) error
- // 设定该连接的写操作deadline,参数t为零值表示不设置期限
- // 即使写入超时,返回值n也可能>0,说明成功写入了部分数据
- SetWriteDeadline(t time.Time) error
- }
- package main
- import (
- "fmt"
- "net"
- )
- func process(conn net.Conn) {
- defer conn.Close()
- for {
- buf := make([]byte, 512)
- n, err := conn.Read(buf)
- if err != nil {
- fmt.Println("read err:", err)
- return
- }
- fmt.Println("read:", string(buf[:n]))
- }
- }
- func main() {
- fmt.Println("server start...")
- listen, err := net.Listen("tcp", "0.0.0.0:8000")
- if err != nil {
- fmt.Println("listen failed, err:", err)
- return
- }
- for {
- conn, err := listen.Accept()
- if err != nil {
- fmt.Println("accept failed, err:", err)
- continue
- }
- go process(conn)
- }
- }
- package main
- import (
- "bufio"
- "fmt"
- "net"
- "os"
- "strings"
- )
- func main() {
- conn, err := net.Dial("tcp", "localhost:8000")
- if err != nil {
- fmt.Println("err dialing:", err.Error())
- return
- }
- defer conn.Close()
- inputReader := bufio.NewReader(os.Stdin)
- for {
- input, _ := inputReader.ReadString('\n')
- trimedInput := strings.Trim(input, "\r\n")
- if trimedInput == "Q" {
- return
- }
- _, err := conn.Write([]byte(trimedInput))
- if err != nil {
- fmt.Println("err conn.write:", err)
- return
- }
- }
- }
封装一个 http 连接,请求百度
- package main
- import (
- "fmt"
- "io"
- "net"
- )
- func main() {
- conn, err := net.Dial("tcp", "www.baidu.com:80")
- if err != nil {
- fmt.Println("err dialing:", err.Error())
- return
- }
- defer conn.Close()
- msg := "GET / HTTP/1.1\r\n"
- msg += "Host: www.baidu.com\r\n"
- msg += "Connection: close\r\n"
- // msg += "Connection: keep-alive\r\n"
- msg += "\r\n\r\n"
- _, err = io.WriteString(conn, msg)
- if err != nil {
- fmt.Println("io write string failed, err:", err)
- return
- }
- buf := make([]byte, 4096)
- for {
- count, err := conn.Read(buf)
- if err != nil {
- break
- }
- fmt.Println(string(buf[:count]))
- }
- }
- data, err := json.Marshal("hello world")
- if err != nil {
- return
- }
- var buf [4]byte
- packLen := uint32(len(data))
- fmt.Println("packlen:", packLen)
- // 前4个字节表示data大小
- binary.BigEndian.PutUint32(buf[0:4], packLen)
- n, err := conn.Write(buf[:])
- if err != nil || n != 4 {
- fmt.Println("write data failed")
- return
- }
- _, err = conn.Write([]byte(data))
- if err != nil {
- return
- }
来源: http://www.cnblogs.com/suoning/p/7259210.html