二、netパッケージの使用

6468 ワード

Netパッケージ使用
Netパッケージは主に3つのデータ型をめぐって派生しており、type Addr type Listener type Conn
1、Listen関数
ローカルネットワークアドレスladdrで傍受されたListenerを返します.ネットワークタイプパラメータnetは、「tcp」、「tcp 4」、「tcp 6」、「unix」または「unixpacket」である必要があります.サーバ側で使用されるため、接続を確立する必要があり、パッケージ向けudpは接続されていないため、listen関数netパラメータはudpをサポートしません.Dial関数を参照してladdrの構文を取得する
func Listen(network, address string) (Listener, error) {
    addrs, err := DefaultResolver.resolveAddrList(context.Background(), "listen", network, address, nil)
    if err != nil {
        return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err}
    }
    var l Listener
    switch la := addrs.first(isIPv4).(type) {
    case *TCPAddr:
        l, err = ListenTCP(network, la)
    case *UnixAddr:
        l, err = ListenUnix(network, la)
    default:
        return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}}
    }
    if err != nil {
        return nil, err // l is non-nil interface containing nil pointer
    }
    return l, nil
}

Listen関数は、次の3つの関数をパッケージする関数に相当するリスナーを取得するために使用されます.
socket()
bind()
listen()

2、Accept方法
Acceptメソッドはnet.に属する.Listenerタイプのメソッドでは、コンピュータ上のアプリケーションが現在のプログラムとtcp接続を確立するまで、呼び出し時にプロセスがブロックされます.acceptメソッドは、net.の連続値を返します.Connタイプ値、errorタイプ値
Accept() (Conn, error)

3、clientエンド関数Dial関数とDialTimeout関数
ネットワークnetworkにアドレスaddressを接続し、Connインタフェースを返します.利用可能なネットワークタイプは、「tcp」、「tcp 4」、「tcp 6」、「udp」、「udp 4」、「udp 6」、「ip」、「ip 4」、「ip 6」、「unix」、「unixgram」、「unixpacket」のTCPおよびUDPネットワークであり、アドレスフォーマットはhost:portまたは[host]:portであり、関数JoinHostPortおよびSplitHostPortを参照すると、以下の3つの関数をパッケージする関数に等価である.
socket()
bind()
connect

関数のプロトタイプ:
func Dial(network, address string) (Conn, error)
func DialTimeout(network, address string, timeout time.Duration) (Conn, error)

4、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
}

4、Read方法
func (c *TCPConn) Write(b []byte) (int, error)

5、Write方法
func (c *TCPConn) Write(b []byte) (int, error)

6、Close方法
func (c *TCPConn) Close() error

7、LocalAddrとRemoteAddrの方法
func (c *TCPConn) LocalAddr() Addr //LocalAddr        
func (c *TCPConn) RemoteAddr() Addr //RemoteAddr        

8、SetDeadline、SetReadDeadline、SetWriteDeadline
func (c *TCPConn) SetDeadline(t time.Time) error //SetDeadline        ,   Conn   SetDeadline  
func (c *TCPConn) SetReadDeadline(t time.Time) error //SetReadDeadline       ,   Conn   SetReadDeadline  
unc (c *TCPConn) SetWriteDeadline(t time.Time) error //SetWriteDeadline       ,   Conn   SetWriteDeadline  

9、ParseIP関数stringタイプのipアドレスをIPオブジェクトに変換する
type IP []byte //IP       IP   []byte  。          4  (IPv4) 16  (IPv6)       
func ParseIP(s string) IP

type IPMask []byte //IPMask    IP     

コード事例:
package main

import (
    "net"
    "fmt"
    "os"
)

func main(){
    ipS := "192.168.1.97"
    //       ip  ,         ,  s     IP      ,ParseIP   nil
    ip := net.ParseIP(ipS)
    if ip == nil {
        fmt.Fprintf(os.Stderr, "ipS err:        
") } fmt.Print(ip , "
") // IP mask := ip.DefaultMask() network := ip.Mask(mask) fmt.Printf("ip: %s, mask: %s, network: %s
", ip, mask.String(), network.String()) }

10、ドメイン名をipアドレスに解析する
ResolveTCPAddrはaddrをTCPアドレスとして解析して返す.パラメータaddrフォーマットは「host:port」または「[ipv 6-host%zone]:port」であり、解析によりネットワーク名とポート名が得られる.Netは「tcp」、「tcp 4」または「tcp 6」でなければなりません.
IPv 6アドレスのフォント値/名前は、「[::1]:80」、「[ipv 6-host]:http」、または「[ipv 6-host%zone]:80」などの四角カッコで囲まなければなりません.
func ResolveTCPAddr(net, addr string) (*TCPAddr, error)

コード事例:
domain := "www.baidu.com:8080"
addr, err := net.ResolveTCPAddr("tcp", domain)
if err != nil {
    fmt.Printf("err: %s", err)
    return
}
fmt.Print(addr)

11、使用例
サービス側サービス:
package main

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

func clientHandler(conn net.Conn) {
    defer conn.Close()

    //        
    params, err := ioutil.ReadAll(conn)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Print(string(params))

    //        
    n, err := conn.Write([]byte("hello,client \r
")) if err != nil { log.Fatal(err) } fmt.Print(n) } func main() { listen, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } for { conn, err := listen.Accept() if err != nil { fmt.Print(err) continue } go clientHandler(conn) } }

クライアントクライアント:
package main

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

func main() {
    conn, err := net.Dial("tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }

    //        
    n, err := conn.Write([]byte("GET / HTTP/1.1 \r
\r
")) if err != nil { log.Fatal(err) } // res, err := ioutil.ReadAll(conn) if err != nil { log.Fatal(err) } fmt.Printf("response: %s, write byte num: %d", string(res), n) conn.Close() }