Go Socketプログラミング(1):ダイヤル機能とその使用

従来のソケットプログラミング

Go言語でネットワークプログラミングを行う場合、従来のネットワークプログラミングよりも簡潔です。

TCPプロトコルに基づくネットワークサービスを例にとると、C言語でネットワークプログラムを作成する場合、クライアントとサーバーの実装プロセスは通常次のようになります。

ソケットプログラミングアイコン

サーバーの観点から、コードの記述は次のステップに分けられます。

  1. ソケットの確立とバインド:最初に、サーバーはsocket() 関数を使用 してネットワークソケットを確立し、次にそのbind() 関数を使用 してソケットに指定されたIPとポートをバインドします。
  2. 要求の監視:次に、サーバーはlisten() 関数を使用して 、IPとポートをバインドするクライアントの要求を監視します。
  3. 接続の受信:要求があり、3ウェイハンドシェイクによって接続が正常に確立された場合は、このaccept() 機能を使用し て接続を受信および処理します。
  4. リクエストの処理とレスポンスの送信:サーバー read() は、write() 関数を介して上記の確立された接続からクライアントから送信されたリクエストデータを読み取り、処理後に関数を介して クライアントにレスポンスデータを送信します。

クライアントの観点から、コードの記述は次のステップに分けられます。

  1. ソケットの確立:クライアントは、socket()関数を使用 してネットワークソケットを確立します。
  2. 接続を確立します。次に、connect() 関数を呼び出して IPとポート番号を渡し、指定されたサーバーネットワークプログラムとの接続を確立します。
  3. 要求の送信と応答の受信:接続が正常に確立された後、クライアントはwrite() 関数を介してサーバーにデータを送信し、 関数を使用 read() してサーバーから応答を受信できます。

UDPプロトコルに基づくネットワークサービスの一般的なプロセスも同じですが、サーバーとクライアントの間に接続を確立する必要はありません。

Go言語の標準ライブラリは、このプロセスを抽象化してカプセル化します。使用するプロトコルや接続の形式に関係なく、net.Dial() 関数を呼び出すだけで、コードの記述量が大幅に簡素化されます。以下の関数を見てみましょう。使用法。

Dial()関数

Dial() 関数のプロトタイプは次のとおりです。

func Dial(network, address string) (Conn, error) {
    var d Dialer
    return d.Dial(network, address)
}

network パラメータは、(のような着信ネットワークプロトコルを示す tcpudp など)を、address パラメータが入ってくるIPアドレスまたはドメイン名を示し、ポート番号はオプションです。あなたはそれを指定する必要がある場合は、の形でアドレスまたはドメイン名に従ってください":"十分です。接続が成功した場合、関数は接続オブジェクトを返しますerrorそれ以外の場合、関数はを返します 

いくつかの一般的なプロトコルの呼び出しメソッドを見てみましょう。

1. TCP接続:

conn, err := net.Dial("tcp", "192.168.10.10:80")

2. UDP接続:

conn, err := net.Dial("udp", "192.168.10.10:8888")

3. ICMP接続(プロトコル名を使用):

conn, err := net.Dial("ip4:icmp", "www.xueyuanjun.com")

注:これip4 はIPv4を意味し、対応するもの ip6 はIPv6を意味します。

4. ICMP接続(プロトコル番号を使用):

conn, err := net.Dial("ip4:1", "10.0.0.3")

注:プロトコル番号の意味は、次のリンクから確認できます:http//www.iana.org/assignments/protocol-numbers/protocol-numbers.xml

現時点では、Dial() この関数は以下のネットワークサポートtcpプロトコル:tcp4tcp6udpudp4udp6ipip4ip6unix、、unixgram と unixpacket次のようにこれらの契約が説明されます:

  • tcp:TCPプロトコルを表し、それが基づいているIPプロトコルのバージョンはパラメータのaddress 値適応します 
  • tcp4:IPプロトコルの4番目のバージョンに基づくTCPプロトコルを表します。
  • tcp6:IPプロトコルの第6版に基づくTCPプロトコルを表します。
  • udp:UDPプロトコルを表し、それが基づいているIPプロトコルのバージョンはパラメーターのaddress 値適応します 
  • udp4:IPプロトコルの4番目のバージョンに基づくUDPプロトコルを表します。
  • udp6:IPプロトコルの第6版に基づくUDPプロトコルを表します。
  • unix:UnixドメインをSOCK_STREAM ソケットタイプとして表すための内部ソケット通信プロトコル 
  • unixgram:UnixドメインをSOCK_DGRAM ソケットタイプとして表すための内部ソケット通信プロトコル 
  • unixpacket:UnixドメインをSOCK_SEQPACKET ソケットタイプとして表すための内部ソケット通信プロトコル 

接続が正常に確立されると、データを送受信できます。データを送信するとき は、接続オブジェクトconn のWrite()メソッドを使用しデータを受信するときそのメソッドを使用 し ます Read() 。次に、簡単なサンプルプログラムを通じて、Go言語でのネットワークプログラミングの実現について説明します。

TCPサンプルプログラム 

TCP接続を確立することで単純なHTTPプロトコルを実装します。HTTPヘッドリクエストをネットワークホストに送信し、ネットワークホストから返された情報を読み取ることで、具体的なコードの実装は次のようになります。 

package main

import (
    "bytes"
    "fmt"
    "io"
    "net"
    "os"
)

func main() {
    if len(os.Args) != 2 {
        fmt.Fprintf(os.Stderr, "Usage: %s host:port", os.Args[0])
        os.Exit(1)
    }
    // 从参数中读取主机信息
    service := os.Args[1]

    // 建立网络连接
    conn, err := net.Dial("tcp", service)
    // 连接出错则打印错误消息并退出程序
    checkError(err)

    // 调用返回的连接对象提供的 Write 方法发送请求
    _, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n"))
    checkError(err)

    // 通过连接对象提供的 Read 方法读取所有响应数据
    result, err := readFully(conn)
    checkError(err)

    // 打印响应数据
    fmt.Println(string(result))

    os.Exit(0)
}

func checkError(err error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
        os.Exit(1)
    }
}

func readFully(conn net.Conn) ([]byte, error) {
    // 读取所有响应数据后主动关闭连接
    defer conn.Close()

    result := bytes.NewBuffer(nil)
    var buf [512]byte
    for {
        n, err := conn.Read(buf[0:])
        result.Write(buf[0:n])
        if err != nil {
            if err == io.EOF {
                break
            }
            return nil, err
        }
    }
    return result.Bytes(), nil
}

上記のコードをテストすると、出力は次のようになります。

Go言語のTCPプログラミングコード例

以下のため 80 のポート、あなたもすることができます http 置き換えます:

Go言語のTCPプログラミングコード例

Go言語で記述されたネットワークプログラムの全体的な実装コードは、通信の詳細に注意を払う必要なしに、接続の確立、データの送信、およびデータの受信という非常に単純で明確であることがわかります。さまざまな基礎となるプロトコルの。

おすすめ

転載: blog.csdn.net/wxy_csdn_world/article/details/107445135