代码改变世界

golang net包 tcp

2022-03-12 20:41  youxin  阅读(387)  评论(0编辑  收藏  举报

https://golang.google.cn/pkg/net/

 

Package net provides a portable interface for network I/O, including TCP/IP, UDP, domain name resolution, and Unix domain sockets.

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.

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')
// ...

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)
}

 

import "net"

net包提供了可移植的网络I/O接口,包括TCP/IP、UDP、域名解析和Unix域socket。

虽然本包提供了对网络原语的访问,大部分使用者只需要Dial、Listen和Accept函数提供的基本接口;以及相关的Conn和Listener接口。crypto/tls包提供了相同的接口和类似的Dial和Listen函数。

package main

import (
        "fmt"
        "io"
        "log"
        "net"
)

func worker(conn net.Conn) {
        defer conn.Close()
        b := make([]byte, 512)
        for {
                size, err := conn.Read(b)
                if err == io.EOF {
                        break
                }
                if err != nil {
                        log.Fatal(err)
                }

                fmt.Printf("Received %v bytes from %v\n", size, conn.RemoteAddr())
                size, err = conn.Write(b[0:size])
                if err != nil {
                        log.Fatal(err)
                }
                fmt.Printf("Written %v bytes to %v\n", size, conn.RemoteAddr())
        }
}

func main() {
        listner, err := net.Listen("tcp", "127.0.0.1:8085")
        if err != nil {
                log.Fatal(err)
        }
        fmt.Printf("Listering on %v\n", listner.Addr())
        for {
                conn, err := listner.Accept()
                if err != nil {
                        log.Fatal(err)
                }
                fmt.Printf("Accepted connection to %v from %v\n", conn.LocalAddr(), conn.RemoteAddr())
                go worker(conn)
        }
}
                       

 

client

package main

import (
    "fmt"
    "log"
    "net"
)

func main() {

    conn, err := net.Dial("tcp", "127.0.0.1:8888")
    if err != nil {
        log.Printf("conn err!!")
        log.Fatal(err)
    }
    defer conn.Close()

    fmt.Println("connect server successed \n")

    go handle(conn)

    var msg string
    for {
        msg = ""
        fmt.Scan(&msg)
        conn.Write([]byte("say|" + msg))

        if msg == "quit" {
            conn.Write([]byte("quit"))
            break
        }
    }
}
func handle(conn net.Conn) {

    for {

        data := make([]byte, 255)
        msg_read, err := conn.Read(data)

        if msg_read == 0 || err != nil {
            log.Printf("msg_read:%v,err=%v\n", msg_read, err)
            break
        }
        fmt.Println(string(data[0:msg_read]))
    }
}

 

参考:

https://blog.csdn.net/dyd961121/article/details/81252920

 

 

conn, err := net.Dial("tcp", "127.0.0.1:9999")
    if err != nil {
        // handle error
    }
    fmt.Fprintf(conn, "hello world")
    status, err := bufio.NewReader(conn).ReadString('\n')
    fmt.Println(status)

在Go语言的net包中有一个类型TCPConn,这个类型可以用来作为客户端和服务器端交互的通道,他有两个主要的函数:

func (c *TCPConn) Write(b []byte) (n int, err os.Error)
func (c *TCPConn) Read(b []byte) (n int, err os.Error)

TCPConn可以用在客户端和服务器端来读写数据。

在Go语言中通过ResolveTCPAddr获取一个TCPAddr:

func ResolveTCPAddr(net, addr string) (*TCPAddr, os.Error)

net参数是"tcp4"、"tcp6"、"tcp"中的任意一个,分别表示TCP(IPv4-only), TCP(IPv6-only)或者TCP(IPv4, IPv6的任意一个)。

addr表示域名或者IP地址,例如"www.google.com:80" 或者"127.0.0.1:22"。



net.ListenTCPnet.Listen 区别:

func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) 

VS

func Listen(net, laddr string) (Listener, error) 
 
func main() {

    var tcpAddr *net.TCPAddr

    tcpAddr, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:999")

    tcpListener, _ := net.ListenTCP("tcp", tcpAddr)

    defer tcpListener.Close()

    fmt.Println("Server ready to read ...")
    for {
        tcpConn, err := tcpListener.AcceptTCP()
        if err != nil {
            fmt.Println("accept error:", err)
            continue
        }
        fmt.Println("A client connected : " + tcpConn.RemoteAddr().String())
        go tcpPipe(tcpConn)
    }

}